Skip to content

Commit ff1f040

Browse files
committed
Add create_id_for_path() to ResourceUID
1 parent 06c71fb commit ff1f040

File tree

5 files changed

+40
-9
lines changed

5 files changed

+40
-9
lines changed

core/io/resource_uid.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "core/io/dir_access.h"
3636
#include "core/io/file_access.h"
3737
#include "core/io/resource_loader.h"
38+
#include "core/math/random_pcg.h"
3839

3940
// These constants are off by 1, causing the 'z' and '9' characters never to be used.
4041
// This cannot be fixed without breaking compatibility; see GH-83843.
@@ -121,10 +122,31 @@ ResourceUID::ID ResourceUID::create_id() {
121122
}
122123
}
123124

125+
ResourceUID::ID ResourceUID::create_id_for_path(const String &p_path) {
126+
ID id = INVALID_ID;
127+
RandomPCG rng;
128+
129+
const String project_name = GLOBAL_GET("application/config/name");
130+
rng.seed(project_name.hash64() * p_path.hash64() * FileAccess::get_md5(p_path).hash64());
131+
132+
while (true) {
133+
int64_t num1 = rng.rand();
134+
int64_t num2 = ((int64_t)rng.rand()) << 32;
135+
id = (num1 | num2) & 0x7FFFFFFFFFFFFFFF;
136+
137+
MutexLock lock(mutex);
138+
if (!unique_ids.has(id)) {
139+
break;
140+
}
141+
}
142+
return id;
143+
}
144+
124145
bool ResourceUID::has_id(ID p_id) const {
125146
MutexLock l(mutex);
126147
return unique_ids.has(p_id);
127148
}
149+
128150
void ResourceUID::add_id(ID p_id, const String &p_path) {
129151
MutexLock l(mutex);
130152
ERR_FAIL_COND(unique_ids.has(p_id));
@@ -327,6 +349,7 @@ void ResourceUID::_bind_methods() {
327349
ClassDB::bind_method(D_METHOD("text_to_id", "text_id"), &ResourceUID::text_to_id);
328350

329351
ClassDB::bind_method(D_METHOD("create_id"), &ResourceUID::create_id);
352+
ClassDB::bind_method(D_METHOD("create_id_for_path", "path"), &ResourceUID::create_id_for_path);
330353

331354
ClassDB::bind_method(D_METHOD("has_id", "id"), &ResourceUID::has_id);
332355
ClassDB::bind_method(D_METHOD("add_id", "id", "path"), &ResourceUID::add_id);

core/io/resource_uid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class ResourceUID : public Object {
7070
ID text_to_id(const String &p_text) const;
7171

7272
ID create_id();
73+
ID create_id_for_path(const String &p_path);
7374
bool has_id(ID p_id) const;
7475
void add_id(ID p_id, const String &p_path);
7576
void set_id(ID p_id, const String &p_path);

doc/classes/ResourceUID.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@
2626
In order for this UID to be registered, you must call [method add_id] or [method set_id].
2727
</description>
2828
</method>
29+
<method name="create_id_for_path">
30+
<return type="int" />
31+
<param index="0" name="path" type="String" />
32+
<description>
33+
Like [method create_id], but the UID is seeded with the provided [param path] and project name. UIDs generated for that path will be always the same within the current project.
34+
</description>
35+
</method>
2936
<method name="get_id_path" qualifiers="const">
3037
<return type="String" />
3138
<param index="0" name="id" type="int" />

editor/editor_file_system.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ bool EditorFileSystem::_update_scan_actions() {
905905
if (existing_id != ResourceUID::INVALID_ID) {
906906
const String old_path = ResourceUID::get_singleton()->get_id_path(existing_id);
907907
if (old_path != new_file_path && FileAccess::exists(old_path)) {
908-
const ResourceUID::ID new_id = ResourceUID::get_singleton()->create_id();
908+
const ResourceUID::ID new_id = ResourceUID::get_singleton()->create_id_for_path(new_file_path);
909909
ResourceUID::get_singleton()->add_id(new_id, new_file_path);
910910
ResourceSaver::set_uid(new_file_path, new_id);
911911
WARN_PRINT(vformat("Duplicate UID detected for Resource at \"%s\".\nOld Resource path: \"%s\". The new file UID was changed automatically.", new_file_path, old_path));
@@ -916,7 +916,7 @@ bool EditorFileSystem::_update_scan_actions() {
916916
} else if (ResourceLoader::should_create_uid_file(new_file_path)) {
917917
Ref<FileAccess> f = FileAccess::open(new_file_path + ".uid", FileAccess::WRITE);
918918
if (f.is_valid()) {
919-
ia.new_file->uid = ResourceUID::get_singleton()->create_id();
919+
ia.new_file->uid = ResourceUID::get_singleton()->create_id_for_path(new_file_path);
920920
f->store_line(ResourceUID::get_singleton()->id_to_text(ia.new_file->uid));
921921
}
922922
}
@@ -1353,7 +1353,7 @@ void EditorFileSystem::_process_file_system(const ScannedDirectory *p_scan_dir,
13531353
Ref<FileAccess> f = FileAccess::open(path + ".uid", FileAccess::WRITE);
13541354
if (f.is_valid()) {
13551355
if (fi->uid == ResourceUID::INVALID_ID) {
1356-
fi->uid = ResourceUID::get_singleton()->create_id();
1356+
fi->uid = ResourceUID::get_singleton()->create_id_for_path(path);
13571357
} else {
13581358
WARN_PRINT(vformat("Missing .uid file for path \"%s\". The file was re-created from cache.", path));
13591359
}
@@ -2442,7 +2442,7 @@ void EditorFileSystem::update_files(const Vector<String> &p_script_paths) {
24422442
if (ResourceLoader::should_create_uid_file(file)) {
24432443
Ref<FileAccess> f = FileAccess::open(file + ".uid", FileAccess::WRITE);
24442444
if (f.is_valid()) {
2445-
const ResourceUID::ID id = ResourceUID::get_singleton()->create_id();
2445+
const ResourceUID::ID id = ResourceUID::get_singleton()->create_id_for_path(file);
24462446
ResourceUID::get_singleton()->add_id(id, file);
24472447
f->store_line(ResourceUID::get_singleton()->id_to_text(id));
24482448
fi->uid = id;
@@ -2630,7 +2630,7 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
26302630
}
26312631

26322632
if (uid == ResourceUID::INVALID_ID) {
2633-
uid = ResourceUID::get_singleton()->create_id();
2633+
uid = ResourceUID::get_singleton()->create_id_for_path(file);
26342634
}
26352635

26362636
f->store_line("uid=\"" + ResourceUID::get_singleton()->id_to_text(uid) + "\""); // Store in readable format.
@@ -2852,7 +2852,7 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap<Strin
28522852
}
28532853

28542854
if (uid == ResourceUID::INVALID_ID) {
2855-
uid = ResourceUID::get_singleton()->create_id();
2855+
uid = ResourceUID::get_singleton()->create_id_for_path(p_file);
28562856
}
28572857

28582858
//finally, perform import!!
@@ -3541,14 +3541,14 @@ ResourceUID::ID EditorFileSystem::_resource_saver_get_resource_id_for_path(const
35413541
}
35423542

35433543
if (p_generate) {
3544-
return ResourceUID::get_singleton()->create_id(); // Just create a new one, we will be notified of save anyway and fetch the right UID at that time, to keep things simple.
3544+
return ResourceUID::get_singleton()->create_id_for_path(p_path); // Just create a new one, we will be notified of save anyway and fetch the right UID at that time, to keep things simple.
35453545
} else {
35463546
return ResourceUID::INVALID_ID;
35473547
}
35483548
} else if (fs->files[cpos]->uid != ResourceUID::INVALID_ID) {
35493549
return fs->files[cpos]->uid;
35503550
} else if (p_generate) {
3551-
return ResourceUID::get_singleton()->create_id(); // Just create a new one, we will be notified of save anyway and fetch the right UID at that time, to keep things simple.
3551+
return ResourceUID::get_singleton()->create_id_for_path(p_path); // Just create a new one, we will be notified of save anyway and fetch the right UID at that time, to keep things simple.
35523552
} else {
35533553
return ResourceUID::INVALID_ID;
35543554
}

editor/import/3d/resource_importer_scene.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2930,7 +2930,7 @@ static Error convert_path_to_uid(ResourceUID::ID p_source_id, const String &p_ha
29302930
if (ResourceUID::get_singleton()->has_id(save_id)) {
29312931
if (save_path != ResourceUID::get_singleton()->get_id_path(save_id)) {
29322932
// The user has specified a path which does not match the default UID.
2933-
save_id = ResourceUID::get_singleton()->create_id();
2933+
save_id = ResourceUID::get_singleton()->create_id_for_path(save_path);
29342934
}
29352935
}
29362936
p_settings[p_path_key] = ResourceUID::get_singleton()->id_to_text(save_id);

0 commit comments

Comments
 (0)