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

Method setup_csharp_script_binding

modules/mono/csharp_script.cpp:1147–1204  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1145}
1146
1147bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object) {
1148#ifdef DEBUG_ENABLED
1149 // I don't trust you
1150 if (p_object->get_script_instance()) {
1151 CSharpInstance *csharp_instance = CAST_CSHARP_INSTANCE(p_object->get_script_instance());
1152 CRASH_COND(csharp_instance != nullptr && !csharp_instance->is_destructing_script_instance());
1153 }
1154#endif // DEBUG_ENABLED
1155
1156 StringName type_name = p_object->get_class_name();
1157
1158 const ClassDB::ClassInfo *classinfo = ClassDB::classes.getptr(type_name);
1159
1160 // This skipping of GDExtension classes, as well as whatever classes are in this list of ignored types, is a
1161 // workaround to allow GDExtension classes to be used from C# so long as they're only used through base classes that
1162 // are registered from the engine. This will likely need to be removed whenever proper support for GDExtension
1163 // classes is added to C#. See #75955 for more details.
1164 while (classinfo && (!classinfo->exposed || classinfo->gdextension || ignored_types.has(classinfo->name))) {
1165 classinfo = classinfo->inherits_ptr;
1166 }
1167
1168 ERR_FAIL_NULL_V(classinfo, false);
1169 type_name = classinfo->name;
1170
1171 bool parent_is_object_class = ClassDB::is_parent_class(p_object->get_class_name(), type_name);
1172 ERR_FAIL_COND_V_MSG(!parent_is_object_class, false,
1173 "Type inherits from native type '" + type_name + "', so it can't be instantiated in object of type: '" + p_object->get_class() + "'.");
1174
1175#ifdef DEBUG_ENABLED
1176 CRASH_COND(!r_script_binding.gchandle.is_released());
1177#endif // DEBUG_ENABLED
1178
1179 GCHandleIntPtr strong_gchandle =
1180 GDMonoCache::managed_callbacks.ScriptManagerBridge_CreateManagedForGodotObjectBinding(
1181 &type_name, p_object);
1182
1183 ERR_FAIL_NULL_V(strong_gchandle.value, false);
1184
1185 r_script_binding.inited = true;
1186 r_script_binding.type_name = type_name;
1187 r_script_binding.gchandle = MonoGCHandleData(strong_gchandle, gdmono::GCHandleType::STRONG_HANDLE);
1188 r_script_binding.owner = p_object;
1189
1190 // Tie managed to unmanaged
1191 RefCounted *rc = Object::cast_to<RefCounted>(p_object);
1192
1193 if (rc) {
1194 // Unsafe refcount increment. The managed instance also counts as a reference.
1195 // This way if the unmanaged world has no references to our owner
1196 // but the managed instance is alive, the refcount will be 1 instead of 0.
1197 // See: godot_icall_RefCounted_Dtor(MonoObject *p_obj, Object *p_ptr)
1198
1199 rc->reference();
1200 CSharpLanguage::get_singleton()->post_unsafe_reference(rc);
1201 }
1202
1203 return true;
1204}

Callers 1

Calls 9

MonoGCHandleDataClass · 0.85
get_script_instanceMethod · 0.80
post_unsafe_referenceMethod · 0.80
getptrMethod · 0.45
hasMethod · 0.45
get_classMethod · 0.45
is_releasedMethod · 0.45
referenceMethod · 0.45

Tested by

no test coverage detected