summaryrefslogtreecommitdiff
path: root/modules/mono/glue/base_object_glue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/glue/base_object_glue.cpp')
-rw-r--r--modules/mono/glue/base_object_glue.cpp127
1 files changed, 66 insertions, 61 deletions
diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp
index 02246b2f2f..2b87c2d9a4 100644
--- a/modules/mono/glue/base_object_glue.cpp
+++ b/modules/mono/glue/base_object_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,17 +28,17 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "base_object_glue.h"
-
#ifdef MONO_GLUE_ENABLED
-#include "core/reference.h"
-#include "core/string_name.h"
+#include "core/object/class_db.h"
+#include "core/object/ref_counted.h"
+#include "core/string/string_name.h"
#include "../csharp_script.h"
#include "../mono_gd/gd_mono_cache.h"
#include "../mono_gd/gd_mono_class.h"
#include "../mono_gd/gd_mono_internals.h"
+#include "../mono_gd/gd_mono_marshal.h"
#include "../mono_gd/gd_mono_utils.h"
#include "../signal_awaiter_utils.h"
#include "arguments_vector.h"
@@ -51,7 +51,7 @@ Object *godot_icall_Object_Ctor(MonoObject *p_obj) {
void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
#ifdef DEBUG_ENABLED
- CRASH_COND(p_ptr == NULL);
+ CRASH_COND(p_ptr == nullptr);
#endif
if (p_ptr->get_script_instance()) {
@@ -59,7 +59,7 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
if (cs_instance) {
if (!cs_instance->is_destructing_script_instance()) {
cs_instance->mono_object_disposed(p_obj);
- p_ptr->set_script_instance(NULL);
+ p_ptr->set_script_instance(nullptr);
}
return;
}
@@ -70,25 +70,25 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
if (data) {
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
if (script_binding.inited) {
- Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
- if (gchandle.is_valid()) {
+ MonoGCHandleData &gchandle = script_binding.gchandle;
+ if (!gchandle.is_released()) {
CSharpLanguage::release_script_gchandle(p_obj, gchandle);
}
}
}
}
-void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolean p_is_finalizer) {
+void godot_icall_RefCounted_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolean p_is_finalizer) {
#ifdef DEBUG_ENABLED
- CRASH_COND(p_ptr == NULL);
- // This is only called with Reference derived classes
- CRASH_COND(!Object::cast_to<Reference>(p_ptr));
+ CRASH_COND(p_ptr == nullptr);
+ // This is only called with RefCounted derived classes
+ CRASH_COND(!Object::cast_to<RefCounted>(p_ptr));
#endif
- Reference *ref = static_cast<Reference *>(p_ptr);
+ RefCounted *rc = static_cast<RefCounted *>(p_ptr);
- if (ref->get_script_instance()) {
- CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(ref->get_script_instance());
+ if (rc->get_script_instance()) {
+ CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(rc->get_script_instance());
if (cs_instance) {
if (!cs_instance->is_destructing_script_instance()) {
bool delete_owner;
@@ -97,9 +97,9 @@ void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolea
cs_instance->mono_object_disposed_baseref(p_obj, p_is_finalizer, delete_owner, remove_script_instance);
if (delete_owner) {
- memdelete(ref);
+ memdelete(rc);
} else if (remove_script_instance) {
- ref->set_script_instance(NULL);
+ rc->set_script_instance(nullptr);
}
}
return;
@@ -108,17 +108,17 @@ void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolea
// Unsafe refcount decrement. The managed instance also counts as a reference.
// See: CSharpLanguage::alloc_instance_binding_data(Object *p_object)
- CSharpLanguage::get_singleton()->pre_unsafe_unreference(ref);
- if (ref->unreference()) {
- memdelete(ref);
+ CSharpLanguage::get_singleton()->pre_unsafe_unreference(rc);
+ if (rc->unreference()) {
+ memdelete(rc);
} else {
- void *data = ref->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
+ void *data = rc->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
if (data) {
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
if (script_binding.inited) {
- Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
- if (gchandle.is_valid()) {
+ MonoGCHandleData &gchandle = script_binding.gchandle;
+ if (!gchandle.is_released()) {
CSharpLanguage::release_script_gchandle(p_obj, gchandle);
}
}
@@ -126,37 +126,46 @@ void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolea
}
}
-MethodBind *godot_icall_Object_ClassDB_get_method(MonoString *p_type, MonoString *p_method) {
- StringName type(GDMonoMarshal::mono_string_to_godot(p_type));
+void godot_icall_Object_ConnectEventSignals(Object *p_ptr) {
+ CSharpInstance *csharp_instance = CAST_CSHARP_INSTANCE(p_ptr->get_script_instance());
+ if (csharp_instance) {
+ csharp_instance->connect_event_signals();
+ }
+}
+
+MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString *p_method) {
+ StringName type = p_type ? *p_type : StringName();
StringName method(GDMonoMarshal::mono_string_to_godot(p_method));
return ClassDB::get_method(type, method);
}
-MonoObject *godot_icall_Object_weakref(Object *p_obj) {
- if (!p_obj)
- return NULL;
+MonoObject *godot_icall_Object_weakref(Object *p_ptr) {
+ if (!p_ptr) {
+ return nullptr;
+ }
Ref<WeakRef> wref;
- Reference *ref = Object::cast_to<Reference>(p_obj);
+ RefCounted *rc = Object::cast_to<RefCounted>(p_ptr);
- if (ref) {
- REF r = ref;
- if (!r.is_valid())
- return NULL;
+ if (rc) {
+ REF r = rc;
+ if (!r.is_valid()) {
+ return nullptr;
+ }
- wref.instance();
+ wref.instantiate();
wref->set_ref(r);
} else {
- wref.instance();
- wref->set_obj(p_obj);
+ wref.instantiate();
+ wref->set_obj(p_ptr);
}
return GDMonoUtils::unmanaged_get_managed(wref.ptr());
}
-Error godot_icall_SignalAwaiter_connect(Object *p_source, MonoString *p_signal, Object *p_target, MonoObject *p_awaiter) {
- String signal = GDMonoMarshal::mono_string_to_godot(p_signal);
- return SignalAwaiterUtils::connect_signal_awaiter(p_source, signal, p_target, p_awaiter);
+int32_t godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter) {
+ StringName signal = p_signal ? *p_signal : StringName();
+ return (int32_t)gd_mono_connect_signal_awaiter(p_source, signal, p_target, p_awaiter);
}
MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) {
@@ -189,12 +198,12 @@ MonoBoolean godot_icall_DynamicGodotObject_InvokeMember(Object *p_ptr, MonoStrin
args.set(i, &arg_store.get(i));
}
- Variant::CallError error;
+ Callable::CallError error;
Variant result = p_ptr->call(StringName(name), args.ptr(), argc, error);
*r_result = GDMonoMarshal::variant_to_mono_object(result);
- return error.error == Variant::CallError::CALL_OK;
+ return error.error == Callable::CallError::CALL_OK;
}
MonoBoolean godot_icall_DynamicGodotObject_GetMember(Object *p_ptr, MonoString *p_name, MonoObject **r_result) {
@@ -223,30 +232,26 @@ MonoBoolean godot_icall_DynamicGodotObject_SetMember(Object *p_ptr, MonoString *
MonoString *godot_icall_Object_ToString(Object *p_ptr) {
#ifdef DEBUG_ENABLED
// Cannot happen in C#; would get an ObjectDisposedException instead.
- CRASH_COND(p_ptr == NULL);
-
- if (ScriptDebugger::get_singleton() && !Object::cast_to<Reference>(p_ptr)) { // Only if debugging!
- // Cannot happen either in C#; the handle is nullified when the object is destroyed
- CRASH_COND(!ObjectDB::instance_validate(p_ptr));
- }
+ CRASH_COND(p_ptr == nullptr);
#endif
-
+ // Can't call 'Object::to_string()' here, as that can end up calling 'ToString' again resulting in an endless circular loop.
String result = "[" + p_ptr->get_class() + ":" + itos(p_ptr->get_instance_id()) + "]";
return GDMonoMarshal::mono_string_from_godot(result);
}
void godot_register_object_icalls() {
- mono_add_internal_call("Godot.Object::godot_icall_Object_Ctor", (void *)godot_icall_Object_Ctor);
- mono_add_internal_call("Godot.Object::godot_icall_Object_Disposed", (void *)godot_icall_Object_Disposed);
- mono_add_internal_call("Godot.Object::godot_icall_Reference_Disposed", (void *)godot_icall_Reference_Disposed);
- mono_add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", (void *)godot_icall_Object_ClassDB_get_method);
- mono_add_internal_call("Godot.Object::godot_icall_Object_ToString", (void *)godot_icall_Object_ToString);
- mono_add_internal_call("Godot.Object::godot_icall_Object_weakref", (void *)godot_icall_Object_weakref);
- mono_add_internal_call("Godot.SignalAwaiter::godot_icall_SignalAwaiter_connect", (void *)godot_icall_SignalAwaiter_connect);
- mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMemberList", (void *)godot_icall_DynamicGodotObject_SetMemberList);
- mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_InvokeMember", (void *)godot_icall_DynamicGodotObject_InvokeMember);
- mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_GetMember", (void *)godot_icall_DynamicGodotObject_GetMember);
- mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMember", (void *)godot_icall_DynamicGodotObject_SetMember);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_Ctor", godot_icall_Object_Ctor);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_Disposed", godot_icall_Object_Disposed);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_RefCounted_Disposed", godot_icall_RefCounted_Disposed);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ConnectEventSignals", godot_icall_Object_ConnectEventSignals);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", godot_icall_Object_ClassDB_get_method);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ToString", godot_icall_Object_ToString);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_weakref", godot_icall_Object_weakref);
+ GDMonoUtils::add_internal_call("Godot.SignalAwaiter::godot_icall_SignalAwaiter_connect", godot_icall_SignalAwaiter_connect);
+ GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMemberList", godot_icall_DynamicGodotObject_SetMemberList);
+ GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_InvokeMember", godot_icall_DynamicGodotObject_InvokeMember);
+ GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_GetMember", godot_icall_DynamicGodotObject_GetMember);
+ GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMember", godot_icall_DynamicGodotObject_SetMember);
}
#endif // MONO_GLUE_ENABLED