diff options
Diffstat (limited to 'modules/gdnative/pluginscript')
10 files changed, 261 insertions, 163 deletions
diff --git a/modules/gdnative/pluginscript/SCsub b/modules/gdnative/pluginscript/SCsub index 20eaa99592..0b2db3b504 100644 --- a/modules/gdnative/pluginscript/SCsub +++ b/modules/gdnative/pluginscript/SCsub @@ -1,6 +1,6 @@ #!/usr/bin/env python -Import('env') -Import('env_gdnative') +Import("env") +Import("env_gdnative") -env_gdnative.add_source_files(env.modules_sources, '*.cpp') +env_gdnative.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp index c64a00a4d9..7d17a7d5ab 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); } @@ -126,7 +156,7 @@ bool PluginScriptInstance::init(PluginScript *p_script, Object *p_owner) { _script = Ref<PluginScript>(p_script); _desc = &p_script->_desc->instance_desc; _data = _desc->init(p_script->_data, (godot_object *)p_owner); - ERR_FAIL_COND_V(_data == NULL, false); + ERR_FAIL_COND_V(_data == nullptr, false); p_owner->set_script_instance(this); return true; } diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index dc1229a44d..690d1a0432 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -55,18 +55,12 @@ public: virtual bool set(const StringName &p_name, const Variant &p_value); virtual bool get(const StringName &p_name, Variant &r_ret) const; virtual void get_property_list(List<PropertyInfo> *p_properties) const; - virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = NULL) const; + virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const; 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); - - // Rely on default implementations provided by ScriptInstance for the moment. - // Note that multilevel call could be removed in 3.0 release, so stay tuned - // (see https://godotengine.org/qa/9244/can-override-the-_ready-and-_process-functions-child-classes) - //virtual void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount); - //virtual void call_multilevel_reversed(const StringName& p_method,const Variant** p_args,int p_argcount); + virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); virtual void notification(int p_notification); @@ -76,7 +70,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..bccbe95033 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 */ @@ -211,7 +210,7 @@ void PluginScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) c } } -void PluginScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const { +void PluginScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const { // TODO: provide this statically in `godot_pluginscript_language_desc` ? if (_desc.get_public_constants) { Dictionary constants; @@ -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]); } @@ -400,39 +399,18 @@ void PluginScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool } void PluginScriptLanguage::lock() { -#ifndef NO_THREADS - if (_lock) { - _lock->lock(); - } -#endif + _lock.lock(); } void PluginScriptLanguage::unlock() { -#ifndef NO_THREADS - if (_lock) { - _lock->unlock(); - } -#endif + _lock.unlock(); } PluginScriptLanguage::PluginScriptLanguage(const godot_pluginscript_language_desc *desc) : _desc(*desc) { _resource_loader = Ref<ResourceFormatLoaderPluginScript>(memnew(ResourceFormatLoaderPluginScript(this))); _resource_saver = Ref<ResourceFormatSaverPluginScript>(memnew(ResourceFormatSaverPluginScript(this))); - -// TODO: totally remove _lock attribute if NO_THREADS is set -#ifdef NO_THREADS - _lock = NULL; -#else - _lock = Mutex::create(); -#endif } PluginScriptLanguage::~PluginScriptLanguage() { -#ifndef NO_THREADS - if (_lock) { - memdelete(_lock); - _lock = NULL; - } -#endif } diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h index 145ab5599c..dd6758713f 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.h +++ b/modules/gdnative/pluginscript/pluginscript_language.h @@ -53,7 +53,7 @@ class PluginScriptLanguage : public ScriptLanguage { const godot_pluginscript_language_desc _desc; godot_pluginscript_language_data *_data; - Mutex *_lock; + Mutex _lock; SelfList<PluginScript>::List _script_list; public: @@ -74,13 +74,13 @@ 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 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 = NULL, List<ScriptLanguage::Warning> *r_warnings = NULL, Set<int> *r_safe_lines = NULL) const; + 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 = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const; virtual Script *create_script() const; virtual bool has_named_classes() const; 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); @@ -112,7 +112,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_public_functions(List<MethodInfo> *p_functions) const; - virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const; + virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const; virtual void profiling_start(); virtual void profiling_stop(); diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp index fe1cc83c69..4feee4f4a5 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.cpp +++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp @@ -39,9 +39,10 @@ ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptL _language = language; } -RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error) { - if (r_error) +RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { + if (r_error) { *r_error = ERR_FILE_CANT_OPEN; + } PluginScript *script = memnew(PluginScript); script->init(_language); @@ -55,8 +56,9 @@ RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p script->reload(); - if (r_error) + if (r_error) { *r_error = OK; + } return scriptres; } @@ -71,8 +73,9 @@ bool ResourceFormatLoaderPluginScript::handles_type(const String &p_type) const String ResourceFormatLoaderPluginScript::get_resource_type(const String &p_path) const { String el = p_path.get_extension().to_lower(); - if (el == _language->get_extension()) + if (el == _language->get_extension()) { return _language->get_type(); + } return ""; } @@ -101,13 +104,11 @@ Error ResourceFormatSaverPluginScript::save(const String &p_path, const RES &p_r } void ResourceFormatSaverPluginScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { - if (Object::cast_to<PluginScript>(*p_resource)) { p_extensions->push_back(_language->get_extension()); } } bool ResourceFormatSaverPluginScript::recognize(const RES &p_resource) const { - - return Object::cast_to<PluginScript>(*p_resource) != NULL; + return Object::cast_to<PluginScript>(*p_resource) != nullptr; } diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h index ede31c027e..35fc79c2ca 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.h +++ b/modules/gdnative/pluginscript/pluginscript_loader.h @@ -39,19 +39,17 @@ class PluginScriptLanguage; class ResourceFormatLoaderPluginScript : public ResourceFormatLoader { - PluginScriptLanguage *_language; public: ResourceFormatLoaderPluginScript(PluginScriptLanguage *language); - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; }; class ResourceFormatSaverPluginScript : public ResourceFormatSaver { - PluginScriptLanguage *_language; public: diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index cc5bdee0a1..87c6288806 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,8 @@ 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) { - - r_error.error = Variant::CallError::CALL_OK; +PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; // Create instance PluginScriptInstance *instance = memnew(PluginScriptInstance()); @@ -65,9 +66,9 @@ 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); + ERR_FAIL_V(nullptr); } // Construct @@ -81,17 +82,16 @@ 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) { - - r_error.error = Variant::CallError::CALL_OK; +Variant PluginScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + 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(); } REF ref; - Object *owner = NULL; + Object *owner = nullptr; if (get_instance_base_type() == "") { owner = memnew(Reference); @@ -100,7 +100,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(); } @@ -138,6 +138,13 @@ bool PluginScript::can_instance() const { return can; } +bool PluginScript::inherits_script(const Ref<Script> &p_script) const { +#ifndef _MSC_VER +#warning inheritance needs to be implemented in PluginScript +#endif + return false; +} + Ref<Script> PluginScript::get_base_script() const { if (_ref_base_parent.is_valid()) { return Ref<PluginScript>(_ref_base_parent); @@ -147,10 +154,12 @@ Ref<Script> PluginScript::get_base_script() const { } StringName PluginScript::get_instance_base_type() const { - if (_native_parent) + if (_native_parent) { return _native_parent; - if (_ref_base_parent.is_valid()) + } + if (_ref_base_parent.is_valid()) { return _ref_base_parent->get_instance_base_type(); + } return StringName(); } @@ -158,7 +167,6 @@ void PluginScript::update_exports() { #ifdef TOOLS_ENABLED ASSERT_SCRIPT_VALID(); if (placeholders.size()) { - //update placeholders if any Map<StringName, Variant> propdefvalues; List<PropertyInfo> propinfos; @@ -173,7 +181,7 @@ void PluginScript::update_exports() { // TODO: rename p_this "p_owner" ? ScriptInstance *PluginScript::instance_create(Object *p_this) { - ASSERT_SCRIPT_VALID_V(NULL); + ASSERT_SCRIPT_VALID_V(nullptr); // TODO check script validity ? if (!_tool && !ScriptServer::is_scripting_enabled()) { #ifdef TOOLS_ENABLED @@ -183,7 +191,7 @@ ScriptInstance *PluginScript::instance_create(Object *p_this) { update_exports(); return si; #else - return NULL; + return nullptr; #endif } @@ -192,15 +200,15 @@ ScriptInstance *PluginScript::instance_create(Object *p_this) { 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()) { + // if (EngineDebugger::is_active()) { // _language->debug_break_parse(get_path(), 0, msg); // } - ERR_FAIL_V_MSG(NULL, msg); + ERR_FAIL_V_MSG(nullptr, msg); } } - Variant::CallError unchecked_error; - return _create_instance(NULL, 0, p_this, unchecked_error); + Callable::CallError unchecked_error; + return _create_instance(nullptr, 0, p_this, unchecked_error); } bool PluginScript::instance_has(const Object *p_this) const { @@ -220,8 +228,9 @@ String PluginScript::get_source_code() const { } void PluginScript::set_source_code(const String &p_code) { - if (_source == p_code) + if (_source == p_code) { return; + } _source = p_code; } @@ -235,11 +244,13 @@ Error PluginScript::reload(bool p_keep_state) { _valid = false; String basedir = _path; - if (basedir == "") + if (basedir == "") { basedir = get_path(); + } - if (basedir != "") + if (basedir != "") { basedir = basedir.get_base_dir(); + } if (_data) { _desc->finish(_data); @@ -272,7 +283,6 @@ Error PluginScript::reload(bool p_keep_state) { // 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 { @@ -294,22 +304,35 @@ Error PluginScript::reload(bool p_keep_state) { _tool = manifest.is_tool; Dictionary *members = (Dictionary *)&manifest.member_lines; - for (const Variant *key = members->next(); key != NULL; key = members->next(key)) { + for (const Variant *key = members->next(); key != nullptr; key = members->next(key)) { _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 +347,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()) { @@ -345,14 +374,14 @@ Error PluginScript::reload(bool p_keep_state) { void PluginScript::get_script_method_list(List<MethodInfo> *r_methods) const { ASSERT_SCRIPT_VALID(); - for (Map<StringName, MethodInfo>::Element *e = _methods_info.front(); e != NULL; e = e->next()) { + for (Map<StringName, MethodInfo>::Element *e = _methods_info.front(); e != nullptr; e = e->next()) { r_methods->push_back(e->get()); } } void PluginScript::get_script_property_list(List<PropertyInfo> *r_properties) const { ASSERT_SCRIPT_VALID(); - for (Map<StringName, PropertyInfo>::Element *e = _properties_info.front(); e != NULL; e = e->next()) { + for (Map<StringName, PropertyInfo>::Element *e = _properties_info.front(); e != nullptr; e = e->next()) { r_properties->push_back(e->get()); } } @@ -365,7 +394,7 @@ bool PluginScript::has_method(const StringName &p_method) const { MethodInfo PluginScript::get_method_info(const StringName &p_method) const { ASSERT_SCRIPT_VALID_V(MethodInfo()); const Map<StringName, MethodInfo>::Element *e = _methods_info.find(p_method); - if (e != NULL) { + if (e != nullptr) { return e->get(); } else { return MethodInfo(); @@ -380,7 +409,7 @@ bool PluginScript::has_property(const StringName &p_method) const { PropertyInfo PluginScript::get_property_info(const StringName &p_property) const { ASSERT_SCRIPT_VALID_V(PropertyInfo()); const Map<StringName, PropertyInfo>::Element *e = _properties_info.find(p_property); - if (e != NULL) { + if (e != nullptr) { return e->get(); } else { return PropertyInfo(); @@ -391,7 +420,7 @@ bool PluginScript::get_property_default_value(const StringName &p_property, Vari ASSERT_SCRIPT_VALID_V(false); #ifdef TOOLS_ENABLED const Map<StringName, Variant>::Element *e = _properties_default_values.find(p_property); - if (e != NULL) { + if (e != nullptr) { r_value = e->get(); return true; } else { @@ -406,23 +435,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."); } @@ -441,46 +469,91 @@ bool PluginScript::has_script_signal(const StringName &p_signal) const { void PluginScript::get_script_signal_list(List<MethodInfo> *r_signals) const { ASSERT_SCRIPT_VALID(); - for (Map<StringName, MethodInfo>::Element *e = _signals_info.front(); e != NULL; e = e->next()) { + for (Map<StringName, MethodInfo>::Element *e = _signals_info.front(); e != nullptr; e = e->next()) { r_signals->push_back(e->get()); } } int PluginScript::get_member_line(const StringName &p_member) const { #ifdef TOOLS_ENABLED - if (_member_lines.has(p_member)) + if (_member_lines.has(p_member)) { return _member_lines[p_member]; - else + } #endif - return -1; + 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_rset_mode(const StringName &p_variable) const { +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 = _variables_rset_mode.find(p_variable); - if (e != NULL) { - return e->get(); - } else { + 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; +} + +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); + 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() : - _data(NULL), - _desc(NULL), - _language(NULL), - _tool(false), - _valid(false), _script_list(this) { } diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index f67c88c794..9cd38cd4b4 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -38,18 +38,17 @@ #include <pluginscript/godot_pluginscript.h> class PluginScript : public Script { - GDCLASS(PluginScript, Script); friend class PluginScriptInstance; friend class PluginScriptLanguage; private: - godot_pluginscript_script_data *_data; - const godot_pluginscript_script_desc *_desc; - PluginScriptLanguage *_language; - bool _tool; - bool _valid; + godot_pluginscript_script_data *_data = nullptr; + const godot_pluginscript_script_desc *_desc = nullptr; + PluginScriptLanguage *_language = nullptr; + bool _tool = false; + bool _valid = false; Ref<Script> _ref_base_parent; StringName _native_parent; @@ -60,8 +59,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,54 +71,65 @@ 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); + bool inherits_script(const Ref<Script> &p_script) const override; + + 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; //void _update_placeholder(PlaceHolderScriptInstance *p_placeholder); - virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder); + virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) override; #endif public: - virtual bool can_instance() const; + virtual bool can_instance() const override; - virtual Ref<Script> get_base_script() const; //for script inheritance + virtual Ref<Script> get_base_script() const override; //for script inheritance - virtual StringName get_instance_base_type() const; // this may not work in all scripts, will return empty if so - virtual ScriptInstance *instance_create(Object *p_this); - virtual bool instance_has(const Object *p_this) const; + virtual StringName get_instance_base_type() const override; // this may not work in all scripts, will return empty if so + virtual ScriptInstance *instance_create(Object *p_this) override; + virtual bool instance_has(const Object *p_this) const override; - virtual bool has_source_code() const; - virtual String get_source_code() const; - virtual void set_source_code(const String &p_code); - virtual Error reload(bool p_keep_state = false); + virtual bool has_source_code() const override; + virtual String get_source_code() const override; + virtual void set_source_code(const String &p_code) override; + virtual Error reload(bool p_keep_state = false) override; // TODO: load_source_code only allow utf-8 file, should handle bytecode as well ? virtual Error load_source_code(const String &p_path); - virtual bool has_method(const StringName &p_method) const; - virtual MethodInfo get_method_info(const StringName &p_method) const; + virtual bool has_method(const StringName &p_method) const override; + virtual MethodInfo get_method_info(const StringName &p_method) const override; bool has_property(const StringName &p_method) const; PropertyInfo get_property_info(const StringName &p_property) const; - bool is_tool() const { return _tool; } - bool is_valid() const { return true; } + bool is_tool() const override { return _tool; } + bool is_valid() const override { return true; } + + virtual ScriptLanguage *get_language() const override; - virtual ScriptLanguage *get_language() const; + virtual bool has_script_signal(const StringName &p_signal) const override; + virtual void get_script_signal_list(List<MethodInfo> *r_signals) const override; - virtual bool has_script_signal(const StringName &p_signal) const; - virtual void get_script_signal_list(List<MethodInfo> *r_signals) const; + virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const override; - virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const; + virtual void update_exports() override; + virtual void get_script_method_list(List<MethodInfo> *r_methods) const override; + virtual void get_script_property_list(List<PropertyInfo> *r_properties) const override; - virtual void update_exports(); - virtual void get_script_method_list(List<MethodInfo> *r_methods) const; - virtual void get_script_property_list(List<PropertyInfo> *r_properties) const; + virtual int get_member_line(const StringName &p_member) const override; - virtual int get_member_line(const StringName &p_member) const; + virtual Vector<ScriptNetData> get_rpc_methods() const override; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const override; + virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const override; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override; + virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override; - MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; - MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + virtual Vector<ScriptNetData> get_rset_properties() const override; + virtual uint16_t get_rset_property_id(const StringName &p_property) const override; + virtual StringName get_rset_property(const uint16_t p_rset_property_id) const override; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const override; + virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override; PluginScript(); void init(PluginScriptLanguage *language); diff --git a/modules/gdnative/pluginscript/register_types.h b/modules/gdnative/pluginscript/register_types.h index a4f7284b54..c6a64b4f40 100644 --- a/modules/gdnative/pluginscript/register_types.h +++ b/modules/gdnative/pluginscript/register_types.h @@ -28,5 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef PLUGINSCRIPT_REGISTER_TYPES_H +#define PLUGINSCRIPT_REGISTER_TYPES_H + void register_pluginscript_types(); void unregister_pluginscript_types(); + +#endif // PLUGINSCRIPT_REGISTER_TYPES_H |