MCPcopy Create free account
hub / github.com/Redot-Engine/redot-engine / tie_native_managed_to_unmanaged

Method tie_native_managed_to_unmanaged

modules/mono/csharp_script.cpp:1372–1415  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1370 return p_object->has_instance_binding(get_singleton());
1371}
1372void CSharpLanguage::tie_native_managed_to_unmanaged(GCHandleIntPtr p_gchandle_intptr, Object *p_unmanaged, const StringName *p_native_name, bool p_ref_counted) {
1373 // This method should not fail
1374
1375 CRASH_COND(!p_unmanaged);
1376
1377 // All mono objects created from the managed world (e.g.: 'new Player()')
1378 // need to have a CSharpScript in order for their methods to be callable from the unmanaged side
1379
1380 RefCounted *rc = Object::cast_to<RefCounted>(p_unmanaged);
1381
1382 CRASH_COND(p_ref_counted != (bool)rc);
1383
1384 MonoGCHandleData gchandle = MonoGCHandleData(p_gchandle_intptr,
1385 p_ref_counted ? gdmono::GCHandleType::WEAK_HANDLE : gdmono::GCHandleType::STRONG_HANDLE);
1386
1387 // If it's just a wrapper Godot class and not a custom inheriting class, then attach a
1388 // script binding instead. One of the advantages of this is that if a script is attached
1389 // later and it's not a C# script, then the managed object won't have to be disposed.
1390 // Another reason for doing this is that this instance could outlive CSharpLanguage, which would
1391 // be problematic when using a script. See: https://github.com/godotengine/godot/issues/25621
1392
1393 if (p_ref_counted) {
1394 // Unsafe refcount increment. The managed instance also counts as a reference.
1395 // This way if the unmanaged world has no references to our owner
1396 // but the managed instance is alive, the refcount will be 1 instead of 0.
1397 // See: godot_icall_RefCounted_Dtor(MonoObject *p_obj, Object *p_ptr)
1398
1399 // May not me referenced yet, so we must use init_ref() instead of reference()
1400 if (rc->init_ref()) {
1401 CSharpLanguage::get_singleton()->post_unsafe_reference(rc);
1402 }
1403 }
1404
1405 // The object was just created, no script instance binding should have been attached
1406 CRASH_COND(CSharpLanguage::has_instance_binding(p_unmanaged));
1407
1408 void *binding = CSharpLanguage::get_singleton()->get_instance_binding(p_unmanaged);
1409
1410 CSharpScriptBinding &script_binding = ((RBMap<Object *, CSharpScriptBinding>::Element *)binding)->value();
1411 script_binding.inited = true;
1412 script_binding.type_name = *p_native_name;
1413 script_binding.gchandle = gchandle;
1414 script_binding.owner = p_unmanaged;
1415}
1416
1417void CSharpLanguage::tie_user_managed_to_unmanaged(GCHandleIntPtr p_gchandle_intptr, Object *p_unmanaged, Ref<CSharpScript> *p_script, bool p_ref_counted) {
1418 // This method should not fail

Callers

nothing calls this directly

Calls 5

MonoGCHandleDataClass · 0.85
init_refMethod · 0.80
post_unsafe_referenceMethod · 0.80
valueMethod · 0.80
get_instance_bindingMethod · 0.45

Tested by

no test coverage detected