Merge pull request #71687 from reduz/support-script-class-name-in-efs
Support script global resource name in EditorFileSystem
This commit is contained in:
commit
ebd0b40f6e
|
@ -91,7 +91,8 @@ enum {
|
|||
// Version 2: added 64 bits support for float and int.
|
||||
// Version 3: changed nodepath encoding.
|
||||
// Version 4: new string ID for ext/subresources, breaks forward compat.
|
||||
FORMAT_VERSION = 4,
|
||||
// Version 5: Ability to store script class in the header.
|
||||
FORMAT_VERSION = 5,
|
||||
FORMAT_VERSION_CAN_RENAME_DEPS = 1,
|
||||
FORMAT_VERSION_NO_NODEPATH_PROPERTY = 3,
|
||||
};
|
||||
|
@ -1009,6 +1010,10 @@ void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p
|
|||
uid = ResourceUID::INVALID_ID;
|
||||
}
|
||||
|
||||
if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) {
|
||||
script_class = get_unicode_string();
|
||||
}
|
||||
|
||||
for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) {
|
||||
f->get_32(); //skip a few reserved fields
|
||||
}
|
||||
|
@ -1113,6 +1118,57 @@ String ResourceLoaderBinary::recognize(Ref<FileAccess> p_f) {
|
|||
return get_unicode_string();
|
||||
}
|
||||
|
||||
String ResourceLoaderBinary::recognize_script_class(Ref<FileAccess> p_f) {
|
||||
error = OK;
|
||||
|
||||
f = p_f;
|
||||
uint8_t header[4];
|
||||
f->get_buffer(header, 4);
|
||||
if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
|
||||
// Compressed.
|
||||
Ref<FileAccessCompressed> fac;
|
||||
fac.instantiate();
|
||||
error = fac->open_after_magic(f);
|
||||
if (error != OK) {
|
||||
f.unref();
|
||||
return "";
|
||||
}
|
||||
f = fac;
|
||||
|
||||
} else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
|
||||
// Not normal.
|
||||
error = ERR_FILE_UNRECOGNIZED;
|
||||
f.unref();
|
||||
return "";
|
||||
}
|
||||
|
||||
bool big_endian = f->get_32();
|
||||
f->get_32(); // use_real64
|
||||
|
||||
f->set_big_endian(big_endian != 0); //read big endian if saved as big endian
|
||||
|
||||
uint32_t ver_major = f->get_32();
|
||||
f->get_32(); // ver_minor
|
||||
uint32_t ver_fmt = f->get_32();
|
||||
|
||||
if (ver_fmt > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
|
||||
f.unref();
|
||||
return "";
|
||||
}
|
||||
|
||||
get_unicode_string(); // type
|
||||
|
||||
f->get_64(); // Metadata offset
|
||||
uint32_t flags = f->get_32();
|
||||
f->get_64(); // UID
|
||||
|
||||
if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) {
|
||||
return get_unicode_string();
|
||||
} else {
|
||||
return String();
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Resource> ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
|
||||
if (r_error) {
|
||||
*r_error = ERR_FILE_CANT_OPEN;
|
||||
|
@ -1295,6 +1351,9 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
|
|||
|
||||
fw->store_32(flags);
|
||||
fw->store_64(uid_data);
|
||||
if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) {
|
||||
save_ustring(fw, get_ustring(f));
|
||||
}
|
||||
|
||||
for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) {
|
||||
fw->store_32(0); // reserved
|
||||
|
@ -1416,6 +1475,18 @@ String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const
|
|||
return ClassDB::get_compatibility_remapped_class(r);
|
||||
}
|
||||
|
||||
String ResourceFormatLoaderBinary::get_resource_script_class(const String &p_path) const {
|
||||
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (f.is_null()) {
|
||||
return ""; //could not read
|
||||
}
|
||||
|
||||
ResourceLoaderBinary loader;
|
||||
loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
|
||||
loader.res_path = loader.local_path;
|
||||
return loader.recognize_script_class(f);
|
||||
}
|
||||
|
||||
ResourceUID::ID ResourceFormatLoaderBinary::get_resource_uid(const String &p_path) const {
|
||||
String ext = p_path.get_extension().to_lower();
|
||||
if (!ClassDB::is_resource_extension(ext)) {
|
||||
|
@ -2033,15 +2104,31 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re
|
|||
|
||||
save_unicode_string(f, _resource_get_class(p_resource));
|
||||
f->store_64(0); //offset to import metadata
|
||||
|
||||
String script_class;
|
||||
{
|
||||
uint32_t format_flags = FORMAT_FLAG_NAMED_SCENE_IDS | FORMAT_FLAG_UIDS;
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
format_flags |= FORMAT_FLAG_REAL_T_IS_DOUBLE;
|
||||
#endif
|
||||
if (!p_resource->is_class("PackedScene")) {
|
||||
Ref<Script> s = p_resource->get_script();
|
||||
if (s.is_valid()) {
|
||||
script_class = s->get_global_name();
|
||||
if (!script_class.is_empty()) {
|
||||
format_flags |= ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f->store_32(format_flags);
|
||||
}
|
||||
ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(p_path, true);
|
||||
f->store_64(uid);
|
||||
if (!script_class.is_empty()) {
|
||||
save_unicode_string(f, script_class);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) {
|
||||
f->store_32(0); // reserved
|
||||
}
|
||||
|
@ -2294,6 +2381,10 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU
|
|||
fw->store_32(flags);
|
||||
fw->store_64(p_uid);
|
||||
|
||||
if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) {
|
||||
save_ustring(fw, get_ustring(f));
|
||||
}
|
||||
|
||||
//rest of file
|
||||
uint8_t b = f->get_8();
|
||||
while (!f->eof_reached()) {
|
||||
|
|
|
@ -65,6 +65,7 @@ class ResourceLoaderBinary {
|
|||
|
||||
bool using_named_scene_ids = false;
|
||||
bool using_uids = false;
|
||||
String script_class;
|
||||
bool use_sub_threads = false;
|
||||
float *progress = nullptr;
|
||||
Vector<ExtResource> external_resources;
|
||||
|
@ -99,6 +100,7 @@ public:
|
|||
void set_remaps(const HashMap<String, String> &p_remaps) { remaps = p_remaps; }
|
||||
void open(Ref<FileAccess> p_f, bool p_no_resources = false, bool p_keep_uuid_paths = false);
|
||||
String recognize(Ref<FileAccess> p_f);
|
||||
String recognize_script_class(Ref<FileAccess> p_f);
|
||||
void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types);
|
||||
void get_classes_used(Ref<FileAccess> p_f, HashSet<StringName> *p_classes);
|
||||
|
||||
|
@ -112,6 +114,7 @@ public:
|
|||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String &p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
virtual String get_resource_script_class(const String &p_path) const;
|
||||
virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes);
|
||||
virtual ResourceUID::ID get_resource_uid(const String &p_path) const;
|
||||
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
|
||||
|
@ -164,6 +167,7 @@ public:
|
|||
FORMAT_FLAG_NAMED_SCENE_IDS = 1,
|
||||
FORMAT_FLAG_UIDS = 2,
|
||||
FORMAT_FLAG_REAL_T_IS_DOUBLE = 4,
|
||||
FORMAT_FLAG_HAS_SCRIPT_CLASS = 8,
|
||||
|
||||
// Amount of reserved 32-bit fields in resource header
|
||||
RESERVED_FIELDS = 11
|
||||
|
|
|
@ -99,6 +99,12 @@ String ResourceFormatLoader::get_resource_type(const String &p_path) const {
|
|||
return ret;
|
||||
}
|
||||
|
||||
String ResourceFormatLoader::get_resource_script_class(const String &p_path) const {
|
||||
String ret;
|
||||
GDVIRTUAL_CALL(_get_resource_script_class, p_path, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) const {
|
||||
int64_t uid = ResourceUID::INVALID_ID;
|
||||
GDVIRTUAL_CALL(_get_resource_uid, p_path, uid);
|
||||
|
@ -184,6 +190,7 @@ void ResourceFormatLoader::_bind_methods() {
|
|||
GDVIRTUAL_BIND(_recognize_path, "path", "type");
|
||||
GDVIRTUAL_BIND(_handles_type, "type");
|
||||
GDVIRTUAL_BIND(_get_resource_type, "path");
|
||||
GDVIRTUAL_BIND(_get_resource_script_class, "path");
|
||||
GDVIRTUAL_BIND(_get_resource_uid, "path");
|
||||
GDVIRTUAL_BIND(_get_dependencies, "path", "add_types");
|
||||
GDVIRTUAL_BIND(_rename_dependencies, "path", "renames");
|
||||
|
@ -764,6 +771,19 @@ String ResourceLoader::get_resource_type(const String &p_path) {
|
|||
return "";
|
||||
}
|
||||
|
||||
String ResourceLoader::get_resource_script_class(const String &p_path) {
|
||||
String local_path = _validate_local_path(p_path);
|
||||
|
||||
for (int i = 0; i < loader_count; i++) {
|
||||
String result = loader[i]->get_resource_script_class(local_path);
|
||||
if (!result.is_empty()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
ResourceUID::ID ResourceLoader::get_resource_uid(const String &p_path) {
|
||||
String local_path = _validate_local_path(p_path);
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ protected:
|
|||
GDVIRTUAL2RC(bool, _recognize_path, String, StringName)
|
||||
GDVIRTUAL1RC(bool, _handles_type, StringName)
|
||||
GDVIRTUAL1RC(String, _get_resource_type, String)
|
||||
GDVIRTUAL1RC(String, _get_resource_script_class, String)
|
||||
GDVIRTUAL1RC(ResourceUID::ID, _get_resource_uid, String)
|
||||
GDVIRTUAL2RC(Vector<String>, _get_dependencies, String, bool)
|
||||
GDVIRTUAL1RC(Vector<String>, _get_classes_used, String)
|
||||
|
@ -71,6 +72,7 @@ public:
|
|||
virtual bool handles_type(const String &p_type) const;
|
||||
virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes);
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
virtual String get_resource_script_class(const String &p_path) const;
|
||||
virtual ResourceUID::ID get_resource_uid(const String &p_path) const;
|
||||
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
|
||||
virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map);
|
||||
|
@ -175,6 +177,7 @@ public:
|
|||
static void remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader);
|
||||
static void get_classes_used(const String &p_path, HashSet<StringName> *r_classes);
|
||||
static String get_resource_type(const String &p_path);
|
||||
static String get_resource_script_class(const String &p_path);
|
||||
static ResourceUID::ID get_resource_uid(const String &p_path);
|
||||
static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
|
||||
static Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map);
|
||||
|
|
|
@ -123,7 +123,7 @@ public:
|
|||
virtual bool can_instantiate() const = 0;
|
||||
|
||||
virtual Ref<Script> get_base_script() const = 0; //for script inheritance
|
||||
|
||||
virtual StringName get_global_name() const = 0;
|
||||
virtual bool inherits_script(const Ref<Script> &p_script) const = 0;
|
||||
|
||||
virtual StringName get_instance_base_type() const = 0; // this may not work in all scripts, will return empty if so
|
||||
|
|
|
@ -53,6 +53,7 @@ protected:
|
|||
public:
|
||||
EXBIND0RC(bool, can_instantiate)
|
||||
EXBIND0RC(Ref<Script>, get_base_script)
|
||||
EXBIND0RC(StringName, get_global_name)
|
||||
EXBIND1RC(bool, inherits_script, const Ref<Script> &)
|
||||
EXBIND0RC(StringName, get_instance_base_type)
|
||||
|
||||
|
|
|
@ -38,6 +38,13 @@
|
|||
Gets the list of extensions for files this loader is able to read.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_resource_script_class" qualifiers="virtual const">
|
||||
<return type="String" />
|
||||
<param index="0" name="path" type="String" />
|
||||
<description>
|
||||
Returns the script class name associated with the [Resource] under the given [param path]. If the resource has no script or the script isn't a named class, it should return [code]""[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_resource_type" qualifiers="virtual const">
|
||||
<return type="String" />
|
||||
<param index="0" name="path" type="String" />
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
EditorFileSystem *EditorFileSystem::singleton = nullptr;
|
||||
//the name is the version, to keep compatibility with different versions of Godot
|
||||
#define CACHE_FILE_NAME "filesystem_cache7"
|
||||
#define CACHE_FILE_NAME "filesystem_cache8"
|
||||
|
||||
void EditorFileSystemDirectory::sort_files() {
|
||||
files.sort_custom<FileInfoSort>();
|
||||
|
@ -169,6 +169,11 @@ StringName EditorFileSystemDirectory::get_file_type(int p_idx) const {
|
|||
return files[p_idx]->type;
|
||||
}
|
||||
|
||||
StringName EditorFileSystemDirectory::get_file_resource_script_class(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx, files.size(), "");
|
||||
return files[p_idx]->resource_script_class;
|
||||
}
|
||||
|
||||
String EditorFileSystemDirectory::get_name() {
|
||||
return name;
|
||||
}
|
||||
|
@ -266,6 +271,10 @@ void EditorFileSystem::_scan_filesystem() {
|
|||
|
||||
FileCache fc;
|
||||
fc.type = split[1];
|
||||
if (fc.type.find("/") != -1) {
|
||||
fc.type = fc.type.get_slice("/", 0);
|
||||
fc.resource_script_class = fc.type.get_slice("/", 1);
|
||||
}
|
||||
fc.uid = split[2].to_int();
|
||||
fc.modification_time = split[3].to_int();
|
||||
fc.import_modification_time = split[4].to_int();
|
||||
|
@ -854,6 +863,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAc
|
|||
|
||||
if (fc && fc->modification_time == mt && fc->import_modification_time == import_mt && !_test_for_reimport(path, true)) {
|
||||
fi->type = fc->type;
|
||||
fi->resource_script_class = fc->resource_script_class;
|
||||
fi->uid = fc->uid;
|
||||
fi->deps = fc->deps;
|
||||
fi->modified_time = fc->modification_time;
|
||||
|
@ -875,6 +885,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAc
|
|||
|
||||
if (fc->type.is_empty()) {
|
||||
fi->type = ResourceLoader::get_resource_type(path);
|
||||
fi->resource_script_class = ResourceLoader::get_resource_script_class(path);
|
||||
fi->import_group_file = ResourceLoader::get_import_group_file(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?)
|
||||
//note: I think this should not happen any longer..
|
||||
|
@ -904,6 +915,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAc
|
|||
if (fc && fc->modification_time == mt) {
|
||||
//not imported, so just update type if changed
|
||||
fi->type = fc->type;
|
||||
fi->resource_script_class = fc->resource_script_class;
|
||||
fi->uid = fc->uid;
|
||||
fi->modified_time = fc->modification_time;
|
||||
fi->deps = fc->deps;
|
||||
|
@ -915,6 +927,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAc
|
|||
} else {
|
||||
//new or modified time
|
||||
fi->type = ResourceLoader::get_resource_type(path);
|
||||
fi->resource_script_class = ResourceLoader::get_resource_script_class(path);
|
||||
if (fi->type == "" && textfile_extensions.has(ext)) {
|
||||
fi->type = "TextFile";
|
||||
}
|
||||
|
@ -1029,6 +1042,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->resource_script_class = ResourceLoader::get_resource_script_class(path);
|
||||
if (fi->type == "" && textfile_extensions.has(ext)) {
|
||||
fi->type = "TextFile";
|
||||
}
|
||||
|
@ -1285,7 +1299,12 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir,
|
|||
if (!p_dir->files[i]->import_group_file.is_empty()) {
|
||||
group_file_cache.insert(p_dir->files[i]->import_group_file);
|
||||
}
|
||||
String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->uid) + "::" + 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]->import_group_file + "::" + p_dir->files[i]->script_class_name + "<>" + p_dir->files[i]->script_class_extends + "<>" + p_dir->files[i]->script_class_icon_path;
|
||||
|
||||
String type = p_dir->files[i]->type;
|
||||
if (p_dir->files[i]->resource_script_class) {
|
||||
type += "/" + String(p_dir->files[i]->resource_script_class);
|
||||
}
|
||||
String s = p_dir->files[i]->file + "::" + type + "::" + itos(p_dir->files[i]->uid) + "::" + 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]->import_group_file + "::" + p_dir->files[i]->script_class_name + "<>" + p_dir->files[i]->script_class_extends + "<>" + p_dir->files[i]->script_class_icon_path;
|
||||
s += "::";
|
||||
for (int j = 0; j < p_dir->files[i]->deps.size(); j++) {
|
||||
if (j > 0) {
|
||||
|
@ -1612,6 +1631,8 @@ void EditorFileSystem::update_file(const String &p_file) {
|
|||
if (type.is_empty() && textfile_extensions.has(p_file.get_extension())) {
|
||||
type = "TextFile";
|
||||
}
|
||||
String script_class = ResourceLoader::get_resource_script_class(p_file);
|
||||
|
||||
ResourceUID::ID uid = ResourceLoader::get_resource_uid(p_file);
|
||||
|
||||
if (cpos == -1) {
|
||||
|
@ -1645,6 +1666,7 @@ void EditorFileSystem::update_file(const String &p_file) {
|
|||
}
|
||||
|
||||
fs->files[cpos]->type = type;
|
||||
fs->files[cpos]->resource_script_class = script_class;
|
||||
fs->files[cpos]->uid = uid;
|
||||
fs->files[cpos]->script_class_name = _get_global_script_class(type, p_file, &fs->files[cpos]->script_class_extends, &fs->files[cpos]->script_class_icon_path);
|
||||
fs->files[cpos]->import_group_file = ResourceLoader::get_import_group_file(p_file);
|
||||
|
|
|
@ -54,6 +54,7 @@ class EditorFileSystemDirectory : public Object {
|
|||
struct FileInfo {
|
||||
String file;
|
||||
StringName type;
|
||||
StringName resource_script_class; // If any resource has script with a global class name, its found here.
|
||||
ResourceUID::ID uid = ResourceUID::INVALID_ID;
|
||||
uint64_t modified_time = 0;
|
||||
uint64_t import_modified_time = 0;
|
||||
|
@ -61,6 +62,7 @@ class EditorFileSystemDirectory : public Object {
|
|||
String import_group_file;
|
||||
Vector<String> deps;
|
||||
bool verified = false; //used for checking changes
|
||||
// These are for script resources only.
|
||||
String script_class_name;
|
||||
String script_class_extends;
|
||||
String script_class_icon_path;
|
||||
|
@ -90,6 +92,7 @@ public:
|
|||
String get_file(int p_idx) const;
|
||||
String get_file_path(int p_idx) const;
|
||||
StringName get_file_type(int p_idx) const;
|
||||
StringName get_file_resource_script_class(int p_idx) const;
|
||||
Vector<String> get_file_deps(int p_idx) const;
|
||||
bool get_file_import_is_valid(int p_idx) const;
|
||||
uint64_t get_file_modified_time(int p_idx) const;
|
||||
|
@ -189,6 +192,7 @@ class EditorFileSystem : public Node {
|
|||
/* Used for reading the filesystem cache file */
|
||||
struct FileCache {
|
||||
String type;
|
||||
String resource_script_class;
|
||||
ResourceUID::ID uid = ResourceUID::INVALID_ID;
|
||||
uint64_t modification_time = 0;
|
||||
uint64_t import_modification_time = 0;
|
||||
|
|
|
@ -69,17 +69,9 @@ void EditorQuickOpen::_build_search_cache(EditorFileSystemDirectory *p_efsd) {
|
|||
for (int i = 0; i < p_efsd->get_file_count(); i++) {
|
||||
String file = p_efsd->get_file_path(i);
|
||||
String engine_type = p_efsd->get_file_type(i);
|
||||
// TODO: Fix lack of caching for resource's script's global class name (if applicable).
|
||||
String script_type;
|
||||
if (_load_resources) {
|
||||
Ref<Resource> res = ResourceLoader::load(file);
|
||||
if (res.is_valid()) {
|
||||
Ref<Script> scr = res->get_script();
|
||||
if (scr.is_valid()) {
|
||||
script_type = scr->get_language()->get_global_class_name(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String script_type = p_efsd->get_file_resource_script_class(i);
|
||||
|
||||
String actual_type = script_type.is_empty() ? engine_type : script_type;
|
||||
// Iterate all possible base types.
|
||||
for (String &parent_type : base_types) {
|
||||
|
|
|
@ -43,7 +43,6 @@ class EditorQuickOpen : public ConfirmationDialog {
|
|||
Tree *search_options = nullptr;
|
||||
String base_type;
|
||||
bool allow_multi_select = false;
|
||||
bool _load_resources = false; // Prohibitively slow for now.
|
||||
|
||||
Vector<String> files;
|
||||
OAHashMap<String, Ref<Texture2D>> icons;
|
||||
|
|
|
@ -248,6 +248,10 @@ Ref<Script> GDScript::get_base_script() const {
|
|||
}
|
||||
}
|
||||
|
||||
StringName GDScript::get_global_name() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
StringName GDScript::get_instance_base_type() const {
|
||||
if (native.is_valid()) {
|
||||
return native->get_name();
|
||||
|
|
|
@ -228,6 +228,7 @@ public:
|
|||
virtual bool can_instantiate() const override;
|
||||
|
||||
virtual Ref<Script> get_base_script() const override;
|
||||
virtual StringName get_global_name() const override;
|
||||
|
||||
virtual StringName get_instance_base_type() const override; // this may not work in all scripts, will return empty if so
|
||||
virtual ScriptInstance *instance_create(Object *p_this) override;
|
||||
|
|
|
@ -2606,6 +2606,10 @@ Ref<Script> CSharpScript::get_base_script() const {
|
|||
return base_script;
|
||||
}
|
||||
|
||||
StringName CSharpScript::get_global_name() const {
|
||||
return StringName();
|
||||
}
|
||||
|
||||
void CSharpScript::get_script_property_list(List<PropertyInfo> *r_list) const {
|
||||
#ifdef TOOLS_ENABLED
|
||||
const CSharpScript *top = this;
|
||||
|
|
|
@ -186,6 +186,8 @@ public:
|
|||
bool inherits_script(const Ref<Script> &p_script) const override;
|
||||
|
||||
Ref<Script> get_base_script() const override;
|
||||
StringName get_global_name() const override;
|
||||
|
||||
ScriptLanguage *get_language() const override;
|
||||
|
||||
void get_script_method_list(List<MethodInfo> *p_list) const override;
|
||||
|
|
|
@ -923,7 +923,11 @@ Error ResourceLoaderText::rename_dependencies(Ref<FileAccess> p_f, const String
|
|||
if (is_scene) {
|
||||
fw->store_line("[gd_scene load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + "]\n");
|
||||
} else {
|
||||
fw->store_line("[gd_resource type=\"" + res_type + "\" load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + "]\n");
|
||||
String script_res_text;
|
||||
if (!script_class.is_empty()) {
|
||||
script_res_text = "script_class=\"" + script_class + "\" ";
|
||||
}
|
||||
fw->store_line("[gd_resource type=\"" + res_type + "\" " + script_res_text + "load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + "]\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1047,6 +1051,10 @@ void ResourceLoaderText::open(Ref<FileAccess> p_f, bool p_skip_first_tag) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (tag.fields.has("script_class")) {
|
||||
script_class = tag.fields["script_class"];
|
||||
}
|
||||
|
||||
res_type = tag.fields["type"];
|
||||
|
||||
} else {
|
||||
|
@ -1493,6 +1501,44 @@ Error ResourceLoaderText::get_classes_used(HashSet<StringName> *r_classes) {
|
|||
return OK;
|
||||
}
|
||||
|
||||
String ResourceLoaderText::recognize_script_class(Ref<FileAccess> p_f) {
|
||||
error = OK;
|
||||
|
||||
lines = 1;
|
||||
f = p_f;
|
||||
|
||||
stream.f = f;
|
||||
|
||||
ignore_resource_parsing = true;
|
||||
|
||||
VariantParser::Tag tag;
|
||||
Error err = VariantParser::parse_tag(&stream, lines, error_text, tag);
|
||||
|
||||
if (err) {
|
||||
_printerr();
|
||||
return "";
|
||||
}
|
||||
|
||||
if (tag.fields.has("format")) {
|
||||
int fmt = tag.fields["format"];
|
||||
if (fmt > FORMAT_VERSION) {
|
||||
error_text = "Saved with newer format version";
|
||||
_printerr();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
if (tag.name != "gd_resource") {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (tag.fields.has("script_class")) {
|
||||
return tag.fields["script_class"];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
String ResourceLoaderText::recognize(Ref<FileAccess> p_f) {
|
||||
error = OK;
|
||||
|
||||
|
@ -1662,6 +1708,25 @@ String ResourceFormatLoaderText::get_resource_type(const String &p_path) const {
|
|||
return ClassDB::get_compatibility_remapped_class(r);
|
||||
}
|
||||
|
||||
String ResourceFormatLoaderText::get_resource_script_class(const String &p_path) const {
|
||||
String ext = p_path.get_extension().to_lower();
|
||||
if (ext != "tres") {
|
||||
return String();
|
||||
}
|
||||
|
||||
// ...for anything else must test...
|
||||
|
||||
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (f.is_null()) {
|
||||
return ""; //could not read
|
||||
}
|
||||
|
||||
ResourceLoaderText loader;
|
||||
loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
|
||||
loader.res_path = loader.local_path;
|
||||
return loader.recognize_script_class(f);
|
||||
}
|
||||
|
||||
ResourceUID::ID ResourceFormatLoaderText::get_resource_uid(const String &p_path) const {
|
||||
String ext = p_path.get_extension().to_lower();
|
||||
|
||||
|
@ -1905,7 +1970,12 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
|
|||
String title = packed_scene.is_valid() ? "[gd_scene " : "[gd_resource ";
|
||||
if (packed_scene.is_null()) {
|
||||
title += "type=\"" + _resource_get_class(p_resource) + "\" ";
|
||||
Ref<Script> script = p_resource->get_script();
|
||||
if (script.is_valid() && script->get_global_name()) {
|
||||
title += "script_class=\"" + String(script->get_global_name()) + "\" ";
|
||||
}
|
||||
}
|
||||
|
||||
int load_steps = saved_resources.size() + external_resources.size();
|
||||
|
||||
if (load_steps > 1) {
|
||||
|
@ -2244,7 +2314,12 @@ Error ResourceLoaderText::set_uid(Ref<FileAccess> p_f, ResourceUID::ID p_uid) {
|
|||
if (is_scene) {
|
||||
fw->store_string("[gd_scene load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + " uid=\"" + ResourceUID::get_singleton()->id_to_text(p_uid) + "\"]");
|
||||
} else {
|
||||
fw->store_string("[gd_resource type=\"" + res_type + "\" load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + " uid=\"" + ResourceUID::get_singleton()->id_to_text(p_uid) + "\"]");
|
||||
String script_res_text;
|
||||
if (!script_class.is_empty()) {
|
||||
script_res_text = "script_class=\"" + script_class + "\" ";
|
||||
}
|
||||
|
||||
fw->store_string("[gd_resource type=\"" + res_type + "\" " + script_res_text + "load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + " uid=\"" + ResourceUID::get_singleton()->id_to_text(p_uid) + "\"]");
|
||||
}
|
||||
|
||||
uint8_t c = f->get_8();
|
||||
|
|
|
@ -64,6 +64,7 @@ class ResourceLoaderText {
|
|||
int resources_total = 0;
|
||||
int resource_current = 0;
|
||||
String resource_type;
|
||||
String script_class;
|
||||
|
||||
VariantParser::Tag next_tag;
|
||||
|
||||
|
@ -124,6 +125,7 @@ public:
|
|||
|
||||
void open(Ref<FileAccess> p_f, bool p_skip_first_tag = false);
|
||||
String recognize(Ref<FileAccess> p_f);
|
||||
String recognize_script_class(Ref<FileAccess> p_f);
|
||||
ResourceUID::ID get_uid(Ref<FileAccess> p_f);
|
||||
void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types);
|
||||
Error rename_dependencies(Ref<FileAccess> p_f, const String &p_path, const HashMap<String, String> &p_map);
|
||||
|
@ -143,6 +145,7 @@ public:
|
|||
virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes);
|
||||
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
virtual String get_resource_script_class(const String &p_path) const;
|
||||
virtual ResourceUID::ID get_resource_uid(const String &p_path) const;
|
||||
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
|
||||
virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map);
|
||||
|
|
Loading…
Reference in New Issue