mirror of
https://github.com/godotengine/godot.git
synced 2025-10-20 00:13:30 +00:00
Support script global resource name in EditorFileSystem
* Works for binary and text files. * Makes EditorQuickOpen work with custom resources again. * Information is cached and easily accessible. Properly fixes #66179. Supersedes #66215 and supersedes #62417 **WARNING**: This required breaking backwards binary compatibility (.res and .scn files). Files saved after this PR is merged will no longer open in any earlier versions of Godot.
This commit is contained in:
parent
14fdd28de9
commit
dddd8d43f6
17 changed files with 250 additions and 18 deletions
|
@ -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,
|
||||
};
|
||||
|
@ -1013,6 +1014,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
|
||||
}
|
||||
|
@ -1117,6 +1122,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;
|
||||
|
@ -1299,6 +1355,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
|
||||
|
@ -1420,6 +1479,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)) {
|
||||
|
@ -2037,15 +2108,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
|
||||
}
|
||||
|
@ -2298,6 +2385,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()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue