diff options
Diffstat (limited to 'modules/gdnative/pluginscript/pluginscript_script.cpp')
-rw-r--r-- | modules/gdnative/pluginscript/pluginscript_script.cpp | 139 |
1 files changed, 102 insertions, 37 deletions
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index c3a623e9a1..f7c961d38b 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,17 +34,15 @@ #include "pluginscript_instance.h" #include "pluginscript_script.h" -#if DEBUG_ENABLED -#define __ASSERT_SCRIPT_REASON "Cannot retrieve pluginscript class for this script, is you code correct ?" -#define ASSERT_SCRIPT_VALID() \ - { \ - ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \ - ERR_FAIL_COND(!can_instance()) \ +#ifdef DEBUG_ENABLED +#define __ASSERT_SCRIPT_REASON "Cannot retrieve PluginScript class for this script, is your code correct?" +#define ASSERT_SCRIPT_VALID() \ + { \ + ERR_FAIL_COND_MSG(!can_instance(), __ASSERT_SCRIPT_REASON); \ } -#define ASSERT_SCRIPT_VALID_V(ret) \ - { \ - ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \ - ERR_FAIL_COND_V(!can_instance(), ret) \ +#define ASSERT_SCRIPT_VALID_V(ret) \ + { \ + ERR_FAIL_COND_V_MSG(!can_instance(), ret, __ASSERT_SCRIPT_REASON); \ } #else #define ASSERT_SCRIPT_VALID() @@ -52,6 +50,79 @@ #endif 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; + + // Create instance + PluginScriptInstance *instance = memnew(PluginScriptInstance()); + + if (instance->init(this, p_owner)) { + _language->lock(); + _instances.insert(instance->get_owner()); + _language->unlock(); + } else { + r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL; + memdelete(instance); + ERR_FAIL_V(NULL); + } + + // Construct + // TODO: Support arguments in the constructor? + // There is currently no way to get the constructor function name of the script. + // instance->call("__init__", p_args, p_argcount, r_error); + if (p_argcount > 0) { + WARN_PRINT("PluginScript doesn't support arguments in the constructor"); + } + + return instance; +} + +Variant PluginScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { + + r_error.error = Variant::CallError::CALL_OK; + + if (!_valid) { + r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + + REF ref; + Object *owner = NULL; + + if (get_instance_base_type() == "") { + owner = memnew(Reference); + } else { + owner = ClassDB::instance(get_instance_base_type()); + } + + if (!owner) { + r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL; + return Variant(); + } + + Reference *r = Object::cast_to<Reference>(owner); + if (r) { + ref = REF(r); + } + + PluginScriptInstance *instance = _create_instance(p_args, p_argcount, owner, r_error); + + if (!instance) { + if (ref.is_null()) { + memdelete(owner); //no owner, sorry + } + return Variant(); + } + + if (ref.is_valid()) { + return ref; + } else { + return owner; + } } #ifdef TOOLS_ENABLED @@ -124,22 +195,12 @@ ScriptInstance *PluginScript::instance_create(Object *p_this) { // if (ScriptDebugger::get_singleton()) { // _language->debug_break_parse(get_path(), 0, msg); // } - ERR_EXPLAIN(msg); - ERR_FAIL_V(NULL); + ERR_FAIL_V_MSG(NULL, msg); } } - PluginScriptInstance *instance = memnew(PluginScriptInstance()); - const bool success = instance->init(this, p_this); - if (success) { - _language->lock(); - _instances.insert(instance->get_owner()); - _language->unlock(); - return instance; - } else { - memdelete(instance); - ERR_FAIL_V(NULL); - } + Variant::CallError unchecked_error; + return _create_instance(NULL, 0, p_this, unchecked_error); } bool PluginScript::instance_has(const Object *p_this) const { @@ -165,6 +226,8 @@ void PluginScript::set_source_code(const String &p_code) { } Error PluginScript::reload(bool p_keep_state) { + ERR_FAIL_COND_V(!_language, ERR_UNCONFIGURED); + _language->lock(); ERR_FAIL_COND_V(!p_keep_state && _instances.size(), ERR_ALREADY_IN_USE); _language->unlock(); @@ -206,8 +269,7 @@ Error PluginScript::reload(bool p_keep_state) { _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); + ERR_FAIL_V_MSG(ERR_PARSE_ERROR, _path + ": Script '" + name + "' has an invalid parent '" + *base_name + "'."); } } } @@ -220,7 +282,7 @@ Error PluginScript::reload(bool p_keep_state) { Dictionary *members = (Dictionary *)&manifest.member_lines; for (const Variant *key = members->next(); key != NULL; key = members->next(key)) { - _member_lines[*key] = (*members)[key]; + _member_lines[*key] = (*members)[*key]; } Array *methods = (Array *)&manifest.methods; for (int i = 0; i < methods->size(); ++i) { @@ -339,9 +401,7 @@ Error PluginScript::load_source_code(const String &p_path) { PoolVector<uint8_t> sourcef; Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); - if (err) { - ERR_FAIL_COND_V(err, err); - } + ERR_FAIL_COND_V_MSG(err, err, "Cannot open file '" + p_path + "'."); int len = f->get_len(); sourcef.resize(len + 1); @@ -354,8 +414,7 @@ Error PluginScript::load_source_code(const String &p_path) { String s; if (s.parse_utf8((const char *)w.ptr())) { - ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode."); - ERR_FAIL_V(ERR_INVALID_DATA); + 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."); } _source = s; @@ -409,6 +468,8 @@ MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable PluginScript::PluginScript() : _data(NULL), + _desc(NULL), + _language(NULL), _tool(false), _valid(false), _script_list(this) { @@ -426,11 +487,15 @@ void PluginScript::init(PluginScriptLanguage *language) { } PluginScript::~PluginScript() { - _desc->finish(_data); + if (_desc && _data) { + _desc->finish(_data); + } #ifdef DEBUG_ENABLED - _language->lock(); - _language->_script_list.remove(&_script_list); - _language->unlock(); + if (_language) { + _language->lock(); + _language->_script_list.remove(&_script_list); + _language->unlock(); + } #endif } |