Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix CustomType error spams in CreateDialog #25675

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 36 additions & 8 deletions editor/create_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,17 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
bool cpp_type = ClassDB::class_exists(p_type);
EditorData &ed = EditorNode::get_editor_data();

bool is_script_class = !cpp_type || ScriptServer::is_global_class(p_type);
bool is_custom_type = !(cpp_type || is_script_class) || ed.is_custom_type(p_type);

if (p_type == base_type)
return;

if (cpp_type) {
if (!ClassDB::is_parent_class(p_type, base_type))
return;
} else {
if (!ScriptServer::is_global_class(p_type) || !ed.script_class_is_parent(p_type, base_type))
if (!is_script_class || !ed.script_class_is_parent(p_type, base_type))
return;

String script_path = ScriptServer::get_global_class_path(p_type);
Expand All @@ -196,14 +199,25 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
return;
}

bool can_instance = (cpp_type && ClassDB::can_instance(p_type)) || ScriptServer::is_global_class(p_type);
StringName cpp_base = p_type;
if (is_script_class)
cpp_base = ScriptServer::get_global_class_base(p_type);
else if (is_custom_type)
cpp_base = ed.custom_type_get_base(p_type);

bool can_instance = ClassDB::can_instance(cpp_base);

TreeItem *item = search_options->create_item(parent);
item->set_metadata(0, p_type);
if (cpp_type) {
item->set_text(0, p_type);
} else {
item->set_metadata(0, p_type);
} else if (is_script_class) {
item->set_text(0, p_type + " (" + ScriptServer::get_global_class_path(p_type).get_file() + ")");
} else if (is_custom_type) {
Ref<Script> script = ed.get_custom_type(p_type).script;
if (script.is_null())
return;
item->set_text(0, p_type + " (" + script->get_path().get_file() + ")");
}
if (!can_instance) {
item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
Expand All @@ -213,13 +227,27 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
String to_select_type = *to_select ? (*to_select)->get_text(0) : "";
to_select_type = to_select_type.split(" ")[0];
bool current_item_is_preferred;

String cpp_to_select_type = to_select_type;
if (ScriptServer::is_global_class(to_select_type))
cpp_to_select_type = ScriptServer::get_global_class_base(to_select_type);
String select_ct_base;
const EditorData::CustomType &select_ct = ed.get_custom_type(to_select_type, &select_ct_base);
if (select_ct.script.is_valid()) {
cpp_to_select_type = select_ct_base;
}

if (cpp_type) {
String cpp_to_select_type = to_select_type;
if (ScriptServer::is_global_class(to_select_type))
cpp_to_select_type = ScriptServer::get_global_class_base(to_select_type);
current_item_is_preferred = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(cpp_to_select_type, preferred_search_result_type);
} else {
} else if (is_script_class) {
current_item_is_preferred = ed.script_class_is_parent(p_type, preferred_search_result_type) && !ed.script_class_is_parent(to_select_type, preferred_search_result_type) && search_box->get_text() != to_select_type;
} else if (is_custom_type) {
String ct_base;
const EditorData::CustomType &ct = ed.get_custom_type(p_type, &ct_base);

if (ct.script.is_valid()) {
current_item_is_preferred = ClassDB::is_parent_class(ct_base, preferred_search_result_type) && !ClassDB::is_parent_class(cpp_to_select_type, preferred_search_result_type);
}
}
if (search_box->get_text() == p_type || (*to_select && p_type.length() < (*to_select)->get_text(0).length())) {
current_item_is_preferred = true;
Expand Down
52 changes: 52 additions & 0 deletions editor/editor_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,58 @@ void EditorData::remove_custom_type(const String &p_type) {
}
}

const EditorData::CustomType EditorData::get_custom_type(const String &p_type, String *r_base) const {
for (Map<String, Vector<CustomType> >::Element *E = get_custom_types().front(); E; E = E->next()) {
const Vector<CustomType> &customs = E->value();
for (int i = 0; i < customs.size(); i++) {
if (p_type == customs[i].name) {
if (r_base)
*r_base = E->key();
return customs[i];
}
}
}
return CustomType();
}

bool EditorData::is_custom_type(const String &p_type) const {
const CustomType &ct = get_custom_type(p_type);
return ct.script.is_valid();
}

String EditorData::custom_type_get_base(const String &p_type) const {
const CustomType &ct = get_custom_type(p_type);
return ct.script.is_valid() && p_type == ct.name ? String(ct.script->get_instance_base_type()) : String();
}

bool EditorData::custom_type_is_parent_class(const String &p_type, const String &p_inherits) const {
const CustomType &ct = get_custom_type(p_type);
if (p_type == ct.name) {
Ref<Script> script = ct.script;
if (script.is_null())
return false;
if (ClassDB::class_exists(p_inherits))
return ClassDB::is_parent_class(script->get_instance_base_type(), p_inherits);
if (ScriptServer::is_global_class(p_inherits)) {
Ref<Script> script_class = ResourceLoader::load(ScriptServer::get_global_class_path(p_inherits), "Script");
if (script_class.is_null())
return false;
return script_inherits(script, script_class);
}
return false; // custom types can't inherit
}
return false;
}

bool EditorData::script_inherits(const Ref<Script> &p_script, const Ref<Script> &p_inherits) {
Ref<Script> current = p_script;
void *inherits_ptr = p_inherits.get_ref_ptr().get_data();
while (current.is_valid() && current.get_ref_ptr().get_data() != inherits_ptr) {
current = current->get_base_script();
}
return current.is_valid();
}

int EditorData::add_edited_scene(int p_at_pos) {

if (p_at_pos < 0)
Expand Down
6 changes: 6 additions & 0 deletions editor/editor_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ class EditorData {
Object *instance_custom_type(const String &p_type, const String &p_inherits);
void remove_custom_type(const String &p_type);
const Map<String, Vector<CustomType> > &get_custom_types() const { return custom_types; }
const CustomType get_custom_type(const String &p_type, String *r_base = NULL) const;
bool is_custom_type(const String &p_type) const;
String custom_type_get_base(const String &p_type) const;
bool custom_type_is_parent_class(const String &p_type, const String &p_inherits) const;

static bool script_inherits(const Ref<Script> &p_script, const Ref<Script> &p_inherits);

int add_edited_scene(int p_at_pos);
void move_edited_scene_index(int p_idx, int p_to_idx);
Expand Down