Add a map of autoloads to ProjectSettings
So places that need to look into it can use the list instead of parsing ProjectSettings details (like checking "*" in path for testing if it's singleton).
This commit is contained in:
parent
a535b9160d
commit
9654365547
|
@ -144,6 +144,12 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
|
|
||||||
if (p_value.get_type() == Variant::NIL) {
|
if (p_value.get_type() == Variant::NIL) {
|
||||||
props.erase(p_name);
|
props.erase(p_name);
|
||||||
|
if (p_name.operator String().begins_with("autoload/")) {
|
||||||
|
String node_name = p_name.operator String().split("/")[1];
|
||||||
|
if (autoloads.has(node_name)) {
|
||||||
|
remove_autoload(node_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (p_name == CoreStringNames::get_singleton()->_custom_features) {
|
if (p_name == CoreStringNames::get_singleton()->_custom_features) {
|
||||||
Vector<String> custom_feature_array = String(p_value).split(",");
|
Vector<String> custom_feature_array = String(p_value).split(",");
|
||||||
|
@ -181,6 +187,19 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
} else {
|
} else {
|
||||||
props[p_name] = VariantContainer(p_value, last_order++);
|
props[p_name] = VariantContainer(p_value, last_order++);
|
||||||
}
|
}
|
||||||
|
if (p_name.operator String().begins_with("autoload/")) {
|
||||||
|
String node_name = p_name.operator String().split("/")[1];
|
||||||
|
AutoloadInfo autoload;
|
||||||
|
autoload.name = node_name;
|
||||||
|
String path = p_value;
|
||||||
|
if (path.begins_with("*")) {
|
||||||
|
autoload.is_singleton = true;
|
||||||
|
autoload.path = path.substr(1);
|
||||||
|
} else {
|
||||||
|
autoload.path = path;
|
||||||
|
}
|
||||||
|
add_autoload(autoload);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -945,6 +964,29 @@ bool ProjectSettings::has_custom_feature(const String &p_feature) const {
|
||||||
return custom_features.has(p_feature);
|
return custom_features.has(p_feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<StringName, ProjectSettings::AutoloadInfo> ProjectSettings::get_autoload_list() const {
|
||||||
|
return autoloads;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectSettings::add_autoload(const AutoloadInfo &p_autoload) {
|
||||||
|
ERR_FAIL_COND_MSG(p_autoload.name == StringName(), "Trying to add autoload with no name.");
|
||||||
|
autoloads[p_autoload.name] = p_autoload;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectSettings::remove_autoload(const StringName &p_autoload) {
|
||||||
|
ERR_FAIL_COND_MSG(!autoloads.has(p_autoload), "Trying to remove non-existent autoload.");
|
||||||
|
autoloads.erase(p_autoload);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProjectSettings::has_autoload(const StringName &p_autoload) const {
|
||||||
|
return autoloads.has(p_autoload);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectSettings::AutoloadInfo ProjectSettings::get_autoload(const StringName &p_name) const {
|
||||||
|
ERR_FAIL_COND_V_MSG(!autoloads.has(p_name), AutoloadInfo(), "Trying to get non-existent autoload.");
|
||||||
|
return autoloads[p_name];
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectSettings::_bind_methods() {
|
void ProjectSettings::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting);
|
ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting);
|
||||||
ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &ProjectSettings::set_setting);
|
ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &ProjectSettings::set_setting);
|
||||||
|
|
|
@ -47,6 +47,12 @@ public:
|
||||||
NO_BUILTIN_ORDER_BASE = 1 << 16
|
NO_BUILTIN_ORDER_BASE = 1 << 16
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AutoloadInfo {
|
||||||
|
StringName name;
|
||||||
|
String path;
|
||||||
|
bool is_singleton = false;
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct VariantContainer {
|
struct VariantContainer {
|
||||||
int order = 0;
|
int order = 0;
|
||||||
|
@ -79,6 +85,8 @@ protected:
|
||||||
Set<String> custom_features;
|
Set<String> custom_features;
|
||||||
Map<StringName, StringName> feature_overrides;
|
Map<StringName, StringName> feature_overrides;
|
||||||
|
|
||||||
|
Map<StringName, AutoloadInfo> autoloads;
|
||||||
|
|
||||||
bool _set(const StringName &p_name, const Variant &p_value);
|
bool _set(const StringName &p_name, const Variant &p_value);
|
||||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||||
|
@ -148,6 +156,12 @@ public:
|
||||||
|
|
||||||
bool has_custom_feature(const String &p_feature) const;
|
bool has_custom_feature(const String &p_feature) const;
|
||||||
|
|
||||||
|
Map<StringName, AutoloadInfo> get_autoload_list() const;
|
||||||
|
void add_autoload(const AutoloadInfo &p_autoload);
|
||||||
|
void remove_autoload(const StringName &p_autoload);
|
||||||
|
bool has_autoload(const StringName &p_autoload) const;
|
||||||
|
AutoloadInfo get_autoload(const StringName &p_name) const;
|
||||||
|
|
||||||
ProjectSettings();
|
ProjectSettings();
|
||||||
~ProjectSettings();
|
~ProjectSettings();
|
||||||
};
|
};
|
||||||
|
|
|
@ -477,6 +477,8 @@ void EditorAutoloadSettings::update_autoload() {
|
||||||
info.node->queue_delete();
|
info.node->queue_delete();
|
||||||
info.node = nullptr;
|
info.node = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProjectSettings::get_singleton()->remove_autoload(info.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load new/changed autoloads
|
// Load new/changed autoloads
|
||||||
|
@ -503,6 +505,12 @@ void EditorAutoloadSettings::update_autoload() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProjectSettings::AutoloadInfo prop_info;
|
||||||
|
prop_info.name = info->name;
|
||||||
|
prop_info.path = info->path;
|
||||||
|
prop_info.is_singleton = info->is_singleton;
|
||||||
|
ProjectSettings::get_singleton()->add_autoload(prop_info);
|
||||||
|
|
||||||
if (!info->in_editor && !info->is_singleton) {
|
if (!info->in_editor && !info->is_singleton) {
|
||||||
// No reason to keep this node
|
// No reason to keep this node
|
||||||
memdelete(info->node);
|
memdelete(info->node);
|
||||||
|
|
|
@ -343,16 +343,11 @@ void ScriptTextEditor::_set_theme_for_script() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//colorize singleton autoloads (as types, just as engine singletons are)
|
//colorize singleton autoloads (as types, just as engine singletons are)
|
||||||
List<PropertyInfo> props;
|
Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
|
||||||
ProjectSettings::get_singleton()->get_property_list(&props);
|
for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) {
|
||||||
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
|
const ProjectSettings::AutoloadInfo &info = E->value();
|
||||||
String s = E->get().name;
|
if (info.is_singleton) {
|
||||||
if (!s.begins_with("autoload/")) {
|
text_edit->add_keyword_color(info.name, colors_cache.usertype_color);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String path = ProjectSettings::get_singleton()->get(s);
|
|
||||||
if (path.begins_with("*")) {
|
|
||||||
text_edit->add_keyword_color(s.get_slice("/", 1), colors_cache.usertype_color);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,12 +937,11 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
|
||||||
emit_signal("go_to_help", "class_global:" + result.class_name + ":" + result.class_member);
|
emit_signal("go_to_help", "class_global:" + result.class_name + ":" + result.class_member);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
} else if (ProjectSettings::get_singleton()->has_setting("autoload/" + p_symbol)) {
|
} else if (ProjectSettings::get_singleton()->has_autoload(p_symbol)) {
|
||||||
//check for Autoload scenes
|
// Check for Autoload scenes.
|
||||||
String path = ProjectSettings::get_singleton()->get("autoload/" + p_symbol);
|
const ProjectSettings::AutoloadInfo &info = ProjectSettings::get_singleton()->get_autoload(p_symbol);
|
||||||
if (path.begins_with("*")) {
|
if (info.is_singleton) {
|
||||||
path = path.substr(1, path.length());
|
EditorNode::get_singleton()->load_scene(info.path);
|
||||||
EditorNode::get_singleton()->load_scene(path);
|
|
||||||
}
|
}
|
||||||
} else if (p_symbol.is_rel_path()) {
|
} else if (p_symbol.is_rel_path()) {
|
||||||
// Every symbol other than absolute path is relative path so keep this condition at last.
|
// Every symbol other than absolute path is relative path so keep this condition at last.
|
||||||
|
@ -974,7 +968,7 @@ void ScriptTextEditor::_validate_symbol(const String &p_symbol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptLanguage::LookupResult result;
|
ScriptLanguage::LookupResult result;
|
||||||
if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK || ProjectSettings::get_singleton()->has_setting("autoload/" + p_symbol)) {
|
if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK || (ProjectSettings::get_singleton()->has_autoload(p_symbol) && ProjectSettings::get_singleton()->get_autoload(p_symbol).is_singleton)) {
|
||||||
text_edit->set_highlighted_word(p_symbol);
|
text_edit->set_highlighted_word(p_symbol);
|
||||||
} else if (p_symbol.is_rel_path()) {
|
} else if (p_symbol.is_rel_path()) {
|
||||||
String path = _get_absolute_path(p_symbol);
|
String path = _get_absolute_path(p_symbol);
|
||||||
|
|
|
@ -1792,46 +1792,26 @@ bool Main::start() {
|
||||||
if (!project_manager && !editor) { // game
|
if (!project_manager && !editor) { // game
|
||||||
if (game_path != "" || script != "") {
|
if (game_path != "" || script != "") {
|
||||||
//autoload
|
//autoload
|
||||||
List<PropertyInfo> props;
|
Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
|
||||||
ProjectSettings::get_singleton()->get_property_list(&props);
|
|
||||||
|
|
||||||
//first pass, add the constants so they exist before any script is loaded
|
//first pass, add the constants so they exist before any script is loaded
|
||||||
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
|
for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) {
|
||||||
String s = E->get().name;
|
const ProjectSettings::AutoloadInfo &info = E->get();
|
||||||
if (!s.begins_with("autoload/")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String name = s.get_slicec('/', 1);
|
|
||||||
String path = ProjectSettings::get_singleton()->get(s);
|
|
||||||
bool global_var = false;
|
|
||||||
if (path.begins_with("*")) {
|
|
||||||
global_var = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (global_var) {
|
if (info.is_singleton) {
|
||||||
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
|
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
|
||||||
ScriptServer::get_language(i)->add_global_constant(name, Variant());
|
ScriptServer::get_language(i)->add_global_constant(info.name, Variant());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//second pass, load into global constants
|
//second pass, load into global constants
|
||||||
List<Node *> to_add;
|
List<Node *> to_add;
|
||||||
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
|
for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) {
|
||||||
String s = E->get().name;
|
const ProjectSettings::AutoloadInfo &info = E->get();
|
||||||
if (!s.begins_with("autoload/")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String name = s.get_slicec('/', 1);
|
|
||||||
String path = ProjectSettings::get_singleton()->get(s);
|
|
||||||
bool global_var = false;
|
|
||||||
if (path.begins_with("*")) {
|
|
||||||
global_var = true;
|
|
||||||
path = path.substr(1, path.length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
RES res = ResourceLoader::load(path);
|
RES res = ResourceLoader::load(info.path);
|
||||||
ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + path);
|
ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path);
|
||||||
Node *n = nullptr;
|
Node *n = nullptr;
|
||||||
if (res->is_class("PackedScene")) {
|
if (res->is_class("PackedScene")) {
|
||||||
Ref<PackedScene> ps = res;
|
Ref<PackedScene> ps = res;
|
||||||
|
@ -1840,7 +1820,7 @@ bool Main::start() {
|
||||||
Ref<Script> script_res = res;
|
Ref<Script> script_res = res;
|
||||||
StringName ibt = script_res->get_instance_base_type();
|
StringName ibt = script_res->get_instance_base_type();
|
||||||
bool valid_type = ClassDB::is_parent_class(ibt, "Node");
|
bool valid_type = ClassDB::is_parent_class(ibt, "Node");
|
||||||
ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + path);
|
ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + info.path);
|
||||||
|
|
||||||
Object *obj = ClassDB::instance(ibt);
|
Object *obj = ClassDB::instance(ibt);
|
||||||
|
|
||||||
|
@ -1850,15 +1830,15 @@ bool Main::start() {
|
||||||
n->set_script(script_res);
|
n->set_script(script_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + path);
|
ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + info.path);
|
||||||
n->set_name(name);
|
n->set_name(info.name);
|
||||||
|
|
||||||
//defer so references are all valid on _ready()
|
//defer so references are all valid on _ready()
|
||||||
to_add.push_back(n);
|
to_add.push_back(n);
|
||||||
|
|
||||||
if (global_var) {
|
if (info.is_singleton) {
|
||||||
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
|
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
|
||||||
ScriptServer::get_language(i)->add_global_constant(name, n);
|
ScriptServer::get_language(i)->add_global_constant(info.name, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,16 +123,11 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
|
||||||
case CompletionKind::NODE_PATHS: {
|
case CompletionKind::NODE_PATHS: {
|
||||||
{
|
{
|
||||||
// AutoLoads
|
// AutoLoads
|
||||||
List<PropertyInfo> props;
|
Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
|
||||||
ProjectSettings::get_singleton()->get_property_list(&props);
|
|
||||||
|
|
||||||
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
|
for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) {
|
||||||
String s = E->get().name;
|
const ProjectSettings::AutoloadInfo &info = E->value();
|
||||||
if (!s.begins_with("autoload/")) {
|
suggestions.push_back(quoted("/root/" + String(info.name)));
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String name = s.get_slice("/", 1);
|
|
||||||
suggestions.push_back(quoted("/root/" + name));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue