Merge pull request #51739 from neikeq/fix-csharp-instance-bindings
Fix C# native instance bindings after recent re-write
This commit is contained in:
commit
2735f829c9
|
@ -1811,6 +1811,21 @@ void *Object::get_instance_binding(void *p_token, const GDNativeInstanceBindingC
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Object::has_instance_binding(void *p_token) {
|
||||||
|
bool found = false;
|
||||||
|
_instance_binding_mutex.lock();
|
||||||
|
for (uint32_t i = 0; i < _instance_binding_count; i++) {
|
||||||
|
if (_instance_bindings[i].token == p_token) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_instance_binding_mutex.unlock();
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
void Object::_construct_object(bool p_reference) {
|
void Object::_construct_object(bool p_reference) {
|
||||||
type_is_reference = p_reference;
|
type_is_reference = p_reference;
|
||||||
_instance_id = ObjectDB::add_instance(this);
|
_instance_id = ObjectDB::add_instance(this);
|
||||||
|
|
|
@ -809,6 +809,7 @@ public:
|
||||||
void *get_instance_binding(void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks);
|
void *get_instance_binding(void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks);
|
||||||
// Used on creation by binding only.
|
// Used on creation by binding only.
|
||||||
void set_instance_binding(void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks);
|
void set_instance_binding(void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks);
|
||||||
|
bool has_instance_binding(void *p_token);
|
||||||
|
|
||||||
void clear_internal_resource_paths();
|
void clear_internal_resource_paths();
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,12 @@ static bool _create_project_solution_if_needed() {
|
||||||
|
|
||||||
CSharpLanguage *CSharpLanguage::singleton = nullptr;
|
CSharpLanguage *CSharpLanguage::singleton = nullptr;
|
||||||
|
|
||||||
|
GDNativeInstanceBindingCallbacks CSharpLanguage::_instance_binding_callbacks = {
|
||||||
|
&_instance_binding_create_callback,
|
||||||
|
&_instance_binding_free_callback,
|
||||||
|
&_instance_binding_reference_callback
|
||||||
|
};
|
||||||
|
|
||||||
String CSharpLanguage::get_name() const {
|
String CSharpLanguage::get_name() const {
|
||||||
return "C#";
|
return "C#";
|
||||||
}
|
}
|
||||||
|
@ -1444,46 +1450,46 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
|
Map<Object *, CSharpScriptBinding>::Element *CSharpLanguage::insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding) {
|
||||||
MutexLock lock(language_bind_mutex);
|
return script_bindings.insert(p_object, p_script_binding);
|
||||||
|
}
|
||||||
|
|
||||||
Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
|
void *CSharpLanguage::_instance_binding_create_callback(void *, void *p_instance) {
|
||||||
|
CSharpLanguage *csharp_lang = CSharpLanguage::get_singleton();
|
||||||
|
|
||||||
|
MutexLock lock(csharp_lang->language_bind_mutex);
|
||||||
|
|
||||||
|
Map<Object *, CSharpScriptBinding>::Element *match = csharp_lang->script_bindings.find((Object *)p_instance);
|
||||||
if (match) {
|
if (match) {
|
||||||
return (void *)match;
|
return (void *)match;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSharpScriptBinding script_binding;
|
CSharpScriptBinding script_binding;
|
||||||
|
|
||||||
if (!setup_csharp_script_binding(script_binding, p_object)) {
|
return (void *)csharp_lang->insert_script_binding((Object *)p_instance, script_binding);
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (void *)insert_script_binding(p_object, script_binding);
|
void CSharpLanguage::_instance_binding_free_callback(void *, void *, void *p_binding) {
|
||||||
}
|
CSharpLanguage *csharp_lang = CSharpLanguage::get_singleton();
|
||||||
|
|
||||||
Map<Object *, CSharpScriptBinding>::Element *CSharpLanguage::insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding) {
|
|
||||||
return script_bindings.insert(p_object, p_script_binding);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSharpLanguage::free_instance_binding_data(void *p_data) {
|
|
||||||
if (GDMono::get_singleton() == nullptr) {
|
if (GDMono::get_singleton() == nullptr) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
CRASH_COND(!script_bindings.is_empty());
|
CRASH_COND(!csharp_lang->script_bindings.is_empty());
|
||||||
#endif
|
#endif
|
||||||
// Mono runtime finalized, all the gchandle bindings were already released
|
// Mono runtime finalized, all the gchandle bindings were already released
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finalizing) {
|
if (csharp_lang->finalizing) {
|
||||||
return; // inside CSharpLanguage::finish(), all the gchandle bindings are released there
|
return; // inside CSharpLanguage::finish(), all the gchandle bindings are released there
|
||||||
}
|
}
|
||||||
|
|
||||||
GD_MONO_ASSERT_THREAD_ATTACHED;
|
GD_MONO_ASSERT_THREAD_ATTACHED;
|
||||||
|
|
||||||
{
|
{
|
||||||
MutexLock lock(language_bind_mutex);
|
MutexLock lock(csharp_lang->language_bind_mutex);
|
||||||
|
|
||||||
Map<Object *, CSharpScriptBinding>::Element *data = (Map<Object *, CSharpScriptBinding>::Element *)p_data;
|
Map<Object *, CSharpScriptBinding>::Element *data = (Map<Object *, CSharpScriptBinding>::Element *)p_binding;
|
||||||
|
|
||||||
CSharpScriptBinding &script_binding = data->value();
|
CSharpScriptBinding &script_binding = data->value();
|
||||||
|
|
||||||
|
@ -1497,62 +1503,21 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
|
||||||
script_binding.gchandle.release();
|
script_binding.gchandle.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
script_bindings.erase(data);
|
csharp_lang->script_bindings.erase(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
|
GDNativeBool CSharpLanguage::_instance_binding_reference_callback(void *p_token, void *p_binding, GDNativeBool p_reference) {
|
||||||
#if 0
|
CRASH_COND(!p_binding);
|
||||||
RefCounted *rc_owner = Object::cast_to<RefCounted>(p_object);
|
|
||||||
|
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)p_binding)->get();
|
||||||
|
|
||||||
|
RefCounted *rc_owner = Object::cast_to<RefCounted>(script_binding.owner);
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
CRASH_COND(!rc_owner);
|
CRASH_COND(!rc_owner);
|
||||||
CRASH_COND(!p_object->has_script_instance_binding(get_language_index()));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *data = p_object->get_script_instance_binding(get_language_index());
|
|
||||||
CRASH_COND(!data);
|
|
||||||
|
|
||||||
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
|
||||||
MonoGCHandleData &gchandle = script_binding.gchandle;
|
|
||||||
|
|
||||||
if (!script_binding.inited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
|
|
||||||
GD_MONO_SCOPE_THREAD_ATTACH;
|
|
||||||
|
|
||||||
// The reference count was increased after the managed side was the only one referencing our owner.
|
|
||||||
// This means the owner is being referenced again by the unmanaged side,
|
|
||||||
// so the owner must hold the managed side alive again to avoid it from being GCed.
|
|
||||||
|
|
||||||
MonoObject *target = gchandle.get_target();
|
|
||||||
if (!target) {
|
|
||||||
return; // Called after the managed side was collected, so nothing to do here
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release the current weak handle and replace it with a strong handle.
|
|
||||||
MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(target);
|
|
||||||
gchandle.release();
|
|
||||||
gchandle = strong_gchandle;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
|
|
||||||
#if 0
|
|
||||||
RefCounted *rc_owner = Object::cast_to<RefCounted>(p_object);
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
CRASH_COND(!rc_owner);
|
|
||||||
CRASH_COND(!p_object->has_script_instance_binding(get_language_index()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *data = p_object->get_script_instance_binding(get_language_index());
|
|
||||||
CRASH_COND(!data);
|
|
||||||
|
|
||||||
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
|
||||||
MonoGCHandleData &gchandle = script_binding.gchandle;
|
MonoGCHandleData &gchandle = script_binding.gchandle;
|
||||||
|
|
||||||
int refcount = rc_owner->reference_get_count();
|
int refcount = rc_owner->reference_get_count();
|
||||||
|
@ -1561,6 +1526,29 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
|
||||||
return refcount == 0;
|
return refcount == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_reference) {
|
||||||
|
// Refcount incremented
|
||||||
|
if (refcount > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
|
||||||
|
GD_MONO_SCOPE_THREAD_ATTACH;
|
||||||
|
|
||||||
|
// The reference count was increased after the managed side was the only one referencing our owner.
|
||||||
|
// This means the owner is being referenced again by the unmanaged side,
|
||||||
|
// so the owner must hold the managed side alive again to avoid it from being GCed.
|
||||||
|
|
||||||
|
MonoObject *target = gchandle.get_target();
|
||||||
|
if (!target) {
|
||||||
|
return false; // Called after the managed side was collected, so nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release the current weak handle and replace it with a strong handle.
|
||||||
|
MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(target);
|
||||||
|
gchandle.release();
|
||||||
|
gchandle = strong_gchandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// Refcount decremented
|
||||||
if (refcount == 1 && !gchandle.is_released() && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
|
if (refcount == 1 && !gchandle.is_released() && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
|
||||||
GD_MONO_SCOPE_THREAD_ATTACH;
|
GD_MONO_SCOPE_THREAD_ATTACH;
|
||||||
|
|
||||||
|
@ -1581,8 +1569,44 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return refcount == 0;
|
return refcount == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *CSharpLanguage::get_instance_binding(Object *p_object) {
|
||||||
|
void *binding = p_object->get_instance_binding(get_singleton(), &_instance_binding_callbacks);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// `setup_csharp_script_binding` may call `reference()`. It was moved here outside to fix that.
|
||||||
|
|
||||||
|
if (binding) {
|
||||||
|
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)binding)->value();
|
||||||
|
|
||||||
|
if (!script_binding.inited) {
|
||||||
|
MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
|
||||||
|
|
||||||
|
if (!script_binding.inited) { // Another thread may have set it up
|
||||||
|
CSharpLanguage::get_singleton()->setup_csharp_script_binding(script_binding, p_object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *CSharpLanguage::get_existing_instance_binding(Object *p_object) {
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
CRASH_COND(p_object->has_instance_binding(p_object));
|
||||||
#endif
|
#endif
|
||||||
return false;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSharpLanguage::has_instance_binding(Object *p_object) {
|
||||||
|
return p_object->has_instance_binding(get_singleton());
|
||||||
}
|
}
|
||||||
|
|
||||||
CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const MonoGCHandleData &p_gchandle) {
|
CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const MonoGCHandleData &p_gchandle) {
|
||||||
|
@ -2260,28 +2284,15 @@ CSharpInstance::~CSharpInstance() {
|
||||||
// Otherwise, the unsafe reference debug checks will incorrectly detect a bug.
|
// Otherwise, the unsafe reference debug checks will incorrectly detect a bug.
|
||||||
bool die = _unreference_owner_unsafe();
|
bool die = _unreference_owner_unsafe();
|
||||||
CRASH_COND(die); // `owner_keep_alive` holds a reference, so it can't die
|
CRASH_COND(die); // `owner_keep_alive` holds a reference, so it can't die
|
||||||
#if 0
|
|
||||||
void *data = owner->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
|
|
||||||
|
|
||||||
|
|
||||||
|
void *data = CSharpLanguage::get_instance_binding(owner);
|
||||||
CRASH_COND(data == nullptr);
|
CRASH_COND(data == nullptr);
|
||||||
|
|
||||||
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
||||||
|
|
||||||
if (!script_binding.inited) {
|
|
||||||
MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
|
|
||||||
|
|
||||||
if (!script_binding.inited) { // Other thread may have set it up
|
|
||||||
// Already had a binding that needs to be setup
|
|
||||||
CSharpLanguage::get_singleton()->setup_csharp_script_binding(script_binding, owner);
|
|
||||||
CRASH_COND(!script_binding.inited);
|
CRASH_COND(!script_binding.inited);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
// The "instance binding" holds a reference so the refcount should be at least 2 before `scope_keep_owner_alive` goes out of scope
|
// The "instance binding" holds a reference so the refcount should be at least 2 before `scope_keep_owner_alive` goes out of scope
|
||||||
CRASH_COND(rc_owner->reference_get_count() <= 1);
|
CRASH_COND(rc_owner->reference_get_count() <= 1);
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3100,10 +3111,10 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
|
||||||
// Hold it alive. Important if we have to dispose a script instance binding before creating the CSharpInstance.
|
// Hold it alive. Important if we have to dispose a script instance binding before creating the CSharpInstance.
|
||||||
ref = Ref<RefCounted>(static_cast<RefCounted *>(p_owner));
|
ref = Ref<RefCounted>(static_cast<RefCounted *>(p_owner));
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
// If the object had a script instance binding, dispose it before adding the CSharpInstance
|
// If the object had a script instance binding, dispose it before adding the CSharpInstance
|
||||||
if (p_owner->has_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index())) {
|
if (CSharpLanguage::has_instance_binding(p_owner)) {
|
||||||
void *data = p_owner->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
|
void *data = CSharpLanguage::get_existing_instance_binding(p_owner);
|
||||||
CRASH_COND(data == nullptr);
|
CRASH_COND(data == nullptr);
|
||||||
|
|
||||||
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
||||||
|
@ -3122,7 +3133,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
|
||||||
script_binding.inited = false;
|
script_binding.inited = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
CSharpInstance *instance = memnew(CSharpInstance(Ref<CSharpScript>(this)));
|
CSharpInstance *instance = memnew(CSharpInstance(Ref<CSharpScript>(this)));
|
||||||
instance->base_ref_counted = p_is_ref_counted;
|
instance->base_ref_counted = p_is_ref_counted;
|
||||||
instance->owner = p_owner;
|
instance->owner = p_owner;
|
||||||
|
|
|
@ -401,7 +401,18 @@ class CSharpLanguage : public ScriptLanguage {
|
||||||
static void _editor_init_callback();
|
static void _editor_init_callback();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void *_instance_binding_create_callback(void *p_token, void *p_instance);
|
||||||
|
static void _instance_binding_free_callback(void *p_token, void *p_instance, void *p_binding);
|
||||||
|
static GDNativeBool _instance_binding_reference_callback(void *p_token, void *p_binding, GDNativeBool p_reference);
|
||||||
|
|
||||||
|
static GDNativeInstanceBindingCallbacks _instance_binding_callbacks;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static void *get_instance_binding(Object *p_object);
|
||||||
|
static void *get_existing_instance_binding(Object *p_object);
|
||||||
|
static void set_instance_binding(Object *p_object, void *p_binding);
|
||||||
|
static bool has_instance_binding(Object *p_object);
|
||||||
|
|
||||||
StringNameCache string_names;
|
StringNameCache string_names;
|
||||||
|
|
||||||
const Mutex &get_language_bind_mutex() { return language_bind_mutex; }
|
const Mutex &get_language_bind_mutex() { return language_bind_mutex; }
|
||||||
|
@ -507,12 +518,6 @@ public:
|
||||||
void thread_enter() override;
|
void thread_enter() override;
|
||||||
void thread_exit() override;
|
void thread_exit() override;
|
||||||
|
|
||||||
// Don't use these. I'm watching you
|
|
||||||
void *alloc_instance_binding_data(Object *p_object) override;
|
|
||||||
void free_instance_binding_data(void *p_data) override;
|
|
||||||
void refcount_incremented_instance_binding(Object *p_object) override;
|
|
||||||
bool refcount_decremented_instance_binding(Object *p_object) override;
|
|
||||||
|
|
||||||
Map<Object *, CSharpScriptBinding>::Element *insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding);
|
Map<Object *, CSharpScriptBinding>::Element *insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding);
|
||||||
bool setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object);
|
bool setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object);
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,8 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
void *data = p_ptr->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
|
void *data = CSharpLanguage::get_existing_instance_binding(p_ptr);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
||||||
|
@ -76,7 +76,6 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void godot_icall_RefCounted_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) {
|
||||||
|
@ -85,7 +84,7 @@ void godot_icall_RefCounted_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoole
|
||||||
// This is only called with RefCounted derived classes
|
// This is only called with RefCounted derived classes
|
||||||
CRASH_COND(!Object::cast_to<RefCounted>(p_ptr));
|
CRASH_COND(!Object::cast_to<RefCounted>(p_ptr));
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
|
||||||
RefCounted *rc = static_cast<RefCounted *>(p_ptr);
|
RefCounted *rc = static_cast<RefCounted *>(p_ptr);
|
||||||
|
|
||||||
if (rc->get_script_instance()) {
|
if (rc->get_script_instance()) {
|
||||||
|
@ -113,7 +112,7 @@ void godot_icall_RefCounted_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoole
|
||||||
if (rc->unreference()) {
|
if (rc->unreference()) {
|
||||||
memdelete(rc);
|
memdelete(rc);
|
||||||
} else {
|
} else {
|
||||||
void *data = rc->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
|
void *data = CSharpLanguage::get_existing_instance_binding(rc);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
|
||||||
|
@ -125,7 +124,6 @@ void godot_icall_RefCounted_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoole
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void godot_icall_Object_ConnectEventSignals(Object *p_ptr) {
|
void godot_icall_Object_ConnectEventSignals(Object *p_ptr) {
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
namespace GDMonoInternals {
|
namespace GDMonoInternals {
|
||||||
void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
|
void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
|
||||||
// This method should not fail
|
// This method should not fail
|
||||||
#if 0
|
|
||||||
CRASH_COND(!unmanaged);
|
CRASH_COND(!unmanaged);
|
||||||
|
|
||||||
// All mono objects created from the managed world (e.g.: 'new Player()')
|
// All mono objects created from the managed world (e.g.: 'new Player()')
|
||||||
|
@ -89,12 +89,12 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The object was just created, no script instance binding should have been attached
|
// The object was just created, no script instance binding should have been attached
|
||||||
CRASH_COND(unmanaged->has_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index()));
|
CRASH_COND(CSharpLanguage::has_instance_binding(unmanaged));
|
||||||
|
|
||||||
void *data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(unmanaged, script_binding);
|
void *data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(unmanaged, script_binding);
|
||||||
|
|
||||||
// Should be thread safe because the object was just created and nothing else should be referencing it
|
// Should be thread safe because the object was just created and nothing else should be referencing it
|
||||||
unmanaged->set_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index(), data);
|
CSharpLanguage::set_instance_binding(unmanaged, data);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,6 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
|
||||||
CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);
|
CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);
|
||||||
|
|
||||||
unmanaged->set_script_and_instance(script, csharp_instance);
|
unmanaged->set_script_and_instance(script, csharp_instance);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unhandled_exception(MonoException *p_exc) {
|
void unhandled_exception(MonoException *p_exc) {
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
namespace GDMonoUtils {
|
namespace GDMonoUtils {
|
||||||
|
|
||||||
MonoObject *unmanaged_get_managed(Object *unmanaged) {
|
MonoObject *unmanaged_get_managed(Object *unmanaged) {
|
||||||
#if 0
|
|
||||||
if (!unmanaged) {
|
if (!unmanaged) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -69,22 +68,10 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
|
||||||
|
|
||||||
// If the owner does not have a CSharpInstance...
|
// If the owner does not have a CSharpInstance...
|
||||||
|
|
||||||
void *data = unmanaged->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
|
void *data = CSharpLanguage::get_instance_binding(unmanaged);
|
||||||
|
|
||||||
ERR_FAIL_NULL_V(data, nullptr);
|
ERR_FAIL_NULL_V(data, nullptr);
|
||||||
|
|
||||||
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
|
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
|
||||||
|
|
||||||
if (!script_binding.inited) {
|
|
||||||
MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
|
|
||||||
|
|
||||||
if (!script_binding.inited) { // Other thread may have set it up
|
|
||||||
// Already had a binding that needs to be setup
|
|
||||||
CSharpLanguage::get_singleton()->setup_csharp_script_binding(script_binding, unmanaged);
|
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!script_binding.inited, nullptr);
|
ERR_FAIL_COND_V(!script_binding.inited, nullptr);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoGCHandleData &gchandle = script_binding.gchandle;
|
MonoGCHandleData &gchandle = script_binding.gchandle;
|
||||||
|
|
||||||
|
@ -121,8 +108,6 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return mono_object;
|
return mono_object;
|
||||||
#endif
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_main_thread(MonoThread *p_thread) {
|
void set_main_thread(MonoThread *p_thread) {
|
||||||
|
|
Loading…
Reference in a new issue