diff options
Diffstat (limited to 'modules/gdnative/pluginscript/pluginscript_script.cpp')
-rw-r--r-- | modules/gdnative/pluginscript/pluginscript_script.cpp | 96 |
1 files changed, 40 insertions, 56 deletions
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index b4525ff8aa..c3a623e9a1 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -84,35 +84,20 @@ StringName PluginScript::get_instance_base_type() const { } void PluginScript::update_exports() { -// TODO #ifdef TOOLS_ENABLED -#if 0 ASSERT_SCRIPT_VALID(); - if (/*changed &&*/ placeholders.size()) { //hm :( + if (placeholders.size()) { //update placeholders if any Map<StringName, Variant> propdefvalues; List<PropertyInfo> propinfos; - const String *props = (const String *)pybind_get_prop_list(_py_exposed_class); - for (int i = 0; props[i] != ""; ++i) { - const String propname = props[i]; - pybind_get_prop_default_value(_py_exposed_class, propname.c_str(), (godot_variant *)&propdefvalues[propname]); - pybind_prop_info raw_info; - pybind_get_prop_info(_py_exposed_class, propname.c_str(), &raw_info); - PropertyInfo info; - info.type = (Variant::Type)raw_info.type; - info.name = propname; - info.hint = (PropertyHint)raw_info.hint; - info.hint_string = *(String *)&raw_info.hint_string; - info.usage = raw_info.usage; - propinfos.push_back(info); - } + + get_script_property_list(&propinfos); for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) { - E->get()->update(propinfos, propdefvalues); + E->get()->update(propinfos, _properties_default_values); } } #endif -#endif } // TODO: rename p_this "p_owner" ? @@ -131,13 +116,10 @@ ScriptInstance *PluginScript::instance_create(Object *p_this) { #endif } - PluginScript *top = this; - // TODO: can be optimized by storing a PluginScript::_base_parent direct pointer - while (top->_ref_base_parent.is_valid()) - top = top->_ref_base_parent.ptr(); - if (top->_native_parent) { - if (!ClassDB::is_parent_class(p_this->get_class_name(), top->_native_parent)) { - String msg = "Script inherits from native type '" + String(top->_native_parent) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'"; + StringName base_type = get_instance_base_type(); + if (base_type) { + if (!ClassDB::is_parent_class(p_this->get_class_name(), base_type)) { + String msg = "Script inherits from native type '" + String(base_type) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'"; // TODO: implement PluginscriptLanguage::debug_break_parse // if (ScriptDebugger::get_singleton()) { // _language->debug_break_parse(get_path(), 0, msg); @@ -210,29 +192,31 @@ Error PluginScript::reload(bool p_keep_state) { // TODO: GDscript uses `ScriptDebugger` here to jump into the parsing error return err; } + + // Script's parent is passed as base_name which can make reference to a + // ClassDB name (i.e. `Node2D`) or a resource path (i.e. `res://foo/bar.gd`) + StringName *base_name = (StringName *)&manifest.base; + if (*base_name) { + + if (ClassDB::class_exists(*base_name)) { + _native_parent = *base_name; + } else { + Ref<Script> res = ResourceLoader::load(*base_name); + if (res.is_valid()) { + _ref_base_parent = res; + } else { + String name = *(StringName *)&manifest.name; + ERR_EXPLAIN(_path + ": Script '" + name + "' has an invalid parent '" + *base_name + "'."); + ERR_FAIL_V(ERR_PARSE_ERROR); + } + } + } + _valid = true; // Use the manifest to configure this script object _data = manifest.data; _name = *(StringName *)&manifest.name; _tool = manifest.is_tool; - // Base name is either another PluginScript or a regular class accessible - // through ClassDB - StringName *base_name = (StringName *)&manifest.base; - for (SelfList<PluginScript> *e = _language->_script_list.first(); e != NULL; e = e->next()) { - if (e->self()->_name == *base_name) { - // Found you, base is a PluginScript ! - _ref_base_parent = Ref<PluginScript>(e->self()); - break; - } - } - if (!_ref_base_parent.is_valid()) { - // Base is a native ClassDB - if (!ClassDB::class_exists(*base_name)) { - ERR_EXPLAIN("Unknown script '" + String(_name) + "' parent '" + String(*base_name) + "'."); - ERR_FAIL_V(ERR_PARSE_ERROR); - } - _native_parent = *base_name; - } Dictionary *members = (Dictionary *)&manifest.member_lines; for (const Variant *key = members->next(); key != NULL; key = members->next(key)) { @@ -246,9 +230,9 @@ Error PluginScript::reload(bool p_keep_state) { // rpc_mode is passed as an optional field and is not part of MethodInfo Variant var = v["rpc_mode"]; if (var == Variant()) { - _methods_rpc_mode[mi.name] = ScriptInstance::RPC_MODE_DISABLED; + _methods_rpc_mode[mi.name] = MultiplayerAPI::RPC_MODE_DISABLED; } else { - _methods_rpc_mode[mi.name] = ScriptInstance::RPCMode(int(var)); + _methods_rpc_mode[mi.name] = MultiplayerAPI::RPCMode(int(var)); } } Array *signals = (Array *)&manifest.signals; @@ -266,9 +250,9 @@ Error PluginScript::reload(bool p_keep_state) { // rset_mode is passed as an optional field and is not part of PropertyInfo Variant var = v["rset_mode"]; if (var == Variant()) { - _methods_rpc_mode[pi.name] = ScriptInstance::RPC_MODE_DISABLED; + _methods_rpc_mode[pi.name] = MultiplayerAPI::RPC_MODE_DISABLED; } else { - _methods_rpc_mode[pi.name] = ScriptInstance::RPCMode(int(var)); + _methods_rpc_mode[pi.name] = MultiplayerAPI::RPCMode(int(var)); } } // Manifest's attributes must be explicitly freed @@ -403,23 +387,23 @@ int PluginScript::get_member_line(const StringName &p_member) const { return -1; } -ScriptInstance::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const { - ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED); - const Map<StringName, ScriptInstance::RPCMode>::Element *e = _methods_rpc_mode.find(p_method); +MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const { + ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); + const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _methods_rpc_mode.find(p_method); if (e != NULL) { return e->get(); } else { - return ScriptInstance::RPC_MODE_DISABLED; + return MultiplayerAPI::RPC_MODE_DISABLED; } } -ScriptInstance::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const { - ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED); - const Map<StringName, ScriptInstance::RPCMode>::Element *e = _variables_rset_mode.find(p_variable); +MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const { + ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); + const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _variables_rset_mode.find(p_variable); if (e != NULL) { return e->get(); } else { - return ScriptInstance::RPC_MODE_DISABLED; + return MultiplayerAPI::RPC_MODE_DISABLED; } } |