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.cpp334
1 files changed, 222 insertions, 112 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 46c40b2690..d2a861dbe8 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -49,6 +49,8 @@
#include "mono_gd/gd_mono_class.h"
#include "mono_gd/gd_mono_marshal.h"
#include "signal_awaiter_utils.h"
+#include "utils/macros.h"
+#include "utils/thread_local.h"
#define CACHED_STRING_NAME(m_var) (CSharpLanguage::get_singleton()->get_string_names().m_var)
@@ -119,7 +121,7 @@ void CSharpLanguage::init() {
#ifdef TOOLS_ENABLED
EditorNode::add_init_callback(&gdsharp_editor_init_callback);
- GLOBAL_DEF("mono/export/include_scripts_content", true);
+ GLOBAL_DEF("mono/export/include_scripts_content", false);
#endif
}
@@ -296,30 +298,28 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin
String script_template = "using " BINDINGS_NAMESPACE ";\n"
"using System;\n"
"\n"
- "public class %CLASS_NAME% : %BASE_CLASS_NAME%\n"
+ "public class %CLASS% : %BASE%\n"
"{\n"
- " // Member variables here, example:\n"
+ " // Declare member variables here. Examples:\n"
" // private int a = 2;\n"
- " // private string b = \"textvar\";\n"
+ " // private string b = \"text\";\n"
"\n"
+ " // Called when the node enters the scene tree for the first time.\n"
" public override void _Ready()\n"
" {\n"
- " // Called every time the node is added to the scene.\n"
- " // Initialization here.\n"
" \n"
" }\n"
"\n"
- "// public override void _Process(float delta)\n"
- "// {\n"
- "// // Called every frame. Delta is time since last frame.\n"
- "// // Update game logic here.\n"
- "// \n"
- "// }\n"
+ "// // Called every frame. 'delta' is the elapsed time since the previous frame.\n"
+ "// public override void _Process(float delta)\n"
+ "// {\n"
+ "// \n"
+ "// }\n"
"}\n";
String base_class_name = get_base_class_name(p_base_class_name, p_class_name);
- script_template = script_template.replace("%BASE_CLASS_NAME%", base_class_name)
- .replace("%CLASS_NAME%", p_class_name);
+ script_template = script_template.replace("%BASE%", base_class_name)
+ .replace("%CLASS%", p_class_name);
Ref<CSharpScript> script;
script.instance();
@@ -476,7 +476,7 @@ String CSharpLanguage::_get_indentation() const {
Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info() {
#ifdef DEBUG_ENABLED
- // Printing an error here will result in endless recursion, so we must be careful
+ _TLS_RECURSION_GUARD_V_(Vector<StackInfo>());
if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_core_api_assembly() || !GDMonoUtils::mono_cache.corlib_cache_updated)
return Vector<StackInfo>();
@@ -500,15 +500,15 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info()
#ifdef DEBUG_ENABLED
Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObject *p_stack_trace) {
- // Printing an error here could result in endless recursion, so we must be careful
+ _TLS_RECURSION_GUARD_V_(Vector<StackInfo>());
- MonoObject *exc = NULL;
+ MonoException *exc = NULL;
GDMonoUtils::StackTrace_GetFrames st_get_frames = CACHED_METHOD_THUNK(System_Diagnostics_StackTrace, GetFrames);
- MonoArray *frames = st_get_frames(p_stack_trace, &exc);
+ MonoArray *frames = st_get_frames(p_stack_trace, (MonoObject **)&exc);
if (exc) {
- GDMonoUtils::print_unhandled_exception(exc, true /* fail silently to avoid endless recursion */);
+ GDMonoUtils::debug_print_unhandled_exception(exc);
return Vector<StackInfo>();
}
@@ -523,16 +523,16 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec
si.resize(frame_count);
for (int i = 0; i < frame_count; i++) {
- StackInfo &sif = si[i];
+ StackInfo &sif = si.write[i];
MonoObject *frame = mono_array_get(frames, MonoObject *, i);
MonoString *file_name;
int file_line_num;
MonoString *method_decl;
- get_sf_info(frame, &file_name, &file_line_num, &method_decl, &exc);
+ get_sf_info(frame, &file_name, &file_line_num, &method_decl, (MonoObject **)&exc);
if (exc) {
- GDMonoUtils::print_unhandled_exception(exc, true /* fail silently to avoid endless recursion */);
+ GDMonoUtils::debug_print_unhandled_exception(exc);
return Vector<StackInfo>();
}
@@ -561,12 +561,12 @@ void CSharpLanguage::frame() {
ERR_FAIL_NULL(thunk);
- MonoObject *ex;
- thunk(task_scheduler, &ex);
+ MonoException *exc = NULL;
+ thunk(task_scheduler, (MonoObject **)&exc);
- if (ex) {
- mono_print_unhandled_exception(ex);
- ERR_FAIL();
+ if (exc) {
+ GDMonoUtils::debug_unhandled_exception(exc);
+ _UNREACHABLE_();
}
}
}
@@ -638,33 +638,41 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft
#ifdef TOOLS_ENABLED
void CSharpLanguage::reload_assemblies_if_needed(bool p_soft_reload) {
- if (gdmono->is_runtime_initialized()) {
+ if (!gdmono->is_runtime_initialized())
+ return;
- GDMonoAssembly *proj_assembly = gdmono->get_project_assembly();
+ GDMonoAssembly *proj_assembly = gdmono->get_project_assembly();
- String name = ProjectSettings::get_singleton()->get("application/config/name");
- if (name.empty()) {
- name = "UnnamedProject";
- }
+ String name = ProjectSettings::get_singleton()->get("application/config/name");
+ if (name.empty()) {
+ name = "UnnamedProject";
+ }
- if (proj_assembly) {
- String proj_asm_path = proj_assembly->get_path();
+ name += ".dll";
- if (!FileAccess::exists(proj_assembly->get_path())) {
- // Maybe it wasn't loaded from the default path, so check this as well
- proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name);
- if (!FileAccess::exists(proj_asm_path))
- return; // No assembly to load
- }
+ if (proj_assembly) {
+ String proj_asm_path = proj_assembly->get_path();
- if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time())
- return; // Already up to date
- } else {
- if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name)))
+ if (!FileAccess::exists(proj_assembly->get_path())) {
+ // Maybe it wasn't loaded from the default path, so check this as well
+ proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name);
+ if (!FileAccess::exists(proj_asm_path))
return; // No assembly to load
}
+
+ if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time())
+ return; // Already up to date
+ } else {
+ if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name)))
+ return; // No assembly to load
}
+ if (!gdmono->get_core_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_CORE))
+ return; // The core API assembly to load is invalidated
+
+ if (!gdmono->get_editor_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR))
+ return; // The editor API assembly to load is invalidated
+
#ifndef NO_THREADS
lock->lock();
#endif
@@ -728,6 +736,9 @@ void CSharpLanguage::reload_assemblies_if_needed(bool p_soft_reload) {
obj->get_script_instance()->get_property_state(state);
map[obj->get_instance_id()] = state;
obj->set_script(RefPtr());
+ } else {
+ // no instance found. Let's remove it so we don't loop forever
+ E->get()->placeholders.erase(E->get()->placeholders.front()->get());
}
}
@@ -739,16 +750,31 @@ void CSharpLanguage::reload_assemblies_if_needed(bool p_soft_reload) {
}
}
- if (gdmono->reload_scripts_domain() != OK)
+ if (gdmono->reload_scripts_domain() != OK) {
+ // Failed to reload the scripts domain
+ // Make sure to add the scripts back to their owners before returning
+ for (Map<Ref<CSharpScript>, Map<ObjectID, List<Pair<StringName, Variant> > > >::Element *E = to_reload.front(); E; E = E->next()) {
+ Ref<CSharpScript> scr = E->key();
+ for (Map<ObjectID, List<Pair<StringName, Variant> > >::Element *F = E->get().front(); F; F = F->next()) {
+ Object *obj = ObjectDB::get_instance(F->key());
+ if (!obj)
+ continue;
+ obj->set_script(scr.get_ref_ptr());
+ // Save reload state for next time if not saved
+ if (!scr->pending_reload_state.has(obj->get_instance_id())) {
+ scr->pending_reload_state[obj->get_instance_id()] = F->get();
+ }
+ }
+ }
return;
+ }
for (Map<Ref<CSharpScript>, Map<ObjectID, List<Pair<StringName, Variant> > > >::Element *E = to_reload.front(); E; E = E->next()) {
Ref<CSharpScript> scr = E->key();
- scr->signals_invalidated = true;
scr->exports_invalidated = true;
+ scr->signals_invalidated = true;
scr->reload(p_soft_reload);
- scr->update_signals();
scr->update_exports();
//restore state if saved
@@ -771,6 +797,14 @@ void CSharpLanguage::reload_assemblies_if_needed(bool p_soft_reload) {
continue;
}
+ if (scr->valid && scr->is_tool() && obj->get_script_instance()->is_placeholder()) {
+ // Script instance was a placeholder, but now the script was built successfully and is a tool script.
+ // We have to replace the placeholder with an actual C# script instance.
+ scr->placeholders.erase(static_cast<PlaceHolderScriptInstance *>(obj->get_script_instance()));
+ ScriptInstance *script_instance = scr->instance_create(obj);
+ obj->set_script_instance(script_instance); // Not necessary as it's already done in instance_create, but just in case...
+ }
+
for (List<Pair<StringName, Variant> >::Element *G = F->get().front(); G; G = G->next()) {
obj->get_script_instance()->set(G->get().first, G->get().second);
}
@@ -979,6 +1013,69 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
#endif
}
+void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
+
+ Reference *ref_owner = Object::cast_to<Reference>(p_object);
+
+#ifdef DEBUG_ENABLED
+ CRASH_COND(!ref_owner);
+#endif
+
+ void *data = p_object->get_script_instance_binding(get_language_index());
+ if (!data)
+ return;
+ Ref<MonoGCHandle> &gchandle = ((Map<Object *, Ref<MonoGCHandle> >::Element *)data)->get();
+
+ if (ref_owner->reference_get_count() > 1 && gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ // 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.
+ uint32_t strong_gchandle = MonoGCHandle::make_strong_handle(target);
+ gchandle->release();
+ gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE);
+ }
+}
+
+bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
+
+ Reference *ref_owner = Object::cast_to<Reference>(p_object);
+
+#ifdef DEBUG_ENABLED
+ CRASH_COND(!ref_owner);
+#endif
+
+ int refcount = ref_owner->reference_get_count();
+
+ void *data = p_object->get_script_instance_binding(get_language_index());
+ if (!data)
+ return refcount == 0;
+ Ref<MonoGCHandle> &gchandle = ((Map<Object *, Ref<MonoGCHandle> >::Element *)data)->get();
+
+ if (refcount == 1 && !gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ // 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();
+ 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::make_weak_handle(target);
+ gchandle->release();
+ gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE);
+
+ return false;
+ }
+
+ return refcount == 0;
+}
+
CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref<MonoGCHandle> &p_gchandle) {
CSharpInstance *instance = memnew(CSharpInstance);
@@ -1078,11 +1175,11 @@ bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const {
GDMonoProperty *property = top->get_property(p_name);
if (property) {
- MonoObject *exc = NULL;
+ MonoException *exc = NULL;
MonoObject *value = property->get_value(mono_object, &exc);
if (exc) {
r_ret = Variant();
- GDMonoUtils::print_unhandled_exception(exc);
+ GDMonoUtils::set_pending_exception(exc);
} else {
r_ret = GDMonoMarshal::mono_object_to_variant(value);
}
@@ -1269,11 +1366,13 @@ void CSharpInstance::mono_object_disposed() {
void CSharpInstance::refcount_incremented() {
+#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
+#endif
Reference *ref_owner = Object::cast_to<Reference>(owner);
- if (ref_owner->reference_get_count() > 1) { // 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
// 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.
@@ -1281,26 +1380,28 @@ void CSharpInstance::refcount_incremented() {
// Release the current weak handle and replace it with a strong handle.
uint32_t strong_gchandle = MonoGCHandle::make_strong_handle(gchandle->get_target());
gchandle->release();
- gchandle->set_handle(strong_gchandle);
+ gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE);
}
}
bool CSharpInstance::refcount_decremented() {
+#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
+#endif
Reference *ref_owner = Object::cast_to<Reference>(owner);
int refcount = ref_owner->reference_get_count();
- if (refcount == 1) { // 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
// 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::make_weak_handle(gchandle->get_target());
gchandle->release();
- gchandle->set_handle(weak_gchandle);
+ gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE);
return false;
}
@@ -1467,8 +1568,12 @@ void CSharpScript::_update_exports_values(Map<StringName, Variant> &values, List
bool CSharpScript::_update_exports() {
#ifdef TOOLS_ENABLED
- if (!valid)
+ if (!valid) {
+ for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
+ E->get()->set_build_failed(true);
+ }
return false;
+ }
bool changed = false;
@@ -1490,12 +1595,12 @@ bool CSharpScript::_update_exports() {
CACHED_FIELD(GodotObject, ptr)->set_value_raw(tmp_object, tmp_object); // FIXME WTF is this workaround
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
- MonoObject *ex = NULL;
- ctor->invoke(tmp_object, NULL, &ex);
+ MonoException *exc = NULL;
+ ctor->invoke(tmp_object, NULL, &exc);
- if (ex) {
+ if (exc) {
ERR_PRINT("Exception thrown from constructor of temporary MonoObject:");
- mono_print_unhandled_exception(ex);
+ GDMonoUtils::debug_print_unhandled_exception(exc);
tmp_object = NULL;
ERR_FAIL_V(false);
}
@@ -1544,11 +1649,11 @@ bool CSharpScript::_update_exports() {
exported_members_cache.push_front(prop_info);
if (tmp_object) {
- MonoObject *exc = NULL;
+ MonoException *exc = NULL;
MonoObject *ret = property->get_value(tmp_object, &exc);
if (exc) {
exported_members_defval_cache[name] = Variant();
- GDMonoUtils::print_unhandled_exception(exc);
+ GDMonoUtils::debug_print_unhandled_exception(exc);
} else {
exported_members_defval_cache[name] = GDMonoMarshal::mono_object_to_variant(ret);
}
@@ -1570,6 +1675,7 @@ bool CSharpScript::_update_exports() {
_update_exports_values(values, propnames);
for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
+ E->get()->set_build_failed(false);
E->get()->update(propnames, values);
}
}
@@ -1579,42 +1685,38 @@ bool CSharpScript::_update_exports() {
return false;
}
-bool CSharpScript::_update_signals() {
- if (!valid)
- return false;
-
- bool changed = false;
-
- if (signals_invalidated) {
- signals_invalidated = false;
+void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class) {
- GDMonoClass *top = script_class;
+ // no need to load the script's signals more than once
+ if (!signals_invalidated) {
+ return;
+ }
- _signals.clear();
- changed = true; // TODO Do a real check for change
+ // make sure this classes signals are empty when loading for the first time
+ _signals.clear();
- while (top && top != native) {
- const Vector<GDMonoClass *> &delegates = top->get_all_delegates();
- for (int i = delegates.size() - 1; i >= 0; --i) {
- Vector<Argument> parameters;
+ GDMonoClass *top = p_class;
+ while (top && top != p_native_class) {
+ const Vector<GDMonoClass *> &delegates = top->get_all_delegates();
+ for (int i = delegates.size() - 1; i >= 0; --i) {
+ Vector<Argument> parameters;
- GDMonoClass *delegate = delegates[i];
+ GDMonoClass *delegate = delegates[i];
- if (_get_signal(top, delegate, parameters)) {
- _signals[delegate->get_name()] = parameters;
- }
+ if (_get_signal(top, delegate, parameters)) {
+ _signals[delegate->get_name()] = parameters;
}
-
- top = top->get_parent_class();
}
+
+ top = top->get_parent_class();
}
- return changed;
+ signals_invalidated = false;
}
bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Vector<Argument> &params) {
if (p_delegate->has_attribute(CACHED_CLASS(SignalAttribute))) {
- MonoType *raw_type = GDMonoClass::get_raw_type(p_delegate);
+ MonoType *raw_type = p_delegate->get_mono_type();
if (mono_type_get_type(raw_type) == MONO_TYPE_CLASS) {
// Arguments are accessibles as arguments of .Invoke method
@@ -1684,7 +1786,7 @@ bool CSharpScript::_get_member_export(GDMonoClass *p_class, GDMonoClassMember *p
MonoObject *attr = p_member->get_attribute(CACHED_CLASS(ExportAttribute));
- PropertyHint hint;
+ PropertyHint hint = PROPERTY_HINT_NONE;
String hint_string;
if (variant_type == Variant::NIL) {
@@ -1848,6 +1950,8 @@ Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class) {
top = top->get_parent_class();
}
+ script->load_script_signals(script->script_class, script->native);
+
return script;
}
@@ -1868,7 +1972,11 @@ bool CSharpScript::can_instance() const {
}
#endif
- return valid || (!tool && !ScriptServer::is_scripting_enabled());
+#ifdef TOOLS_ENABLED
+ return valid && (tool || ScriptServer::is_scripting_enabled());
+#else
+ return valid;
+#endif
}
StringName CSharpScript::get_instance_base_type() const {
@@ -1918,7 +2026,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
// Construct
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), p_argcount);
- ctor->invoke(mono_object, p_args, NULL);
+ ctor->invoke(mono_object, p_args);
// Tie managed to unmanaged
instance->gchandle = MonoGCHandle::create_strong(mono_object);
@@ -1966,33 +2074,23 @@ Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Variant::Call
ScriptInstance *CSharpScript::instance_create(Object *p_this) {
- ERR_FAIL_COND_V(!valid, NULL);
-
- if (!tool && !ScriptServer::is_scripting_enabled()) {
-#ifdef TOOLS_ENABLED
- PlaceHolderScriptInstance *si = memnew(PlaceHolderScriptInstance(CSharpLanguage::get_singleton(), Ref<Script>(this), p_this));
- placeholders.insert(si);
- _update_exports();
- _update_signals();
- return si;
-#else
- return NULL;
+#ifdef DEBUG_ENABLED
+ CRASH_COND(!valid);
#endif
- }
if (!script_class) {
if (GDMono::get_singleton()->get_project_assembly() == NULL) {
// The project assembly is not loaded
ERR_EXPLAIN("Cannot instance script because the project assembly is not loaded. Script: " + get_path());
ERR_FAIL_V(NULL);
+ } else {
+ // The project assembly is loaded, but the class could not found
+ ERR_EXPLAIN("Cannot instance script because the class '" + name + "' could not be found. Script: " + get_path());
+ ERR_FAIL_V(NULL);
}
-
- // The project assembly is loaded, but the class could not found
- ERR_EXPLAIN("Cannot instance script because the class '" + name + "' could not be found. Script: " + get_path());
- ERR_FAIL_V(NULL);
}
- update_signals();
+ ERR_FAIL_COND_V(!valid, NULL);
if (native) {
String native_name = native->get_name();
@@ -2009,6 +2107,18 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) {
return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this), unchecked_error);
}
+PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_this) {
+
+#ifdef TOOLS_ENABLED
+ PlaceHolderScriptInstance *si = memnew(PlaceHolderScriptInstance(CSharpLanguage::get_singleton(), Ref<Script>(this), p_this));
+ placeholders.insert(si);
+ _update_exports();
+ return si;
+#else
+ return NULL;
+#endif
+}
+
bool CSharpScript::instance_has(const Object *p_this) const {
#ifndef NO_THREADS
@@ -2046,6 +2156,9 @@ void CSharpScript::set_source_code(const String &p_code) {
bool CSharpScript::has_method(const StringName &p_method) const {
+ if (!script_class)
+ return false;
+
return script_class->has_fetched_method_unknown_params(p_method);
}
@@ -2072,9 +2185,7 @@ Error CSharpScript::reload(bool p_keep_state) {
if (script_class) {
#ifdef DEBUG_ENABLED
- OS::get_singleton()->print(String("Found class " + script_class->get_namespace() + "." +
- script_class->get_name() + " for script " + get_path() + "\n")
- .utf8());
+ print_verbose("Found class " + script_class->get_namespace() + "." + script_class->get_name() + " for script " + get_path());
#endif
tool = script_class->has_attribute(CACHED_CLASS(ToolAttribute));
@@ -2114,6 +2225,8 @@ Error CSharpScript::reload(bool p_keep_state) {
top->fetch_methods_with_godot_api_checks(native);
top = top->get_parent_class();
}
+
+ load_script_signals(script_class, native);
}
return OK;
@@ -2173,10 +2286,6 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
}
}
-void CSharpScript::update_signals() {
- _update_signals();
-}
-
Ref<Script> CSharpScript::get_base_script() const {
// TODO search in metadata file once we have it, not important any way?
@@ -2241,9 +2350,10 @@ CSharpScript::CSharpScript() :
#ifdef TOOLS_ENABLED
source_changed_cache = false;
exports_invalidated = true;
- signals_invalidated = true;
#endif
+ signals_invalidated = true;
+
_resource_path_changed();
#ifdef DEBUG_ENABLED