diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 01d62a1c62d0..2e6e24ab6765 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -140,6 +140,149 @@ const char *GDScriptFunctions::get_func_name(Function p_func) { return _names[p_func]; } +Variant GDScriptFunctions::_inst2dict(const Variant &p_arg, Variant::CallError &r_error) { + if (p_arg.get_type() == Variant::NIL) { + return Variant(); + } else if (p_arg.get_type() != Variant::OBJECT) { + r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + return Variant(); + } else { + + Object *obj = p_arg; + if (!obj) { + return Variant(); + + } else if (!obj->get_script_instance() || obj->get_script_instance()->get_language() != GDScriptLanguage::get_singleton()) { + + r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::DICTIONARY; + return RTR("Not a script with an instance"); + } else { + + GDScriptInstance *ins = static_cast(obj->get_script_instance()); + Ref base = ins->get_script(); + if (base.is_null()) { + + r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::DICTIONARY; + return RTR("Not based on a script"); + } + + GDScript *p = base.ptr(); + Vector sname; + + while (p->_owner) { + + sname.push_back(p->name); + p = p->_owner; + } + sname.invert(); + + if (!p->path.is_resource_file()) { + r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::DICTIONARY; + return RTR("Not based on a resource file"); + } + + NodePath cp(sname, Vector(), false); + + Dictionary d; + d["@subpath"] = cp; + d["@path"] = p->get_path(); + + for (Map::Element *E = base->member_indices.front(); E; E = E->next()) { + if (!d.has(E->key())) { + if (ins->members[E->get().index].get_type() == Variant::OBJECT) { + Variant::CallError err; + err.error = Variant::CallError::CALL_OK; + Dictionary sub_inst = _inst2dict(ins->members[E->get().index], err); + if (err.error == Variant::CallError::CALL_OK) + d[E->key()] = sub_inst; + } else { + d[E->key()] = ins->members[E->get().index]; + } + } + } + return d; + } + } +} + +Variant GDScriptFunctions::_dict2inst(const Dictionary &dict, Variant::CallError &r_error) { + + if (!dict.has("@path")) { + + r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + return RTR("Invalid instance dictionary format (missing @path)"); + } + + Ref