diff options
Diffstat (limited to 'modules/gdnative/pluginscript')
6 files changed, 170 insertions, 56 deletions
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp index c64a00a4d9..22e8372130 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.cpp +++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp @@ -39,13 +39,11 @@ #include "pluginscript_script.h" bool PluginScriptInstance::set(const StringName &p_name, const Variant &p_value) { - String name = String(p_name); - return _desc->set_prop(_data, (const godot_string *)&name, (const godot_variant *)&p_value); + return _desc->set_prop(_data, (const godot_string_name *)&p_name, (const godot_variant *)&p_value); } bool PluginScriptInstance::get(const StringName &p_name, Variant &r_ret) const { - String name = String(p_name); - return _desc->get_prop(_data, (const godot_string *)&name, (godot_variant *)&r_ret); + return _desc->get_prop(_data, (const godot_string_name *)&p_name, (godot_variant *)&r_ret); } Ref<Script> PluginScriptInstance::get_script() const { @@ -81,7 +79,7 @@ bool PluginScriptInstance::has_method(const StringName &p_method) const { return _script->has_method(p_method); } -Variant PluginScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant PluginScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { // TODO: optimize when calling a Godot method from Godot to avoid param conversion ? godot_variant ret = _desc->call_method( _data, (godot_string_name *)&p_method, (const godot_variant **)p_args, @@ -95,10 +93,42 @@ void PluginScriptInstance::notification(int p_notification) { _desc->notification(_data, p_notification); } +Vector<ScriptNetData> PluginScriptInstance::get_rpc_methods() const { + return _script->get_rpc_methods(); +} + +uint16_t PluginScriptInstance::get_rpc_method_id(const StringName &p_variable) const { + return _script->get_rpc_method_id(p_variable); +} + +StringName PluginScriptInstance::get_rpc_method(uint16_t p_id) const { + return _script->get_rpc_method(p_id); +} + +MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode_by_id(uint16_t p_id) const { + return _script->get_rpc_mode_by_id(p_id); +} + MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const { return _script->get_rpc_mode(p_method); } +Vector<ScriptNetData> PluginScriptInstance::get_rset_properties() const { + return _script->get_rset_properties(); +} + +uint16_t PluginScriptInstance::get_rset_property_id(const StringName &p_variable) const { + return _script->get_rset_property_id(p_variable); +} + +StringName PluginScriptInstance::get_rset_property(uint16_t p_id) const { + return _script->get_rset_property(p_id); +} + +MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode_by_id(uint16_t p_id) const { + return _script->get_rset_mode_by_id(p_id); +} + MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const { return _script->get_rset_mode(p_variable); } diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index dc1229a44d..c91ad643a7 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -60,7 +60,7 @@ public: virtual void get_method_list(List<MethodInfo> *p_list) const; virtual bool has_method(const StringName &p_method) const; - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); + virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); // Rely on default implementations provided by ScriptInstance for the moment. // Note that multilevel call could be removed in 3.0 release, so stay tuned @@ -76,7 +76,16 @@ public: void set_path(const String &p_path); + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(uint16_t p_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const; virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_variable) const; + virtual StringName get_rset_property(uint16_t p_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const; virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; virtual void refcount_incremented(); diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index 41f0e34243..4e39f4b0a8 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -109,7 +109,7 @@ Ref<Script> PluginScriptLanguage::get_template(const String &p_class_name, const } bool PluginScriptLanguage::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, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const { - PoolStringArray functions; + PackedStringArray functions; if (_desc.validate) { bool ret = _desc.validate( _data, @@ -118,7 +118,7 @@ bool PluginScriptLanguage::validate(const String &p_script, int &r_line_error, i &r_col_error, (godot_string *)&r_test_error, (godot_string *)&p_path, - (godot_pool_string_array *)&functions); + (godot_packed_string_array *)&functions); for (int i = 0; i < functions.size(); i++) { r_functions->push_back(functions[i]); } @@ -149,9 +149,9 @@ int PluginScriptLanguage::find_function(const String &p_function, const String & return -1; } -String PluginScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const { +String PluginScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const { if (_desc.make_function) { - godot_string tmp = _desc.make_function(_data, (godot_string *)&p_class, (godot_string *)&p_name, (godot_pool_string_array *)&p_args); + godot_string tmp = _desc.make_function(_data, (godot_string *)&p_class, (godot_string *)&p_name, (godot_packed_string_array *)&p_args); String ret = *(String *)&tmp; godot_string_destroy(&tmp); return ret; @@ -187,8 +187,7 @@ void PluginScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int } void PluginScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) { - const String variable = String(p_variable); - _desc.add_global_constant(_data, (godot_string *)&variable, (godot_variant *)&p_value); + _desc.add_global_constant(_data, (godot_string_name *)&p_variable, (godot_variant *)&p_value); } /* LOADER FUNCTIONS */ @@ -337,9 +336,9 @@ String PluginScriptLanguage::debug_get_stack_level_source(int p_level) const { void PluginScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { if (_desc.debug_get_stack_level_locals) { - PoolStringArray locals; + PackedStringArray locals; Array values; - _desc.debug_get_stack_level_locals(_data, p_level, (godot_pool_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth); + _desc.debug_get_stack_level_locals(_data, p_level, (godot_packed_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth); for (int i = 0; i < locals.size(); i++) { p_locals->push_back(locals[i]); } @@ -351,9 +350,9 @@ void PluginScriptLanguage::debug_get_stack_level_locals(int p_level, List<String void PluginScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { if (_desc.debug_get_stack_level_members) { - PoolStringArray members; + PackedStringArray members; Array values; - _desc.debug_get_stack_level_members(_data, p_level, (godot_pool_string_array *)&members, (godot_array *)&values, p_max_subitems, p_max_depth); + _desc.debug_get_stack_level_members(_data, p_level, (godot_packed_string_array *)&members, (godot_array *)&values, p_max_subitems, p_max_depth); for (int i = 0; i < members.size(); i++) { p_members->push_back(members[i]); } @@ -365,9 +364,9 @@ void PluginScriptLanguage::debug_get_stack_level_members(int p_level, List<Strin void PluginScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { if (_desc.debug_get_globals) { - PoolStringArray locals; + PackedStringArray locals; Array values; - _desc.debug_get_globals(_data, (godot_pool_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth); + _desc.debug_get_globals(_data, (godot_packed_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth); for (int i = 0; i < locals.size(); i++) { p_locals->push_back(locals[i]); } diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h index 145ab5599c..037d7a4948 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.h +++ b/modules/gdnative/pluginscript/pluginscript_language.h @@ -80,7 +80,7 @@ public: virtual bool supports_builtin_mode() const; virtual bool can_inherit_from_file() { return true; } virtual int find_function(const String &p_function, const String &p_code) const; - virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; + virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const; virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_force, String &r_call_hint); virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const; virtual void add_global_constant(const StringName &p_variable, const Variant &p_value); diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index cc5bdee0a1..fe1f63f6da 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -34,6 +34,8 @@ #include "pluginscript_instance.h" #include "pluginscript_script.h" +#include <stdint.h> + #ifdef DEBUG_ENABLED #define __ASSERT_SCRIPT_REASON "Cannot retrieve PluginScript class for this script, is your code correct?" #define ASSERT_SCRIPT_VALID() \ @@ -53,9 +55,9 @@ void PluginScript::_bind_methods() { ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &PluginScript::_new, MethodInfo("new")); } -PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Variant::CallError &r_error) { +PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Callable::CallError &r_error) { - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; // Create instance PluginScriptInstance *instance = memnew(PluginScriptInstance()); @@ -65,7 +67,7 @@ PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int _instances.insert(instance->get_owner()); _language->unlock(); } else { - r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL; + r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; memdelete(instance); ERR_FAIL_V(NULL); } @@ -81,12 +83,12 @@ PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int return instance; } -Variant PluginScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant PluginScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; if (!_valid) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); } @@ -100,7 +102,7 @@ Variant PluginScript::_new(const Variant **p_args, int p_argcount, Variant::Call } if (!owner) { - r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL; + r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; return Variant(); } @@ -199,7 +201,7 @@ ScriptInstance *PluginScript::instance_create(Object *p_this) { } } - Variant::CallError unchecked_error; + Callable::CallError unchecked_error; return _create_instance(NULL, 0, p_this, unchecked_error); } @@ -298,18 +300,31 @@ Error PluginScript::reload(bool p_keep_state) { _member_lines[*key] = (*members)[*key]; } Array *methods = (Array *)&manifest.methods; + _rpc_methods.clear(); + _rpc_variables.clear(); + if (_ref_base_parent.is_valid()) { + _rpc_methods = _ref_base_parent->get_rpc_methods(); + _rpc_variables = _ref_base_parent->get_rset_properties(); + } for (int i = 0; i < methods->size(); ++i) { Dictionary v = (*methods)[i]; MethodInfo mi = MethodInfo::from_dict(v); _methods_info[mi.name] = mi; // 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] = MultiplayerAPI::RPC_MODE_DISABLED; - } else { - _methods_rpc_mode[mi.name] = MultiplayerAPI::RPCMode(int(var)); + if (var != Variant()) { + ScriptNetData nd; + nd.name = mi.name; + nd.mode = MultiplayerAPI::RPCMode(int(var)); + if (_rpc_methods.find(nd) == -1) { + _rpc_methods.push_back(nd); + } } } + + // Sort so we are 100% that they are always the same. + _rpc_methods.sort_custom<SortNetData>(); + Array *signals = (Array *)&manifest.signals; for (int i = 0; i < signals->size(); ++i) { Variant v = (*signals)[i]; @@ -324,13 +339,19 @@ Error PluginScript::reload(bool p_keep_state) { _properties_default_values[pi.name] = v["default_value"]; // 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] = MultiplayerAPI::RPC_MODE_DISABLED; - } else { - _methods_rpc_mode[pi.name] = MultiplayerAPI::RPCMode(int(var)); + if (var != Variant()) { + ScriptNetData nd; + nd.name = pi.name; + nd.mode = MultiplayerAPI::RPCMode(int(var)); + if (_rpc_variables.find(nd) == -1) { + _rpc_variables.push_back(nd); + } } } + // Sort so we are 100% that they are always the same. + _rpc_variables.sort_custom<SortNetData>(); + #ifdef TOOLS_ENABLED /*for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) { @@ -407,22 +428,22 @@ ScriptLanguage *PluginScript::get_language() const { Error PluginScript::load_source_code(const String &p_path) { - PoolVector<uint8_t> sourcef; + Vector<uint8_t> sourcef; Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); ERR_FAIL_COND_V_MSG(err, err, "Cannot open file '" + p_path + "'."); int len = f->get_len(); sourcef.resize(len + 1); - PoolVector<uint8_t>::Write w = sourcef.write(); - int r = f->get_buffer(w.ptr(), len); + uint8_t *w = sourcef.ptrw(); + int r = f->get_buffer(w, len); f->close(); memdelete(f); ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN); w[len] = 0; String s; - if (s.parse_utf8((const char *)w.ptr())) { + if (s.parse_utf8((const char *)w)) { ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode."); } @@ -455,24 +476,70 @@ int PluginScript::get_member_line(const StringName &p_member) const { return -1; } -MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const { +Vector<ScriptNetData> PluginScript::get_rpc_methods() const { + return _rpc_methods; +} + +uint16_t PluginScript::get_rpc_method_id(const StringName &p_method) const { + ASSERT_SCRIPT_VALID_V(UINT16_MAX); + for (int i = 0; i < _rpc_methods.size(); i++) { + if (_rpc_methods[i].name == p_method) { + return i; + } + } + return UINT16_MAX; +} + +StringName PluginScript::get_rpc_method(const uint16_t p_rpc_method_id) const { + ASSERT_SCRIPT_VALID_V(StringName()); + if (p_rpc_method_id >= _rpc_methods.size()) + return StringName(); + return _rpc_methods[p_rpc_method_id].name; +} + +MultiplayerAPI::RPCMode PluginScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) 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 { + if (p_rpc_method_id >= _rpc_methods.size()) return MultiplayerAPI::RPC_MODE_DISABLED; + return _rpc_methods[p_rpc_method_id].mode; +} + +MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const { + ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); + return get_rpc_mode_by_id(get_rpc_method_id(p_method)); +} + +Vector<ScriptNetData> PluginScript::get_rset_properties() const { + return _rpc_variables; +} + +uint16_t PluginScript::get_rset_property_id(const StringName &p_property) const { + ASSERT_SCRIPT_VALID_V(UINT16_MAX); + for (int i = 0; i < _rpc_variables.size(); i++) { + if (_rpc_variables[i].name == p_property) { + return i; + } } + return UINT16_MAX; } -MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const { +StringName PluginScript::get_rset_property(const uint16_t p_rset_property_id) const { + ASSERT_SCRIPT_VALID_V(StringName()); + if (p_rset_property_id >= _rpc_variables.size()) + return StringName(); + return _rpc_variables[p_rset_property_id].name; +} + +MultiplayerAPI::RPCMode PluginScript::get_rset_mode_by_id(const uint16_t p_rset_property_id) 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 { + if (p_rset_property_id >= _rpc_variables.size()) return MultiplayerAPI::RPC_MODE_DISABLED; - } + return _rpc_variables[p_rset_property_id].mode; +} + +MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const { + ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); + return get_rset_mode_by_id(get_rset_property_id(p_variable)); } PluginScript::PluginScript() : diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index f67c88c794..5c93ae38f5 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -60,8 +60,8 @@ private: Map<StringName, PropertyInfo> _properties_info; Map<StringName, MethodInfo> _signals_info; Map<StringName, MethodInfo> _methods_info; - Map<StringName, MultiplayerAPI::RPCMode> _variables_rset_mode; - Map<StringName, MultiplayerAPI::RPCMode> _methods_rpc_mode; + Vector<ScriptNetData> _rpc_methods; + Vector<ScriptNetData> _rpc_variables; Set<Object *> _instances; //exported members @@ -72,8 +72,8 @@ private: protected: static void _bind_methods(); - PluginScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Variant::CallError &r_error); - Variant _new(const Variant **p_args, int p_argcount, Variant::CallError &r_error); + PluginScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Callable::CallError &r_error); + Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error); #ifdef TOOLS_ENABLED Set<PlaceHolderScriptInstance *> placeholders; @@ -118,8 +118,17 @@ public: virtual int get_member_line(const StringName &p_member) const; - MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; - MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_property) const; + virtual StringName get_rset_property(const uint16_t p_rset_property_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; PluginScript(); void init(PluginScriptLanguage *language); |