diff options
Diffstat (limited to 'modules/mono')
-rw-r--r-- | modules/mono/csharp_script.cpp | 73 | ||||
-rw-r--r-- | modules/mono/csharp_script.h | 11 | ||||
-rw-r--r-- | modules/mono/editor/godotsharp_builds.cpp | 6 | ||||
-rw-r--r-- | modules/mono/mono_gc_handle.cpp | 4 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 6 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.cpp | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_utils.h | 4 |
7 files changed, 97 insertions, 9 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 3d91a6de6c..161e130a07 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -122,6 +122,9 @@ void CSharpLanguage::init() { void CSharpLanguage::finish() { + // Release gchandle bindings before finalizing mono runtime + gchandle_bindings.clear(); + if (gdmono) { memdelete(gdmono); gdmono = NULL; @@ -297,6 +300,20 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin return script; } +bool CSharpLanguage::is_using_templates() { + + return true; +} + +void CSharpLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) { + + String src = p_script->get_source_code(); + src = src.replace("%BASE%", p_base_class_name) + .replace("%CLASS%", p_class_name) + .replace("%TS%", _get_indentation()); + p_script->set_source_code(src); +} + Script *CSharpLanguage::create_script() const { return memnew(CSharpScript); @@ -396,6 +413,25 @@ String CSharpLanguage::make_function(const String &p_class, const String &p_name #endif } +String CSharpLanguage::_get_indentation() const { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + bool use_space_indentation = EDITOR_DEF("text_editor/indent/type", 0); + + if (use_space_indentation) { + int indent_size = EDITOR_DEF("text_editor/indent/size", 4); + + String space_indent = ""; + for (int i = 0; i < indent_size; i++) { + space_indent += " "; + } + return space_indent; + } + } +#endif + return "\t"; +} + void CSharpLanguage::frame() { const Ref<MonoGCHandle> &task_scheduler_handle = GDMonoUtils::mono_cache.task_scheduler_handle; @@ -794,6 +830,14 @@ void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) { void CSharpLanguage::free_instance_binding_data(void *p_data) { + if (GDMono::get_singleton() == NULL) { +#ifdef DEBUG_ENABLED + CRASH_COND(!gchandle_bindings.empty()); +#endif + // Mono runtime finalized, all the gchandle bindings were already released + return; + } + #ifndef NO_THREADS script_bind_lock->lock(); #endif @@ -1411,6 +1455,34 @@ void CSharpScript::_resource_path_changed() { } } +bool CSharpScript::_get(const StringName &p_name, Variant &r_ret) const { + + if (p_name == CSharpLanguage::singleton->string_names._script_source) { + + r_ret = get_source_code(); + return true; + } + + return false; +} + +bool CSharpScript::_set(const StringName &p_name, const Variant &p_value) { + + if (p_name == CSharpLanguage::singleton->string_names._script_source) { + + set_source_code(p_value); + reload(); + return true; + } + + return false; +} + +void CSharpScript::_get_property_list(List<PropertyInfo> *p_properties) const { + + p_properties->push_back(PropertyInfo(Variant::STRING, CSharpLanguage::singleton->string_names._script_source, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); +} + void CSharpScript::_bind_methods() { ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &CSharpScript::_new, MethodInfo(Variant::OBJECT, "new")); @@ -1984,5 +2056,6 @@ CSharpLanguage::StringNameCache::StringNameCache() { _set = StaticCString::create("_set"); _get = StaticCString::create("_get"); _notification = StaticCString::create("_notification"); + _script_source = StaticCString::create("script/source"); dotctor = StaticCString::create(".ctor"); } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 65a6450da5..255665b495 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -116,6 +116,9 @@ protected: Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); virtual void _resource_path_changed(); + bool _get(const StringName &p_name, Variant &r_ret) const; + bool _set(const StringName &p_name, const Variant &p_value); + void _get_property_list(List<PropertyInfo> *p_properties) const; public: virtual bool can_instance() const; @@ -228,16 +231,17 @@ class CSharpLanguage : public ScriptLanguage { StringName _set; StringName _get; StringName _notification; + StringName _script_source; StringName dotctor; // .ctor StringNameCache(); }; - StringNameCache string_names; - int lang_idx; public: + StringNameCache string_names; + _FORCE_INLINE_ int get_language_index() { return lang_idx; } void set_language_index(int p_idx); @@ -266,6 +270,8 @@ public: virtual void get_comment_delimiters(List<String> *p_delimiters) const; virtual void get_string_delimiters(List<String> *p_delimiters) const; virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const; + virtual bool is_using_templates(); + virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script); /* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const { return true; } virtual Script *create_script() const; virtual bool has_named_classes() const; @@ -273,6 +279,7 @@ public: /* TODO? */ virtual int find_function(const String &p_function, const String &p_code) const { return -1; } virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; /* TODO? */ Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, String &r_call_hint) { return ERR_UNAVAILABLE; } + virtual String _get_indentation() const; /* TODO? */ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {} /* TODO */ virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) {} diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index 83d2bb1471..dbe0cc294c 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -61,10 +61,10 @@ String _find_build_engine_on_unix(const String &p_name) { }; for (int i = 0; i < sizeof(locations) / sizeof(const char *); i++) { - String location = locations[i]; + String hint_path = locations[i] + p_name; - if (FileAccess::exists(location + p_name)) { - return location; + if (FileAccess::exists(hint_path)) { + return hint_path; } } diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp index d3ad968135..e10e06df0e 100644 --- a/modules/mono/mono_gc_handle.cpp +++ b/modules/mono/mono_gc_handle.cpp @@ -59,6 +59,10 @@ Ref<MonoGCHandle> MonoGCHandle::create_weak(MonoObject *p_object) { void MonoGCHandle::release() { +#ifdef DEBUG_ENABLED + CRASH_COND(GDMono::get_singleton() == NULL); +#endif + if (!released && GDMono::get_singleton()->is_runtime_initialized()) { mono_gchandle_free(handle); released = true; diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 904a8ae2c7..c997b0f000 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -705,7 +705,7 @@ bool _GodotSharp::is_domain_loaded() { void _GodotSharp::queue_dispose(Object *p_object) { - if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { + if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { _dispose_object(p_object); } else { #ifndef NO_THREADS @@ -722,7 +722,7 @@ void _GodotSharp::queue_dispose(Object *p_object) { void _GodotSharp::queue_dispose(NodePath *p_node_path) { - if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { + if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { memdelete(p_node_path); } else { #ifndef NO_THREADS @@ -739,7 +739,7 @@ void _GodotSharp::queue_dispose(NodePath *p_node_path) { void _GodotSharp::queue_dispose(RID *p_rid) { - if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { + if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { memdelete(p_rid); } else { #ifndef NO_THREADS diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 77a1ef3cb0..01392447f3 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -600,7 +600,7 @@ MonoArray *Array_to_mono_array(const Array &p_array) { for (int i = 0; i < p_array.size(); i++) { MonoObject *boxed = variant_to_mono_object(p_array[i]); - mono_array_set(ret, MonoObject *, i, boxed); + mono_array_setref(ret, i, boxed); } return ret; diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index e3af57e78a..ebb5d28e4d 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -149,6 +149,10 @@ void attach_current_thread(); void detach_current_thread(); MonoThread *get_current_thread(); +_FORCE_INLINE_ bool is_main_thread() { + return mono_domain_get() != NULL && mono_thread_get_main() == mono_thread_current(); +} + GDMonoClass *get_object_class(MonoObject *p_object); GDMonoClass *type_get_proxy_class(const StringName &p_type); GDMonoClass *get_class_native_base(GDMonoClass *p_class); |