diff options
Diffstat (limited to 'modules/mono/csharp_script.cpp')
-rw-r--r-- | modules/mono/csharp_script.cpp | 143 |
1 files changed, 13 insertions, 130 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 858d1d3e4e..a3464ccfc2 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -410,115 +410,6 @@ ScriptLanguage::ScriptNameCasing CSharpLanguage::preferred_file_name_casing() co } #ifdef TOOLS_ENABLED -struct VariantCsName { - Variant::Type variant_type; - const String cs_type; -}; - -static String variant_type_to_managed_name(const String &p_var_type_name) { - if (p_var_type_name.is_empty()) { - return "Variant"; - } - - if (ClassDB::class_exists(p_var_type_name)) { - return pascal_to_pascal_case(p_var_type_name); - } - - if (p_var_type_name == Variant::get_type_name(Variant::OBJECT)) { - return "GodotObject"; - } - - if (p_var_type_name == Variant::get_type_name(Variant::INT)) { - return "long"; - } - - if (p_var_type_name == Variant::get_type_name(Variant::FLOAT)) { - return "double"; - } - - if (p_var_type_name == Variant::get_type_name(Variant::STRING)) { - return "string"; // I prefer this one >:[ - } - - if (p_var_type_name == Variant::get_type_name(Variant::DICTIONARY)) { - return "Collections.Dictionary"; - } - - if (p_var_type_name.begins_with(Variant::get_type_name(Variant::ARRAY) + "[")) { - String element_type = p_var_type_name.trim_prefix(Variant::get_type_name(Variant::ARRAY) + "[").trim_suffix("]"); - return "Collections.Array<" + variant_type_to_managed_name(element_type) + ">"; - } - - if (p_var_type_name == Variant::get_type_name(Variant::ARRAY)) { - return "Collections.Array"; - } - - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_BYTE_ARRAY)) { - return "byte[]"; - } - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT32_ARRAY)) { - return "int[]"; - } - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT64_ARRAY)) { - return "long[]"; - } - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT32_ARRAY)) { - return "float[]"; - } - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT64_ARRAY)) { - return "double[]"; - } - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_STRING_ARRAY)) { - return "string[]"; - } - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR2_ARRAY)) { - return "Vector2[]"; - } - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR3_ARRAY)) { - return "Vector3[]"; - } - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_COLOR_ARRAY)) { - return "Color[]"; - } - - if (p_var_type_name == Variant::get_type_name(Variant::SIGNAL)) { - return "Signal"; - } - - const VariantCsName var_types[] = { - { Variant::BOOL, "bool" }, - { Variant::INT, "long" }, - { Variant::VECTOR2, "Vector2" }, - { Variant::VECTOR2I, "Vector2I" }, - { Variant::RECT2, "Rect2" }, - { Variant::RECT2I, "Rect2I" }, - { Variant::VECTOR3, "Vector3" }, - { Variant::VECTOR3I, "Vector3I" }, - { Variant::TRANSFORM2D, "Transform2D" }, - { Variant::VECTOR4, "Vector4" }, - { Variant::VECTOR4I, "Vector4I" }, - { Variant::PLANE, "Plane" }, - { Variant::QUATERNION, "Quaternion" }, - { Variant::AABB, "Aabb" }, - { Variant::BASIS, "Basis" }, - { Variant::TRANSFORM3D, "Transform3D" }, - { Variant::PROJECTION, "Projection" }, - { Variant::COLOR, "Color" }, - { Variant::STRING_NAME, "StringName" }, - { Variant::NODE_PATH, "NodePath" }, - { Variant::RID, "Rid" }, - { Variant::CALLABLE, "Callable" }, - }; - - for (unsigned int i = 0; i < sizeof(var_types) / sizeof(VariantCsName); i++) { - if (p_var_type_name == Variant::get_type_name(var_types[i].variant_type)) { - return var_types[i].cs_type; - } - } - - return "Variant"; -} - String CSharpLanguage::make_function(const String &, const String &p_name, const PackedStringArray &p_args) const { // The make_function() API does not work for C# scripts. // It will always append the generated function at the very end of the script. In C#, it will break compilation by @@ -1408,7 +1299,11 @@ GDExtensionBool CSharpLanguage::_instance_binding_reference_callback(void *p_tok } void *CSharpLanguage::get_instance_binding(Object *p_object) { - void *binding = p_object->get_instance_binding(get_singleton(), &_instance_binding_callbacks); + return p_object->get_instance_binding(get_singleton(), &_instance_binding_callbacks); +} + +void *CSharpLanguage::get_instance_binding_with_setup(Object *p_object) { + void *binding = get_instance_binding(p_object); // Initially this was in `_instance_binding_create_callback`. However, after the new instance // binding re-write it was resulting in a deadlock in `_instance_binding_reference`, as @@ -1433,11 +1328,7 @@ void *CSharpLanguage::get_existing_instance_binding(Object *p_object) { #ifdef DEBUG_ENABLED CRASH_COND(p_object->has_instance_binding(p_object)); #endif - return p_object->get_instance_binding(get_singleton(), &_instance_binding_callbacks); -} - -void CSharpLanguage::set_instance_binding(Object *p_object, void *p_binding) { - p_object->set_instance_binding(get_singleton(), p_binding, &_instance_binding_callbacks); + return get_instance_binding(p_object); } bool CSharpLanguage::has_instance_binding(Object *p_object) { @@ -1464,13 +1355,6 @@ void CSharpLanguage::tie_native_managed_to_unmanaged(GCHandleIntPtr p_gchandle_i // Another reason for doing this is that this instance could outlive CSharpLanguage, which would // be problematic when using a script. See: https://github.com/godotengine/godot/issues/25621 - CSharpScriptBinding script_binding; - - script_binding.inited = true; - script_binding.type_name = *p_native_name; - script_binding.gchandle = gchandle; - script_binding.owner = p_unmanaged; - if (p_ref_counted) { // Unsafe refcount increment. The managed instance also counts as a reference. // This way if the unmanaged world has no references to our owner @@ -1486,14 +1370,13 @@ void CSharpLanguage::tie_native_managed_to_unmanaged(GCHandleIntPtr p_gchandle_i // The object was just created, no script instance binding should have been attached CRASH_COND(CSharpLanguage::has_instance_binding(p_unmanaged)); - void *data; - { - MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex()); - data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(p_unmanaged, script_binding); - } + void *binding = CSharpLanguage::get_singleton()->get_instance_binding(p_unmanaged); - // Should be thread safe because the object was just created and nothing else should be referencing it - CSharpLanguage::set_instance_binding(p_unmanaged, data); + CSharpScriptBinding &script_binding = ((RBMap<Object *, CSharpScriptBinding>::Element *)binding)->value(); + script_binding.inited = true; + script_binding.type_name = *p_native_name; + script_binding.gchandle = gchandle; + script_binding.owner = p_unmanaged; } void CSharpLanguage::tie_user_managed_to_unmanaged(GCHandleIntPtr p_gchandle_intptr, Object *p_unmanaged, Ref<CSharpScript> *p_script, bool p_ref_counted) { @@ -2092,7 +1975,7 @@ CSharpInstance::~CSharpInstance() { bool die = _unreference_owner_unsafe(); CRASH_COND(die); // `owner_keep_alive` holds a reference, so it can't die - void *data = CSharpLanguage::get_instance_binding(owner); + void *data = CSharpLanguage::get_instance_binding_with_setup(owner); CRASH_COND(data == nullptr); CSharpScriptBinding &script_binding = ((RBMap<Object *, CSharpScriptBinding>::Element *)data)->get(); CRASH_COND(!script_binding.inited); |