summaryrefslogtreecommitdiffstats
path: root/modules/mono/csharp_script.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/csharp_script.cpp')
-rw-r--r--modules/mono/csharp_script.cpp59
1 files changed, 48 insertions, 11 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 36c8a40ed9..3d12994469 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -148,7 +148,7 @@ void CSharpLanguage::finalize() {
finalizing = true;
- // Make sure all script binding gchandles are released before finalizing GDMono
+ // Make sure all script binding gchandles are released before finalizing GDMono.
for (KeyValue<Object *, CSharpScriptBinding> &E : script_bindings) {
CSharpScriptBinding &script_binding = E.value;
@@ -156,6 +156,10 @@ void CSharpLanguage::finalize() {
script_binding.gchandle.release();
script_binding.inited = false;
}
+
+ // Make sure we clear all the instance binding callbacks so they don't get called
+ // after finalizing the C# language.
+ script_binding.owner->free_instance_binding(this);
}
if (gdmono) {
@@ -1227,6 +1231,11 @@ void CSharpLanguage::_instance_binding_free_callback(void *, void *, void *p_bin
}
GDExtensionBool CSharpLanguage::_instance_binding_reference_callback(void *p_token, void *p_binding, GDExtensionBool p_reference) {
+ // Instance bindings callbacks can only be called if the C# language is available.
+ // Failing this assert usually means that we didn't clear the instance binding in some Object
+ // and the C# language has already been finalized.
+ DEV_ASSERT(CSharpLanguage::get_singleton() != nullptr);
+
CRASH_COND(!p_binding);
CSharpScriptBinding &script_binding = ((RBMap<Object *, CSharpScriptBinding>::Element *)p_binding)->get();
@@ -1488,11 +1497,23 @@ bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const {
void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
List<PropertyInfo> props;
- script->get_script_property_list(&props);
+ ERR_FAIL_COND(!script.is_valid());
+#ifdef TOOLS_ENABLED
+ for (const PropertyInfo &prop : script->exported_members_cache) {
+ props.push_back(prop);
+ }
+#else
+ for (const KeyValue<StringName, PropertyInfo> &E : script->member_info) {
+ props.push_front(E.value);
+ }
+#endif
- // Call _get_property_list
+ for (PropertyInfo &prop : props) {
+ validate_property(prop);
+ p_properties->push_back(prop);
+ }
- ERR_FAIL_COND(!script.is_valid());
+ // Call _get_property_list
StringName method = SNAME("_get_property_list");
@@ -1515,9 +1536,25 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
}
}
- for (PropertyInfo &prop : props) {
- validate_property(prop);
- p_properties->push_back(prop);
+ CSharpScript *top = script.ptr()->base_script.ptr();
+ while (top != nullptr) {
+ props.clear();
+#ifdef TOOLS_ENABLED
+ for (const PropertyInfo &prop : top->exported_members_cache) {
+ props.push_back(prop);
+ }
+#else
+ for (const KeyValue<StringName, PropertyInfo> &E : top->member_info) {
+ props.push_front(E.value);
+ }
+#endif
+
+ for (PropertyInfo &prop : props) {
+ validate_property(prop);
+ p_properties->push_back(prop);
+ }
+
+ top = top->base_script.ptr();
}
}
@@ -1662,7 +1699,7 @@ bool CSharpInstance::_reference_owner_unsafe() {
// but the managed instance is alive, the refcount will be 1 instead of 0.
// See: _unreference_owner_unsafe()
- // May not me referenced yet, so we must use init_ref() instead of reference()
+ // May not be referenced yet, so we must use init_ref() instead of reference()
if (static_cast<RefCounted *>(owner)->init_ref()) {
CSharpLanguage::get_singleton()->post_unsafe_reference(owner);
unsafe_referenced = true;
@@ -2351,8 +2388,8 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
if (!ok) {
// Important to clear this before destroying the script instance here
instance->script = Ref<CSharpScript>();
- instance->owner = nullptr;
p_owner->set_script_instance(nullptr);
+ instance->owner = nullptr;
return nullptr;
}
@@ -2707,7 +2744,7 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
return -1;
}
-const Variant CSharpScript::get_rpc_config() const {
+Variant CSharpScript::get_rpc_config() const {
return rpc_config;
}
@@ -2787,7 +2824,7 @@ Ref<Resource> ResourceFormatLoaderCSharpScript::load(const String &p_path, const
if (GDMonoCache::godot_api_cache_updated) {
GDMonoCache::managed_callbacks.ScriptManagerBridge_GetOrCreateScriptBridgeForPath(&p_path, &scr);
- ERR_FAIL_NULL_V_MSG(scr, Ref<Resource>(), "Could not create C# script '" + real_path + "'.");
+ ERR_FAIL_COND_V_MSG(scr.is_null(), Ref<Resource>(), "Could not create C# script '" + real_path + "'.");
} else {
scr = Ref<CSharpScript>(memnew(CSharpScript));
}