summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2018-07-15 19:29:00 -0300
committerJuan Linietsky <reduzio@gmail.com>2018-07-15 19:29:00 -0300
commita3f1ee5c57d7818eaa30c272dd97d1bbb06ca099 (patch)
treed35d396e515ce20df6b76cc3c461cd7d1ba4cbfb /editor
parentf6ce73f7245fe9cc06d942ac4c8cec44a7252c5c (diff)
Global class names (and GDScript support for it)
Diffstat (limited to 'editor')
-rw-r--r--editor/create_dialog.cpp49
-rw-r--r--editor/editor_file_system.cpp104
-rw-r--r--editor/editor_file_system.h14
-rw-r--r--editor/plugins/script_editor_plugin.cpp1
4 files changed, 161 insertions, 7 deletions
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index a8cbf52cd2..6b2a072e20 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -243,6 +243,18 @@ void CreateDialog::_update_search() {
_parse_fs(EditorFileSystem::get_singleton()->get_filesystem());
*/
+ List<StringName> global_classes;
+ ScriptServer::get_global_class_list(&global_classes);
+
+ Map<String, List<String> > global_class_map;
+ for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
+ String base = ScriptServer::get_global_class_base(E->get());
+ if (!global_class_map.has(base)) {
+ global_class_map[base] = List<String>();
+ }
+ global_class_map[base].push_back(E->get());
+ }
+
HashMap<String, TreeItem *> types;
TreeItem *root = search_options->create_item();
@@ -293,6 +305,32 @@ void CreateDialog::_update_search() {
add_type(I->get(), types, root, &to_select);
}
+ if (global_class_map.has(type) && ClassDB::is_parent_class(type, base_type)) {
+ for (List<String>::Element *J = global_class_map[type].front(); J; J = J->next()) {
+ bool show = search_box->get_text().is_subsequence_ofi(J->get());
+
+ if (!show)
+ continue;
+
+ if (!types.has(type))
+ add_type(type, types, root, &to_select);
+
+ TreeItem *ti;
+ if (types.has(type))
+ ti = types[type];
+ else
+ ti = search_options->get_root();
+
+ TreeItem *item = search_options->create_item(ti);
+ item->set_metadata(0, J->get());
+ item->set_text(0, J->get() + " (" + ScriptServer::get_global_class_path(J->get()).get_file() + ")");
+ item->set_icon(0, _get_editor_icon(type));
+ if (!to_select || J->get() == search_box->get_text()) {
+ to_select = item;
+ }
+ }
+ }
+
if (EditorNode::get_editor_data().get_custom_types().has(type) && ClassDB::is_parent_class(type, base_type)) {
//there are custom types based on this... cool.
@@ -444,6 +482,17 @@ Object *CreateDialog::instance_selected() {
custom = md;
if (custom != String()) {
+
+ if (ScriptServer::is_global_class(custom)) {
+ RES script = ResourceLoader::load(ScriptServer::get_global_class_path(custom));
+ ERR_FAIL_COND_V(!script.is_valid(), NULL);
+
+ Object *obj = ClassDB::instance(ScriptServer::get_global_class_base(custom));
+ ERR_FAIL_COND_V(!obj, NULL);
+
+ obj->set_script(script.get_ref_ptr());
+ return obj;
+ }
return EditorNode::get_editor_data().instance_custom_type(selected->get_text(0), custom);
} else {
return ClassDB::instance(selected->get_text(0));
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index d8ae1da72e..d8ab41fa05 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -125,6 +125,14 @@ bool EditorFileSystemDirectory::get_file_import_is_valid(int p_idx) const {
return files[p_idx]->import_valid;
}
+String EditorFileSystemDirectory::get_file_script_class_name(int p_idx) const {
+ return files[p_idx]->script_class_name;
+}
+
+String EditorFileSystemDirectory::get_file_script_class_extends(int p_idx) const {
+ return files[p_idx]->script_class_extends;
+}
+
StringName EditorFileSystemDirectory::get_file_type(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, files.size(), "");
@@ -149,6 +157,8 @@ void EditorFileSystemDirectory::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_file", "idx"), &EditorFileSystemDirectory::get_file);
ClassDB::bind_method(D_METHOD("get_file_path", "idx"), &EditorFileSystemDirectory::get_file_path);
ClassDB::bind_method(D_METHOD("get_file_type", "idx"), &EditorFileSystemDirectory::get_file_type);
+ ClassDB::bind_method(D_METHOD("get_file_script_class_name", "idx"), &EditorFileSystemDirectory::get_file_script_class_name);
+ ClassDB::bind_method(D_METHOD("get_file_script_class_extends", "idx"), &EditorFileSystemDirectory::get_file_script_class_extends);
ClassDB::bind_method(D_METHOD("get_file_import_is_valid", "idx"), &EditorFileSystemDirectory::get_file_import_is_valid);
ClassDB::bind_method(D_METHOD("get_name"), &EditorFileSystemDirectory::get_name);
ClassDB::bind_method(D_METHOD("get_path"), &EditorFileSystemDirectory::get_path);
@@ -189,7 +199,7 @@ void EditorFileSystem::_scan_filesystem() {
String project = ProjectSettings::get_singleton()->get_resource_path();
- String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache3");
+ String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache4");
FileAccess *f = FileAccess::open(fscache, FileAccess::READ);
if (f) {
@@ -209,7 +219,7 @@ void EditorFileSystem::_scan_filesystem() {
} else {
Vector<String> split = l.split("::");
- ERR_CONTINUE(split.size() != 6);
+ ERR_CONTINUE(split.size() != 7);
String name = split[0];
String file;
@@ -221,8 +231,10 @@ void EditorFileSystem::_scan_filesystem() {
fc.modification_time = split[2].to_int64();
fc.import_modification_time = split[3].to_int64();
fc.import_valid = split[4].to_int64() != 0;
+ fc.script_class_name = split[5].get_slice("<>", 0);
+ fc.script_class_extends = split[5].get_slice("<>", 1);
- String deps = split[5].strip_edges();
+ String deps = split[6].strip_edges();
if (deps.length()) {
Vector<String> dp = deps.split("<>");
for (int i = 0; i < dp.size(); i++) {
@@ -239,7 +251,7 @@ void EditorFileSystem::_scan_filesystem() {
memdelete(f);
}
- String update_cache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update3");
+ String update_cache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4");
if (FileAccess::exists(update_cache)) {
{
@@ -287,7 +299,7 @@ void EditorFileSystem::_scan_filesystem() {
}
void EditorFileSystem::_save_filesystem_cache() {
- String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache3");
+ String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache4");
FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE);
if (f == NULL) {
@@ -563,6 +575,7 @@ void EditorFileSystem::scan() {
scanning = false;
emit_signal("filesystem_changed");
emit_signal("sources_changed", sources_changed.size() > 0);
+ _queue_update_script_classes();
} else {
@@ -706,6 +719,9 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
fi->modified_time = fc->modification_time;
fi->import_modified_time = fc->import_modification_time;
fi->import_valid = fc->import_valid;
+ fi->script_class_name = fc->script_class_name;
+ fi->script_class_extends = fc->script_class_extends;
+
if (fc->type == String()) {
fi->type = ResourceLoader::get_resource_type(path);
//there is also the chance that file type changed due to reimport, must probably check this somehow here (or kind of note it for next time in another file?)
@@ -715,6 +731,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
} else {
fi->type = ResourceFormatImporter::get_singleton()->get_resource_type(path);
+ fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends);
fi->modified_time = 0;
fi->import_modified_time = 0;
fi->import_valid = ResourceLoader::is_import_valid(path);
@@ -734,9 +751,12 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
fi->deps = fc->deps;
fi->import_modified_time = 0;
fi->import_valid = true;
+ fi->script_class_name = fc->script_class_name;
+ fi->script_class_extends = fc->script_class_extends;
} else {
//new or modified time
fi->type = ResourceLoader::get_resource_type(path);
+ fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends);
fi->deps = _get_dependencies(path);
fi->modified_time = mt;
fi->import_modified_time = 0;
@@ -835,6 +855,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
fi->modified_time = FileAccess::get_modified_time(path);
fi->import_modified_time = 0;
fi->type = ResourceLoader::get_resource_type(path);
+ fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends);
fi->import_valid = ResourceLoader::is_import_valid(path);
{
@@ -1044,6 +1065,7 @@ void EditorFileSystem::_notification(int p_what) {
if (_update_scan_actions())
emit_signal("filesystem_changed");
emit_signal("sources_changed", sources_changed.size() > 0);
+ _queue_update_script_classes();
}
} else if (!scanning) {
@@ -1059,6 +1081,7 @@ void EditorFileSystem::_notification(int p_what) {
_update_scan_actions();
emit_signal("filesystem_changed");
emit_signal("sources_changed", sources_changed.size() > 0);
+ _queue_update_script_classes();
}
}
} break;
@@ -1087,7 +1110,7 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir,
for (int i = 0; i < p_dir->files.size(); i++) {
- String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid);
+ String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid) + "::" + p_dir->files[i]->script_class_name + "<>" + p_dir->files[i]->script_class_extends;
s += "::";
for (int j = 0; j < p_dir->files[i]->deps.size(); j++) {
@@ -1268,7 +1291,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p
void EditorFileSystem::_save_late_updated_files() {
//files that already existed, and were modified, need re-scanning for dependencies upon project restart. This is done via saving this special file
- String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update3");
+ String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4");
FileAccessRef f = FileAccess::open(fscache, FileAccess::WRITE);
for (Set<String>::Element *E = late_update_files.front(); E; E = E->next()) {
f->store_line(E->get());
@@ -1293,6 +1316,67 @@ Vector<String> EditorFileSystem::_get_dependencies(const String &p_path) {
return ret;
}
+String EditorFileSystem::_get_global_script_class(const String &p_type, const String &p_path, String *r_extends) const {
+
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ if (ScriptServer::get_language(i)->handles_global_class_type(p_type)) {
+ String global_name;
+ String extends;
+
+ global_name = ScriptServer::get_language(i)->get_global_class_name(p_path, &extends);
+ *r_extends = extends;
+ return global_name;
+ }
+ }
+ *r_extends = String();
+ return String();
+}
+
+void EditorFileSystem::_scan_script_classes(EditorFileSystemDirectory *p_dir) {
+ int filecount = p_dir->files.size();
+ const EditorFileSystemDirectory::FileInfo *const *files = p_dir->files.ptr();
+ for (int i = 0; i < filecount; i++) {
+ if (files[i]->script_class_name == String()) {
+ continue;
+ }
+
+ String lang;
+ for (int j = 0; j < ScriptServer::get_language_count(); j++) {
+ if (ScriptServer::get_language(j)->handles_global_class_type(files[i]->type)) {
+ lang = ScriptServer::get_language(j)->get_name();
+ }
+ }
+
+ ScriptServer::add_global_class(files[i]->script_class_name, files[i]->script_class_extends, lang, p_dir->get_file_path(i));
+ }
+ for (int i = 0; i < p_dir->get_subdir_count(); i++) {
+ _scan_script_classes(p_dir->get_subdir(i));
+ }
+}
+
+void EditorFileSystem::update_script_classes() {
+
+ if (!update_script_classes_queued)
+ return;
+
+ update_script_classes_queued = false;
+ ScriptServer::global_classes_clear();
+ if (get_filesystem()) {
+ _scan_script_classes(get_filesystem());
+ }
+
+ ScriptServer::save_global_classes();
+}
+
+void EditorFileSystem::_queue_update_script_classes() {
+ if (update_script_classes_queued) {
+ return;
+ }
+
+ update_script_classes_queued = true;
+ call_deferred("update_script_classes");
+}
+
void EditorFileSystem::update_file(const String &p_file) {
EditorFileSystemDirectory *fs = NULL;
@@ -1311,7 +1395,9 @@ void EditorFileSystem::update_file(const String &p_file) {
memdelete(fs->files[cpos]);
fs->files.remove(cpos);
}
+
call_deferred("emit_signal", "filesystem_changed"); //update later
+ _queue_update_script_classes();
return;
}
@@ -1351,6 +1437,7 @@ void EditorFileSystem::update_file(const String &p_file) {
}
fs->files[cpos]->type = type;
+ fs->files[cpos]->script_class_name = _get_global_script_class(type, p_file, &fs->files[cpos]->script_class_extends);
fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
fs->files[cpos]->deps = _get_dependencies(p_file);
fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file);
@@ -1359,6 +1446,7 @@ void EditorFileSystem::update_file(const String &p_file) {
EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
call_deferred("emit_signal", "filesystem_changed"); //update later
+ _queue_update_script_classes();
}
void EditorFileSystem::_reimport_file(const String &p_file) {
@@ -1611,6 +1699,7 @@ void EditorFileSystem::_bind_methods() {
ClassDB::bind_method(D_METHOD("update_file", "path"), &EditorFileSystem::update_file);
ClassDB::bind_method(D_METHOD("get_filesystem_path", "path"), &EditorFileSystem::get_filesystem_path);
ClassDB::bind_method(D_METHOD("get_file_type", "path"), &EditorFileSystem::get_file_type);
+ ClassDB::bind_method(D_METHOD("update_script_classes"), &EditorFileSystem::update_script_classes);
ADD_SIGNAL(MethodInfo("filesystem_changed"));
ADD_SIGNAL(MethodInfo("sources_changed", PropertyInfo(Variant::BOOL, "exist")));
@@ -1664,6 +1753,7 @@ EditorFileSystem::EditorFileSystem() {
memdelete(da);
scan_total = 0;
+ update_script_classes_queued = false;
}
EditorFileSystem::~EditorFileSystem() {
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index a587d2879a..1aa35f4782 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -58,6 +58,8 @@ class EditorFileSystemDirectory : public Object {
bool import_valid;
Vector<String> deps;
bool verified; //used for checking changes
+ String script_class_name;
+ String script_class_extends;
};
struct FileInfoSort {
@@ -86,6 +88,8 @@ public:
StringName get_file_type(int p_idx) const;
Vector<String> get_file_deps(int p_idx) const;
bool get_file_import_is_valid(int p_idx) const;
+ String get_file_script_class_name(int p_idx) const; //used for scripts
+ String get_file_script_class_extends(int p_idx) const; //used for scripts
EditorFileSystemDirectory *get_parent();
@@ -157,6 +161,8 @@ class EditorFileSystem : public Node {
uint64_t import_modification_time;
Vector<String> deps;
bool import_valid;
+ String script_class_name;
+ String script_class_extends;
};
HashMap<String, FileCache> file_cache;
@@ -215,6 +221,12 @@ class EditorFileSystem : public Node {
}
};
+ void _scan_script_classes(EditorFileSystemDirectory *p_dir);
+ volatile bool update_script_classes_queued;
+ void _queue_update_script_classes();
+
+ String _get_global_script_class(const String &p_type, const String &p_path, String *r_extends) const;
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -237,6 +249,8 @@ public:
void reimport_files(const Vector<String> &p_files);
+ void update_script_classes();
+
EditorFileSystem();
~EditorFileSystem();
};
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index aa4673f41e..876da7f61a 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1872,6 +1872,7 @@ void ScriptEditor::save_all_scripts() {
}
_update_script_names();
+ EditorFileSystem::get_singleton()->update_script_classes();
}
void ScriptEditor::apply_scripts() const {