summaryrefslogtreecommitdiff
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.cpp128
1 files changed, 57 insertions, 71 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index c3608693f1..28bacbd0f0 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -150,8 +150,8 @@ void CSharpLanguage::finish() {
for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) {
CSharpScriptBinding &script_binding = E->value();
- if (script_binding.gchandle.is_valid()) {
- script_binding.gchandle->release();
+ if (!script_binding.gchandle.is_released()) {
+ script_binding.gchandle.release();
script_binding.inited = false;
}
}
@@ -461,8 +461,11 @@ static String variant_type_to_managed_name(const String &p_var_type_name) {
Variant::BOOL,
Variant::INT,
Variant::VECTOR2,
+ Variant::VECTOR2I,
Variant::RECT2,
+ Variant::RECT2I,
Variant::VECTOR3,
+ Variant::VECTOR3I,
Variant::TRANSFORM2D,
Variant::PLANE,
Variant::QUAT,
@@ -676,7 +679,7 @@ void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
void CSharpLanguage::frame() {
if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != NULL) {
- const Ref<MonoGCHandle> &task_scheduler_handle = GDMonoCache::cached_data.task_scheduler_handle;
+ const Ref<MonoGCHandleRef> &task_scheduler_handle = GDMonoCache::cached_data.task_scheduler_handle;
if (task_scheduler_handle.is_valid()) {
MonoObject *task_scheduler = task_scheduler_handle->get_target();
@@ -804,7 +807,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
for (SelfList<ManagedCallable> *elem = ManagedCallable::instances.first(); elem; elem = elem->next()) {
ManagedCallable *managed_callable = elem->self();
- MonoDelegate *delegate = (MonoDelegate *)managed_callable->delegate_handle->get_target();
+ MonoDelegate *delegate = (MonoDelegate *)managed_callable->delegate_handle.get_target();
Array serialized_data;
MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data);
@@ -1278,6 +1281,7 @@ bool CSharpLanguage::debug_break(const String &p_error, bool p_allow_continue) {
void CSharpLanguage::_on_scripts_domain_unloaded() {
for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) {
CSharpScriptBinding &script_binding = E->value();
+ script_binding.gchandle.release();
script_binding.inited = false;
}
@@ -1286,7 +1290,7 @@ void CSharpLanguage::_on_scripts_domain_unloaded() {
for (SelfList<ManagedCallable> *elem = ManagedCallable::instances.first(); elem; elem = elem->next()) {
ManagedCallable *managed_callable = elem->self();
- managed_callable->delegate_handle.unref();
+ managed_callable->delegate_handle.release();
managed_callable->delegate_invoke = NULL;
}
}
@@ -1328,33 +1332,33 @@ void CSharpLanguage::set_language_index(int p_idx) {
lang_idx = p_idx;
}
-void CSharpLanguage::release_script_gchandle(Ref<MonoGCHandle> &p_gchandle) {
+void CSharpLanguage::release_script_gchandle(MonoGCHandleData &p_gchandle) {
- if (!p_gchandle->is_released()) { // Do not lock unnecessarily
+ if (!p_gchandle.is_released()) { // Do not lock unnecessarily
MutexLock lock(get_singleton()->script_gchandle_release_mutex);
- p_gchandle->release();
+ p_gchandle.release();
}
}
-void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, Ref<MonoGCHandle> &p_gchandle) {
+void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, MonoGCHandleData &p_gchandle) {
- uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(p_expected_obj); // We might lock after this, so pin it
+ uint32_t pinned_gchandle = GDMonoUtils::new_strong_gchandle_pinned(p_expected_obj); // We might lock after this, so pin it
- if (!p_gchandle->is_released()) { // Do not lock unnecessarily
+ if (!p_gchandle.is_released()) { // Do not lock unnecessarily
MutexLock lock(get_singleton()->script_gchandle_release_mutex);
- MonoObject *target = p_gchandle->get_target();
+ MonoObject *target = p_gchandle.get_target();
// We release the gchandle if it points to the MonoObject* we expect (otherwise it was
// already released and could have been replaced) or if we can't get its target MonoObject*
// (which doesn't necessarily mean it was released, and we want it released in order to
// avoid locking other threads unnecessarily).
if (target == p_expected_obj || target == NULL) {
- p_gchandle->release();
+ p_gchandle.release();
}
}
- MonoGCHandle::free_handle(pinned_gchandle);
+ GDMonoUtils::free_gchandle(pinned_gchandle);
}
CSharpLanguage::CSharpLanguage() {
@@ -1399,7 +1403,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
r_script_binding.inited = true;
r_script_binding.type_name = type_name;
r_script_binding.wrapper_class = type_class; // cache
- r_script_binding.gchandle = MonoGCHandle::create_strong(mono_object);
+ r_script_binding.gchandle = MonoGCHandleData::new_strong_handle(mono_object);
r_script_binding.owner = p_object;
// Tie managed to unmanaged
@@ -1464,10 +1468,11 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
if (script_binding.inited) {
// Set the native instance field to IntPtr.Zero, if not yet garbage collected.
// This is done to avoid trying to dispose the native instance from Dispose(bool).
- MonoObject *mono_object = script_binding.gchandle->get_target();
+ MonoObject *mono_object = script_binding.gchandle.get_target();
if (mono_object) {
CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, NULL);
}
+ script_binding.gchandle.release();
}
script_bindings.erase(data);
@@ -1487,26 +1492,26 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
CRASH_COND(!data);
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
- Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
+ MonoGCHandleData &gchandle = script_binding.gchandle;
if (!script_binding.inited)
return;
- if (ref_owner->reference_get_count() > 1 && gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ if (ref_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();
+ 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.
- uint32_t strong_gchandle = MonoGCHandle::new_strong_handle(target);
- gchandle->release();
- gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE);
+ MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(target);
+ gchandle.release();
+ gchandle = strong_gchandle;
}
}
@@ -1523,27 +1528,27 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
CRASH_COND(!data);
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
- Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
+ MonoGCHandleData &gchandle = script_binding.gchandle;
int refcount = ref_owner->reference_get_count();
if (!script_binding.inited)
return refcount == 0;
- if (refcount == 1 && gchandle.is_valid() && !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;
// If owner owner is no longer referenced by the unmanaged side,
// the managed instance takes responsibility of deleting the owner when GCed.
- MonoObject *target = gchandle->get_target();
+ MonoObject *target = gchandle.get_target();
if (!target)
return refcount == 0; // Called after the managed side was collected, so nothing to do here
// Release the current strong handle and replace it with a weak handle.
- uint32_t weak_gchandle = MonoGCHandle::new_weak_handle(target);
- gchandle->release();
- gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE);
+ MonoGCHandleData weak_gchandle = MonoGCHandleData::new_weak_handle(target);
+ gchandle.release();
+ gchandle = weak_gchandle;
return false;
}
@@ -1551,7 +1556,7 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
return refcount == 0;
}
-CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref<MonoGCHandle> &p_gchandle) {
+CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const MonoGCHandleData &p_gchandle) {
CSharpInstance *instance = memnew(CSharpInstance(Ref<CSharpScript>(p_script)));
@@ -1571,8 +1576,8 @@ CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpS
MonoObject *CSharpInstance::get_mono_object() const {
- ERR_FAIL_COND_V(gchandle.is_null(), NULL);
- return gchandle->get_target();
+ ERR_FAIL_COND_V(gchandle.is_released(), NULL);
+ return gchandle.get_target();
}
Object *CSharpInstance::get_owner() {
@@ -1945,10 +1950,6 @@ bool CSharpInstance::_unreference_owner_unsafe() {
}
MonoObject *CSharpInstance::_internal_new_managed() {
-#ifdef DEBUG_ENABLED
- CRASH_COND(!gchandle.is_valid());
-#endif
-
// Search the constructor first, to fail with an error if it's not found before allocating anything else.
GDMonoMethod *ctor = script->script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
ERR_FAIL_NULL_V_MSG(ctor, NULL,
@@ -1975,7 +1976,7 @@ MonoObject *CSharpInstance::_internal_new_managed() {
}
// Tie managed to unmanaged
- gchandle = MonoGCHandle::create_strong(mono_object);
+ gchandle = MonoGCHandleData::new_strong_handle(mono_object);
if (base_ref)
_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
@@ -1994,7 +1995,7 @@ void CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
#ifdef DEBUG_ENABLED
CRASH_COND(base_ref);
- CRASH_COND(gchandle.is_null());
+ CRASH_COND(gchandle.is_released());
#endif
CSharpLanguage::get_singleton()->release_script_gchandle(p_obj, gchandle);
}
@@ -2003,7 +2004,7 @@ void CSharpInstance::mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_f
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
- CRASH_COND(gchandle.is_null());
+ CRASH_COND(gchandle.is_released());
#endif
r_remove_script_instance = false;
@@ -2069,7 +2070,7 @@ void CSharpInstance::refcount_incremented() {
Reference *ref_owner = Object::cast_to<Reference>(owner);
- if (ref_owner->reference_get_count() > 1 && gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ if (ref_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.
@@ -2077,9 +2078,9 @@ void CSharpInstance::refcount_incremented() {
// so the owner must hold the managed side alive again to avoid it from being GCed.
// Release the current weak handle and replace it with a strong handle.
- uint32_t strong_gchandle = MonoGCHandle::new_strong_handle(gchandle->get_target());
- gchandle->release();
- gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE);
+ MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(gchandle.get_target());
+ gchandle.release();
+ gchandle = strong_gchandle;
}
}
@@ -2094,16 +2095,16 @@ bool CSharpInstance::refcount_decremented() {
int refcount = ref_owner->reference_get_count();
- if (refcount == 1 && !gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ if (refcount == 1 && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
GD_MONO_SCOPE_THREAD_ATTACH;
// If owner owner is no longer referenced by the unmanaged side,
// the managed instance takes responsibility of deleting the owner when GCed.
// Release the current strong handle and replace it with a weak handle.
- uint32_t weak_gchandle = MonoGCHandle::new_weak_handle(gchandle->get_target());
- gchandle->release();
- gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE);
+ MonoGCHandleData weak_gchandle = MonoGCHandleData::new_weak_handle(gchandle.get_target());
+ gchandle.release();
+ gchandle = weak_gchandle;
return false;
}
@@ -2269,7 +2270,7 @@ CSharpInstance::~CSharpInstance() {
destructing_script_instance = true;
- if (gchandle.is_valid()) {
+ if (!gchandle.is_released()) {
if (!predelete_notified && !ref_dying) {
// This destructor is not called from the owners destructor.
// This could be being called from the owner's set_script_instance method,
@@ -2277,7 +2278,7 @@ CSharpInstance::~CSharpInstance() {
// we must call Dispose here, because Dispose calls owner->set_script_instance(NULL)
// and that would mess up with the new script instance if called later.
- MonoObject *mono_object = gchandle->get_target();
+ MonoObject *mono_object = gchandle.get_target();
if (mono_object) {
MonoException *exc = NULL;
@@ -2289,7 +2290,7 @@ CSharpInstance::~CSharpInstance() {
}
}
- gchandle->release(); // Make sure the gchandle is released
+ gchandle.release(); // Make sure the gchandle is released
}
// If not being called from the owner's destructor, and we still hold a reference to the owner
@@ -2449,7 +2450,7 @@ bool CSharpScript::_update_exports() {
return false;
}
- uint32_t tmp_pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(tmp_object); // pin it (not sure if needed)
+ uint32_t tmp_pinned_gchandle = GDMonoUtils::new_strong_gchandle_pinned(tmp_object); // pin it (not sure if needed)
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
@@ -2464,7 +2465,7 @@ bool CSharpScript::_update_exports() {
if (ctor_exc) {
// TODO: Should we free 'tmp_native' if the exception was thrown after its creation?
- MonoGCHandle::free_handle(tmp_pinned_gchandle);
+ GDMonoUtils::free_gchandle(tmp_pinned_gchandle);
tmp_object = NULL;
ERR_PRINT("Exception thrown from constructor of temporary MonoObject:");
@@ -2543,7 +2544,7 @@ bool CSharpScript::_update_exports() {
GDMonoUtils::debug_print_unhandled_exception(exc);
}
- MonoGCHandle::free_handle(tmp_pinned_gchandle);
+ GDMonoUtils::free_gchandle(tmp_pinned_gchandle);
tmp_object = NULL;
if (tmp_native && !base_ref) {
@@ -3035,22 +3036,6 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
bool CSharpScript::can_instance() const {
#ifdef TOOLS_ENABLED
- if (Engine::get_singleton()->is_editor_hint()) {
-
- // Hack to lower the risk of attached scripts not being added to the C# project
- if (!get_path().empty() && get_path().find("::") == -1) { // Ignore if built-in script. Can happen if the file is deleted...
- if (_create_project_solution_if_needed()) {
- CSharpProject::add_item(GodotSharpDirs::get_project_csproj_path(),
- "Compile",
- ProjectSettings::get_singleton()->globalize_path(get_path()));
- } else {
- ERR_PRINT("C# project could not be created; cannot add file: '" + get_path() + "'.");
- }
- }
- }
-#endif
-
-#ifdef TOOLS_ENABLED
bool extra_cond = tool || ScriptServer::is_scripting_enabled();
#else
bool extra_cond = true;
@@ -3109,8 +3094,8 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
CRASH_COND(data == NULL);
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
- if (script_binding.inited && script_binding.gchandle.is_valid()) {
- MonoObject *mono_object = script_binding.gchandle->get_target();
+ if (script_binding.inited && !script_binding.gchandle.is_released()) {
+ MonoObject *mono_object = script_binding.gchandle.get_target();
if (mono_object) {
MonoException *exc = NULL;
GDMonoUtils::dispose(mono_object, &exc);
@@ -3120,6 +3105,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
}
}
+ script_binding.gchandle.release(); // Just in case
script_binding.inited = false;
}
}
@@ -3148,7 +3134,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
}
// Tie managed to unmanaged
- instance->gchandle = MonoGCHandle::create_strong(mono_object);
+ instance->gchandle = MonoGCHandleData::new_strong_handle(mono_object);
if (instance->base_ref)
instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)