Fix cases of resources destroyed too early

This commit is contained in:
Pedro J. Estébanez 2021-01-06 20:25:05 +01:00
parent 8158d17edf
commit 6fbe0a494b
9 changed files with 41 additions and 50 deletions

View file

@ -408,15 +408,15 @@ String CreateDialog::get_selected_type() {
return selected->get_text(0); return selected->get_text(0);
} }
Object *CreateDialog::instance_selected() { Variant CreateDialog::instance_selected() {
TreeItem *selected = search_options->get_selected(); TreeItem *selected = search_options->get_selected();
if (!selected) { if (!selected) {
return nullptr; return Variant();
} }
Variant md = selected->get_metadata(0); Variant md = selected->get_metadata(0);
Object *obj = nullptr; Variant obj;
if (md.get_type() != Variant::NIL) { if (md.get_type() != Variant::NIL) {
String custom = md; String custom = md;
if (ScriptServer::is_global_class(custom)) { if (ScriptServer::is_global_class(custom)) {
@ -434,13 +434,13 @@ Object *CreateDialog::instance_selected() {
// Check if any Object-type property should be instantiated. // Check if any Object-type property should be instantiated.
List<PropertyInfo> pinfo; List<PropertyInfo> pinfo;
obj->get_property_list(&pinfo); ((Object *)obj)->get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
PropertyInfo pi = E->get(); PropertyInfo pi = E->get();
if (pi.type == Variant::OBJECT && pi.usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) { if (pi.type == Variant::OBJECT && pi.usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) {
Object *prop = ClassDB::instance(pi.class_name); Object *prop = ClassDB::instance(pi.class_name);
obj->set(pi.name, prop); ((Object *)obj)->set(pi.name, prop);
} }
} }

View file

@ -102,7 +102,7 @@ protected:
void _save_and_update_favorite_list(); void _save_and_update_favorite_list();
public: public:
Object *instance_selected(); Variant instance_selected();
String get_selected_type(); String get_selected_type();
void set_base_type(const String &p_base) { base_type = p_base; } void set_base_type(const String &p_base) { base_type = p_base; }

View file

@ -468,24 +468,25 @@ void EditorData::add_custom_type(const String &p_type, const String &p_inherits,
custom_types[p_inherits].push_back(ct); custom_types[p_inherits].push_back(ct);
} }
Object *EditorData::instance_custom_type(const String &p_type, const String &p_inherits) { Variant EditorData::instance_custom_type(const String &p_type, const String &p_inherits) {
if (get_custom_types().has(p_inherits)) { if (get_custom_types().has(p_inherits)) {
for (int i = 0; i < get_custom_types()[p_inherits].size(); i++) { for (int i = 0; i < get_custom_types()[p_inherits].size(); i++) {
if (get_custom_types()[p_inherits][i].name == p_type) { if (get_custom_types()[p_inherits][i].name == p_type) {
Ref<Script> script = get_custom_types()[p_inherits][i].script; Ref<Script> script = get_custom_types()[p_inherits][i].script;
Object *ob = ClassDB::instance(p_inherits); Variant ob = ClassDB::instance(p_inherits);
ERR_FAIL_COND_V(!ob, nullptr); ERR_FAIL_COND_V(!ob, Variant());
if (ob->is_class("Node")) { Node *n = Object::cast_to<Node>(ob);
ob->call("set_name", p_type); if (n) {
n->set_name(p_type);
} }
ob->set_script(script); ((Object *)ob)->set_script(script);
return ob; return ob;
} }
} }
} }
return nullptr; return Variant();
} }
void EditorData::remove_custom_type(const String &p_type) { void EditorData::remove_custom_type(const String &p_type) {
@ -867,18 +868,18 @@ StringName EditorData::script_class_get_base(const String &p_class) const {
return script->get_language()->get_global_class_name(base_script->get_path()); return script->get_language()->get_global_class_name(base_script->get_path());
} }
Object *EditorData::script_class_instance(const String &p_class) { Variant EditorData::script_class_instance(const String &p_class) {
if (ScriptServer::is_global_class(p_class)) { if (ScriptServer::is_global_class(p_class)) {
Object *obj = ClassDB::instance(ScriptServer::get_global_class_native_base(p_class)); Variant obj = ClassDB::instance(ScriptServer::get_global_class_native_base(p_class));
if (obj) { if (obj) {
Ref<Script> script = script_class_load_script(p_class); Ref<Script> script = script_class_load_script(p_class);
if (script.is_valid()) { if (script.is_valid()) {
obj->set_script(script); ((Object *)obj)->set_script(script);
} }
return obj; return obj;
} }
} }
return nullptr; return Variant();
} }
Ref<Script> EditorData::script_class_load_script(const String &p_class) const { Ref<Script> EditorData::script_class_load_script(const String &p_class) const {

View file

@ -171,7 +171,7 @@ public:
void restore_editor_global_states(); void restore_editor_global_states();
void add_custom_type(const String &p_type, const String &p_inherits, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon); void add_custom_type(const String &p_type, const String &p_inherits, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon);
Object *instance_custom_type(const String &p_type, const String &p_inherits); Variant instance_custom_type(const String &p_type, const String &p_inherits);
void remove_custom_type(const String &p_type); void remove_custom_type(const String &p_type);
const Map<String, Vector<CustomType>> &get_custom_types() const { return custom_types; } const Map<String, Vector<CustomType>> &get_custom_types() const { return custom_types; }
@ -208,7 +208,7 @@ public:
bool script_class_is_parent(const String &p_class, const String &p_inherits); bool script_class_is_parent(const String &p_class, const String &p_inherits);
StringName script_class_get_base(const String &p_class) const; StringName script_class_get_base(const String &p_class) const;
Object *script_class_instance(const String &p_class); Variant script_class_instance(const String &p_class);
Ref<Script> script_class_load_script(const String &p_class) const; Ref<Script> script_class_load_script(const String &p_class) const;

View file

@ -2544,35 +2544,32 @@ void EditorPropertyResource::_menu_option(int p_which) {
return; return;
} }
Object *obj = nullptr; Variant obj;
RES res_temp;
if (ScriptServer::is_global_class(intype)) { if (ScriptServer::is_global_class(intype)) {
obj = ClassDB::instance(ScriptServer::get_global_class_native_base(intype)); obj = ClassDB::instance(ScriptServer::get_global_class_native_base(intype));
if (obj) { if (obj) {
res_temp = obj;
Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(intype)); Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(intype));
if (script.is_valid()) { if (script.is_valid()) {
obj->set_script(Variant(script)); ((Object *)obj)->set_script(script);
} }
} }
} else { } else {
obj = ClassDB::instance(intype); obj = ClassDB::instance(intype);
res_temp = obj;
} }
if (!obj) { if (!obj) {
obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource");
res_temp = obj;
} }
ERR_BREAK(!res_temp.is_valid()); Resource *resp = Object::cast_to<Resource>(obj);
ERR_BREAK(!resp);
if (get_edited_object() && base_type != String() && base_type == "Script") { if (get_edited_object() && base_type != String() && base_type == "Script") {
//make visual script the right type //make visual script the right type
res_temp->call("set_instance_base_type", get_edited_object()->get_class()); resp->call("set_instance_base_type", get_edited_object()->get_class());
} }
res = res_temp; res = RES(resp);
emit_changed(get_edited_property(), res); emit_changed(get_edited_property(), res);
update_property(); update_property();

View file

@ -1898,7 +1898,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} }
void FileSystemDock::_resource_created() { void FileSystemDock::_resource_created() {
Object *c = new_resource_dialog->instance_selected(); Variant c = new_resource_dialog->instance_selected();
ERR_FAIL_COND(!c); ERR_FAIL_COND(!c);
Resource *r = Object::cast_to<Resource>(c); Resource *r = Object::cast_to<Resource>(c);
@ -1912,17 +1912,14 @@ void FileSystemDock::_resource_created() {
memdelete(node); memdelete(node);
} }
REF res(r); editor->push_item(r);
editor->push_item(c);
RES current_res = RES(r);
String fpath = path; String fpath = path;
if (!fpath.ends_with("/")) { if (!fpath.ends_with("/")) {
fpath = fpath.get_base_dir(); fpath = fpath.get_base_dir();
} }
editor->save_resource_as(current_res, fpath); editor->save_resource_as(RES(r), fpath);
} }
void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) { void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) {

View file

@ -270,14 +270,13 @@ void InspectorDock::_select_history(int p_idx) {
} }
void InspectorDock::_resource_created() { void InspectorDock::_resource_created() {
Object *c = new_resource_dialog->instance_selected(); Variant c = new_resource_dialog->instance_selected();
ERR_FAIL_COND(!c); ERR_FAIL_COND(!c);
Resource *r = Object::cast_to<Resource>(c); Resource *r = Object::cast_to<Resource>(c);
ERR_FAIL_COND(!r); ERR_FAIL_COND(!r);
REF res(r); editor->push_item(r);
editor->push_item(c);
} }
void InspectorDock::_resource_selected(const RES &p_res, const String &p_property) { void InspectorDock::_resource_selected(const RES &p_res, const String &p_property) {

View file

@ -262,7 +262,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
return; return;
} }
Object *obj = ClassDB::instance(intype); Variant obj = ClassDB::instance(intype);
if (!obj) { if (!obj) {
if (ScriptServer::is_global_class(intype)) { if (ScriptServer::is_global_class(intype)) {
@ -280,7 +280,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
res->call("set_instance_base_type", owner->get_class()); res->call("set_instance_base_type", owner->get_class());
} }
v = res; v = obj;
emit_signal("variant_changed"); emit_signal("variant_changed");
} break; } break;
@ -1064,7 +1064,7 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) {
String intype = inheritors_array[p_idx]; String intype = inheritors_array[p_idx];
Object *obj = ClassDB::instance(intype); Variant obj = ClassDB::instance(intype);
if (!obj) { if (!obj) {
if (ScriptServer::is_global_class(intype)) { if (ScriptServer::is_global_class(intype)) {
@ -1075,11 +1075,9 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) {
} }
ERR_FAIL_COND(!obj); ERR_FAIL_COND(!obj);
ERR_FAIL_COND(!Object::cast_to<Resource>(obj));
Resource *res = Object::cast_to<Resource>(obj); v = obj;
ERR_FAIL_COND(!res);
v = res;
emit_signal("variant_changed"); emit_signal("variant_changed");
hide(); hide();
} }
@ -1251,7 +1249,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
String intype = inheritors_array[0]; String intype = inheritors_array[0];
if (hint == PROPERTY_HINT_RESOURCE_TYPE) { if (hint == PROPERTY_HINT_RESOURCE_TYPE) {
Object *obj = ClassDB::instance(intype); Variant obj = ClassDB::instance(intype);
if (!obj) { if (!obj) {
if (ScriptServer::is_global_class(intype)) { if (ScriptServer::is_global_class(intype)) {
@ -1262,10 +1260,9 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
} }
ERR_BREAK(!obj); ERR_BREAK(!obj);
Resource *res = Object::cast_to<Resource>(obj); ERR_BREAK(!Object::cast_to<Resource>(obj));
ERR_BREAK(!res);
v = res; v = obj;
emit_signal("variant_changed"); emit_signal("variant_changed");
hide(); hide();
} }

View file

@ -1936,7 +1936,7 @@ void SceneTreeDock::_selection_changed() {
} }
void SceneTreeDock::_do_create(Node *p_parent) { void SceneTreeDock::_do_create(Node *p_parent) {
Object *c = create_dialog->instance_selected(); Variant c = create_dialog->instance_selected();
ERR_FAIL_COND(!c); ERR_FAIL_COND(!c);
Node *child = Object::cast_to<Node>(c); Node *child = Object::cast_to<Node>(c);
@ -2016,7 +2016,7 @@ void SceneTreeDock::_create() {
Node *n = E->get(); Node *n = E->get();
ERR_FAIL_COND(!n); ERR_FAIL_COND(!n);
Object *c = create_dialog->instance_selected(); Variant c = create_dialog->instance_selected();
ERR_FAIL_COND(!c); ERR_FAIL_COND(!c);
Node *newnode = Object::cast_to<Node>(c); Node *newnode = Object::cast_to<Node>(c);