| 1370 | return p_object->has_instance_binding(get_singleton()); |
| 1371 | } |
| 1372 | void 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 | |
| 1417 | void 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 |
nothing calls this directly
no test coverage detected