Improve inheritance system in gdnative pluginscript
This commit is contained in:
parent
05b1843818
commit
0de61998e4
4 changed files with 29 additions and 28 deletions
|
@ -84,8 +84,9 @@ Variant PluginScriptInstance::call(const StringName &p_method, const Variant **p
|
|||
godot_variant ret = _desc->call_method(
|
||||
_data, (godot_string_name *)&p_method, (const godot_variant **)p_args,
|
||||
p_argcount, (godot_variant_call_error *)&r_error);
|
||||
Variant *var_ret = (Variant *)&ret;
|
||||
return *var_ret;
|
||||
Variant var_ret = *(Variant *)&ret;
|
||||
godot_variant_destroy(&ret);
|
||||
return var_ret;
|
||||
}
|
||||
|
||||
#if 0 // TODO: Don't rely on default implementations provided by ScriptInstance ?
|
||||
|
|
|
@ -103,6 +103,7 @@ Ref<Script> PluginScriptLanguage::get_template(const String &p_class_name, const
|
|||
if (_desc.get_template_source_code) {
|
||||
godot_string src = _desc.get_template_source_code(_data, (godot_string *)&p_class_name, (godot_string *)&p_base_class_name);
|
||||
script->set_source_code(*(String *)&src);
|
||||
godot_string_destroy(&src);
|
||||
}
|
||||
return script;
|
||||
}
|
||||
|
|
|
@ -131,13 +131,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 +207,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 ressource 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)) {
|
||||
|
|
|
@ -53,7 +53,7 @@ private:
|
|||
bool _tool;
|
||||
bool _valid;
|
||||
|
||||
Ref<PluginScript> _ref_base_parent;
|
||||
Ref<Script> _ref_base_parent;
|
||||
StringName _native_parent;
|
||||
SelfList<PluginScript> _script_list;
|
||||
|
||||
|
|
Loading…
Reference in a new issue