|
@@ -975,7 +975,6 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
|
|
script->signals_invalidated = true;
|
|
|
|
|
|
script->reload(p_soft_reload);
|
|
|
- script->update_exports();
|
|
|
|
|
|
if (!script->valid) {
|
|
|
script->pending_reload_instances.clear();
|
|
@@ -2955,13 +2954,24 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
|
|
|
|
|
|
CRASH_COND(p_script->native == nullptr);
|
|
|
|
|
|
+ p_script->valid = true;
|
|
|
+
|
|
|
+ update_script_class_info(p_script);
|
|
|
+
|
|
|
+#ifdef TOOLS_ENABLED
|
|
|
+ p_script->_update_member_info_no_exports();
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+// Extract information about the script using the mono class.
|
|
|
+void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) {
|
|
|
GDMonoClass *base = p_script->script_class->get_parent_class();
|
|
|
|
|
|
+ // `base` should only be set if the script is a user defined type.
|
|
|
if (base != p_script->native) {
|
|
|
p_script->base = base;
|
|
|
}
|
|
|
|
|
|
- p_script->valid = true;
|
|
|
p_script->tool = p_script->script_class->has_attribute(CACHED_CLASS(ToolAttribute));
|
|
|
|
|
|
if (!p_script->tool) {
|
|
@@ -2996,17 +3006,74 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
|
|
|
|
|
|
p_script->script_class->fetch_methods_with_godot_api_checks(p_script->native);
|
|
|
|
|
|
- // Need to fetch method from base classes as well
|
|
|
+ p_script->rpc_functions.clear();
|
|
|
+ p_script->rpc_variables.clear();
|
|
|
+
|
|
|
GDMonoClass *top = p_script->script_class;
|
|
|
while (top && top != p_script->native) {
|
|
|
+ // Fetch methods from base classes as well
|
|
|
top->fetch_methods_with_godot_api_checks(p_script->native);
|
|
|
+
|
|
|
+ // Update RPC info
|
|
|
+ {
|
|
|
+ Vector<GDMonoMethod *> methods = top->get_all_methods();
|
|
|
+ for (int i = 0; i < methods.size(); i++) {
|
|
|
+ if (!methods[i]->is_static()) {
|
|
|
+ MultiplayerAPI::RPCMode mode = p_script->_member_get_rpc_mode(methods[i]);
|
|
|
+ if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
|
|
|
+ ScriptNetData nd;
|
|
|
+ nd.name = methods[i]->get_name();
|
|
|
+ nd.mode = mode;
|
|
|
+ if (-1 == p_script->rpc_functions.find(nd)) {
|
|
|
+ p_script->rpc_functions.push_back(nd);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ Vector<GDMonoField *> fields = top->get_all_fields();
|
|
|
+ for (int i = 0; i < fields.size(); i++) {
|
|
|
+ if (!fields[i]->is_static()) {
|
|
|
+ MultiplayerAPI::RPCMode mode = p_script->_member_get_rpc_mode(fields[i]);
|
|
|
+ if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
|
|
|
+ ScriptNetData nd;
|
|
|
+ nd.name = fields[i]->get_name();
|
|
|
+ nd.mode = mode;
|
|
|
+ if (-1 == p_script->rpc_variables.find(nd)) {
|
|
|
+ p_script->rpc_variables.push_back(nd);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ Vector<GDMonoProperty *> properties = top->get_all_properties();
|
|
|
+ for (int i = 0; i < properties.size(); i++) {
|
|
|
+ if (!properties[i]->is_static()) {
|
|
|
+ MultiplayerAPI::RPCMode mode = p_script->_member_get_rpc_mode(properties[i]);
|
|
|
+ if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
|
|
|
+ ScriptNetData nd;
|
|
|
+ nd.name = properties[i]->get_name();
|
|
|
+ nd.mode = mode;
|
|
|
+ if (-1 == p_script->rpc_variables.find(nd)) {
|
|
|
+ p_script->rpc_variables.push_back(nd);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
top = top->get_parent_class();
|
|
|
}
|
|
|
|
|
|
+ // Sort so we are 100% that they are always the same.
|
|
|
+ p_script->rpc_functions.sort_custom<SortNetData>();
|
|
|
+ p_script->rpc_variables.sort_custom<SortNetData>();
|
|
|
+
|
|
|
p_script->load_script_signals(p_script->script_class, p_script->native);
|
|
|
-#ifdef TOOLS_ENABLED
|
|
|
- p_script->_update_member_info_no_exports();
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
bool CSharpScript::can_instance() const {
|
|
@@ -3305,124 +3372,15 @@ Error CSharpScript::reload(bool p_keep_state) {
|
|
|
print_verbose("Found class " + script_class->get_full_name() + " for script " + get_path());
|
|
|
#endif
|
|
|
|
|
|
- tool = script_class->has_attribute(CACHED_CLASS(ToolAttribute));
|
|
|
-
|
|
|
- if (!tool) {
|
|
|
- GDMonoClass *nesting_class = script_class->get_nesting_class();
|
|
|
- tool = nesting_class && nesting_class->has_attribute(CACHED_CLASS(ToolAttribute));
|
|
|
- }
|
|
|
-
|
|
|
-#if TOOLS_ENABLED
|
|
|
- if (!tool) {
|
|
|
- tool = script_class->get_assembly() == GDMono::get_singleton()->get_tools_assembly();
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
native = GDMonoUtils::get_class_native_base(script_class);
|
|
|
|
|
|
CRASH_COND(native == nullptr);
|
|
|
|
|
|
- GDMonoClass *base_class = script_class->get_parent_class();
|
|
|
-
|
|
|
- if (base_class != native) {
|
|
|
- base = base_class;
|
|
|
- }
|
|
|
-
|
|
|
-#ifdef DEBUG_ENABLED
|
|
|
- // For debug builds, we must fetch from all native base methods as well.
|
|
|
- // Native base methods must be fetched before the current class.
|
|
|
- // Not needed if the script class itself is a native class.
|
|
|
+ update_script_class_info(this);
|
|
|
|
|
|
- if (script_class != native) {
|
|
|
- GDMonoClass *native_top = native;
|
|
|
- while (native_top) {
|
|
|
- native_top->fetch_methods_with_godot_api_checks(native);
|
|
|
-
|
|
|
- if (native_top == CACHED_CLASS(GodotObject)) {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- native_top = native_top->get_parent_class();
|
|
|
- }
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
- script_class->fetch_methods_with_godot_api_checks(native);
|
|
|
-
|
|
|
- // Need to fetch method from base classes as well
|
|
|
- GDMonoClass *top = script_class;
|
|
|
- while (top && top != native) {
|
|
|
- top->fetch_methods_with_godot_api_checks(native);
|
|
|
- top = top->get_parent_class();
|
|
|
- }
|
|
|
-
|
|
|
- load_script_signals(script_class, native);
|
|
|
_update_exports();
|
|
|
}
|
|
|
|
|
|
- rpc_functions.clear();
|
|
|
- rpc_variables.clear();
|
|
|
-
|
|
|
- GDMonoClass *top = script_class;
|
|
|
- while (top && top != native) {
|
|
|
- {
|
|
|
- Vector<GDMonoMethod *> methods = top->get_all_methods();
|
|
|
- for (int i = 0; i < methods.size(); i++) {
|
|
|
- if (!methods[i]->is_static()) {
|
|
|
- MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(methods[i]);
|
|
|
- if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
|
|
|
- ScriptNetData nd;
|
|
|
- nd.name = methods[i]->get_name();
|
|
|
- nd.mode = mode;
|
|
|
- if (-1 == rpc_functions.find(nd)) {
|
|
|
- rpc_functions.push_back(nd);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- {
|
|
|
- Vector<GDMonoField *> fields = top->get_all_fields();
|
|
|
- for (int i = 0; i < fields.size(); i++) {
|
|
|
- if (!fields[i]->is_static()) {
|
|
|
- MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(fields[i]);
|
|
|
- if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
|
|
|
- ScriptNetData nd;
|
|
|
- nd.name = fields[i]->get_name();
|
|
|
- nd.mode = mode;
|
|
|
- if (-1 == rpc_variables.find(nd)) {
|
|
|
- rpc_variables.push_back(nd);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- {
|
|
|
- Vector<GDMonoProperty *> properties = top->get_all_properties();
|
|
|
- for (int i = 0; i < properties.size(); i++) {
|
|
|
- if (!properties[i]->is_static()) {
|
|
|
- MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(properties[i]);
|
|
|
- if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
|
|
|
- ScriptNetData nd;
|
|
|
- nd.name = properties[i]->get_name();
|
|
|
- nd.mode = mode;
|
|
|
- if (-1 == rpc_variables.find(nd)) {
|
|
|
- rpc_variables.push_back(nd);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- top = top->get_parent_class();
|
|
|
- }
|
|
|
-
|
|
|
- // Sort so we are 100% that they are always the same.
|
|
|
- rpc_functions.sort_custom<SortNetData>();
|
|
|
- rpc_variables.sort_custom<SortNetData>();
|
|
|
-
|
|
|
return OK;
|
|
|
}
|
|
|
|