summaryrefslogtreecommitdiffstats
path: root/core/io
diff options
context:
space:
mode:
Diffstat (limited to 'core/io')
-rw-r--r--core/io/SCsub1
-rw-r--r--core/io/file_access_pack.cpp16
-rw-r--r--core/io/file_access_pack.h3
-rw-r--r--core/io/packet_peer.cpp2
-rw-r--r--core/io/pck_packer.cpp12
-rw-r--r--core/io/pck_packer.h4
-rw-r--r--core/io/resource.cpp52
-rw-r--r--core/io/resource.h6
-rw-r--r--core/io/resource_format_binary.cpp40
-rw-r--r--core/io/resource_importer.cpp2
-rw-r--r--core/io/resource_importer.h2
11 files changed, 94 insertions, 46 deletions
diff --git a/core/io/SCsub b/core/io/SCsub
index 19a6549225..ab81175894 100644
--- a/core/io/SCsub
+++ b/core/io/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index eec27ce0aa..1340382eaa 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -102,6 +102,22 @@ void PackedData::add_pack_source(PackSource *p_source) {
}
}
+uint8_t *PackedData::get_file_hash(const String &p_path) {
+ PathMD5 pmd5(p_path.md5_buffer());
+ HashMap<PathMD5, PackedFile, PathMD5>::Iterator E = files.find(pmd5);
+ if (!E || E->value.offset == 0) {
+ return nullptr;
+ }
+
+ return E->value.md5;
+}
+
+void PackedData::clear() {
+ files.clear();
+ _free_packed_dirs(root);
+ root = memnew(PackedDir);
+}
+
PackedData *PackedData::singleton = nullptr;
PackedData::PackedData() {
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 595a36bca4..57b7a5f87f 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -111,6 +111,7 @@ private:
public:
void add_pack_source(PackSource *p_source);
void add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted = false); // for PackSource
+ uint8_t *get_file_hash(const String &p_path);
void set_disabled(bool p_disabled) { disabled = p_disabled; }
_FORCE_INLINE_ bool is_disabled() const { return disabled; }
@@ -118,6 +119,8 @@ public:
static PackedData *get_singleton() { return singleton; }
Error add_pack(const String &p_path, bool p_replace_files, uint64_t p_offset);
+ void clear();
+
_FORCE_INLINE_ Ref<FileAccess> try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path);
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index 0329ace313..614f81c42a 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -299,7 +299,7 @@ Ref<StreamPeer> PacketPeerStream::get_stream_peer() const {
void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
ERR_FAIL_COND_MSG(p_max_size < 0, "Max size of input buffer size cannot be smaller than 0.");
- //warning may lose packets
+ // WARNING: May lose packets.
ERR_FAIL_COND_MSG(ring_buffer.data_left(), "Buffer in use, resizing would cause loss of data.");
ring_buffer.resize(nearest_shift(next_power_of_2(p_max_size + 4)) - 1);
input_buffer.resize(next_power_of_2(p_max_size + 4));
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index a7c715c318..93179d9a11 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -47,12 +47,12 @@ static int _get_pad(int p_alignment, int p_n) {
}
void PCKPacker::_bind_methods() {
- ClassDB::bind_method(D_METHOD("pck_start", "pck_name", "alignment", "key", "encrypt_directory"), &PCKPacker::pck_start, DEFVAL(32), DEFVAL("0000000000000000000000000000000000000000000000000000000000000000"), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("pck_start", "pck_path", "alignment", "key", "encrypt_directory"), &PCKPacker::pck_start, DEFVAL(32), DEFVAL("0000000000000000000000000000000000000000000000000000000000000000"), DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_file", "pck_path", "source_path", "encrypt"), &PCKPacker::add_file, DEFVAL(false));
ClassDB::bind_method(D_METHOD("flush", "verbose"), &PCKPacker::flush, DEFVAL(false));
}
-Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &p_key, bool p_encrypt_directory) {
+Error PCKPacker::pck_start(const String &p_pck_path, int p_alignment, const String &p_key, bool p_encrypt_directory) {
ERR_FAIL_COND_V_MSG((p_key.is_empty() || !p_key.is_valid_hex_number(false) || p_key.length() != 64), ERR_CANT_CREATE, "Invalid Encryption Key (must be 64 characters long).");
ERR_FAIL_COND_V_MSG(p_alignment <= 0, ERR_CANT_CREATE, "Invalid alignment, must be greater then 0.");
@@ -83,8 +83,8 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &
}
enc_dir = p_encrypt_directory;
- file = FileAccess::open(p_file, FileAccess::WRITE);
- ERR_FAIL_COND_V_MSG(file.is_null(), ERR_CANT_CREATE, "Can't open file to write: " + String(p_file) + ".");
+ file = FileAccess::open(p_pck_path, FileAccess::WRITE);
+ ERR_FAIL_COND_V_MSG(file.is_null(), ERR_CANT_CREATE, "Can't open file to write: " + String(p_pck_path) + ".");
alignment = p_alignment;
@@ -106,7 +106,7 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &
return OK;
}
-Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encrypt) {
+Error PCKPacker::add_file(const String &p_pck_path, const String &p_src, bool p_encrypt) {
ERR_FAIL_COND_V_MSG(file.is_null(), ERR_INVALID_PARAMETER, "File must be opened before use.");
Ref<FileAccess> f = FileAccess::open(p_src, FileAccess::READ);
@@ -117,7 +117,7 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encr
File pf;
// Simplify path here and on every 'files' access so that paths that have extra '/'
// symbols in them still match to the MD5 hash for the saved path.
- pf.path = p_file.simplify_path();
+ pf.path = p_pck_path.simplify_path();
pf.src_path = p_src;
pf.ofs = ofs;
pf.size = f->get_length();
diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h
index 8764fc90a0..5aac833532 100644
--- a/core/io/pck_packer.h
+++ b/core/io/pck_packer.h
@@ -58,8 +58,8 @@ class PCKPacker : public RefCounted {
Vector<File> files;
public:
- Error pck_start(const String &p_file, int p_alignment = 32, const String &p_key = "0000000000000000000000000000000000000000000000000000000000000000", bool p_encrypt_directory = false);
- Error add_file(const String &p_file, const String &p_src, bool p_encrypt = false);
+ Error pck_start(const String &p_pck_path, int p_alignment = 32, const String &p_key = "0000000000000000000000000000000000000000000000000000000000000000", bool p_encrypt_directory = false);
+ Error add_file(const String &p_pck_path, const String &p_src, bool p_encrypt = false);
Error flush(bool p_verbose = false);
PCKPacker() {}
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 6177cba6a4..0ff4fbe490 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -96,33 +96,45 @@ String Resource::get_path() const {
void Resource::set_path_cache(const String &p_path) {
path_cache = p_path;
+ GDVIRTUAL_CALL(_set_path_cache, p_path);
+}
+
+static thread_local RandomPCG unique_id_gen(0, RandomPCG::DEFAULT_INC);
+
+void Resource::seed_scene_unique_id(uint32_t p_seed) {
+ unique_id_gen.seed(p_seed);
}
String Resource::generate_scene_unique_id() {
// Generate a unique enough hash, but still user-readable.
// If it's not unique it does not matter because the saver will try again.
- OS::DateTime dt = OS::get_singleton()->get_datetime();
- uint32_t hash = hash_murmur3_one_32(OS::get_singleton()->get_ticks_usec());
- hash = hash_murmur3_one_32(dt.year, hash);
- hash = hash_murmur3_one_32(dt.month, hash);
- hash = hash_murmur3_one_32(dt.day, hash);
- hash = hash_murmur3_one_32(dt.hour, hash);
- hash = hash_murmur3_one_32(dt.minute, hash);
- hash = hash_murmur3_one_32(dt.second, hash);
- hash = hash_murmur3_one_32(Math::rand(), hash);
+ if (unique_id_gen.get_seed() == 0) {
+ OS::DateTime dt = OS::get_singleton()->get_datetime();
+ uint32_t hash = hash_murmur3_one_32(OS::get_singleton()->get_ticks_usec());
+ hash = hash_murmur3_one_32(dt.year, hash);
+ hash = hash_murmur3_one_32(dt.month, hash);
+ hash = hash_murmur3_one_32(dt.day, hash);
+ hash = hash_murmur3_one_32(dt.hour, hash);
+ hash = hash_murmur3_one_32(dt.minute, hash);
+ hash = hash_murmur3_one_32(dt.second, hash);
+ hash = hash_murmur3_one_32(Math::rand(), hash);
+ unique_id_gen.seed(hash);
+ }
+
+ uint32_t random_num = unique_id_gen.rand();
static constexpr uint32_t characters = 5;
static constexpr uint32_t char_count = ('z' - 'a');
static constexpr uint32_t base = char_count + ('9' - '0');
String id;
for (uint32_t i = 0; i < characters; i++) {
- uint32_t c = hash % base;
+ uint32_t c = random_num % base;
if (c < char_count) {
id += String::chr('a' + c);
} else {
id += String::chr('0' + (c - char_count));
}
- hash /= base;
+ random_num /= base;
}
return id;
@@ -188,6 +200,7 @@ void Resource::disconnect_changed(const Callable &p_callable) {
}
void Resource::reset_state() {
+ GDVIRTUAL_CALL(_reset_state);
}
Error Resource::copy_from(const Ref<Resource> &p_resource) {
@@ -495,9 +508,9 @@ void Resource::set_as_translation_remapped(bool p_remapped) {
}
}
-#ifdef TOOLS_ENABLED
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
void Resource::set_id_for_path(const String &p_path, const String &p_id) {
+#ifdef TOOLS_ENABLED
if (p_id.is_empty()) {
ResourceCache::path_cache_lock.write_lock();
ResourceCache::resource_path_cache[p_path].erase(get_path());
@@ -507,9 +520,11 @@ void Resource::set_id_for_path(const String &p_path, const String &p_id) {
ResourceCache::resource_path_cache[p_path][get_path()] = p_id;
ResourceCache::path_cache_lock.write_unlock();
}
+#endif
}
String Resource::get_id_for_path(const String &p_path) const {
+#ifdef TOOLS_ENABLED
ResourceCache::path_cache_lock.read_lock();
if (ResourceCache::resource_path_cache[p_path].has(get_path())) {
String result = ResourceCache::resource_path_cache[p_path][get_path()];
@@ -519,13 +534,16 @@ String Resource::get_id_for_path(const String &p_path) const {
ResourceCache::path_cache_lock.read_unlock();
return "";
}
-}
+#else
+ return "";
#endif
+}
void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_path", "path"), &Resource::_set_path);
ClassDB::bind_method(D_METHOD("take_over_path", "path"), &Resource::_take_over_path);
ClassDB::bind_method(D_METHOD("get_path"), &Resource::get_path);
+ ClassDB::bind_method(D_METHOD("set_path_cache", "path"), &Resource::set_path_cache);
ClassDB::bind_method(D_METHOD("set_name", "name"), &Resource::set_name);
ClassDB::bind_method(D_METHOD("get_name"), &Resource::get_name);
ClassDB::bind_method(D_METHOD("get_rid"), &Resource::get_rid);
@@ -533,6 +551,12 @@ void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_local_to_scene"), &Resource::is_local_to_scene);
ClassDB::bind_method(D_METHOD("get_local_scene"), &Resource::get_local_scene);
ClassDB::bind_method(D_METHOD("setup_local_to_scene"), &Resource::setup_local_to_scene);
+ ClassDB::bind_method(D_METHOD("reset_state"), &Resource::reset_state);
+
+ ClassDB::bind_method(D_METHOD("set_id_for_path", "path", "id"), &Resource::set_id_for_path);
+ ClassDB::bind_method(D_METHOD("get_id_for_path", "path"), &Resource::get_id_for_path);
+
+ ClassDB::bind_method(D_METHOD("is_built_in"), &Resource::is_built_in);
ClassDB::bind_static_method("Resource", D_METHOD("generate_scene_unique_id"), &Resource::generate_scene_unique_id);
ClassDB::bind_method(D_METHOD("set_scene_unique_id", "id"), &Resource::set_scene_unique_id);
@@ -552,6 +576,8 @@ void Resource::_bind_methods() {
GDVIRTUAL_BIND(_setup_local_to_scene);
GDVIRTUAL_BIND(_get_rid);
+ GDVIRTUAL_BIND(_reset_state);
+ GDVIRTUAL_BIND(_set_path_cache, "path");
}
Resource::Resource() :
diff --git a/core/io/resource.h b/core/io/resource.h
index 2c1a431255..015f7ad197 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -89,6 +89,9 @@ protected:
GDVIRTUAL0RC(RID, _get_rid);
+ GDVIRTUAL1C(_set_path_cache, String);
+ GDVIRTUAL0(_reset_state);
+
public:
static Node *(*_get_local_scene_func)(); //used by editor
static void (*_update_configuration_warning)(); //used by editor
@@ -111,6 +114,7 @@ public:
virtual void set_path_cache(const String &p_path); // Set raw path without involving resource cache.
_FORCE_INLINE_ bool is_built_in() const { return path_cache.is_empty() || path_cache.contains("::") || path_cache.begins_with("local://"); }
+ static void seed_scene_unique_id(uint32_t p_seed);
static String generate_scene_unique_id();
void set_scene_unique_id(const String &p_id);
String get_scene_unique_id() const;
@@ -144,11 +148,9 @@ public:
virtual RID get_rid() const; // some resources may offer conversion to RID
-#ifdef TOOLS_ENABLED
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
void set_id_for_path(const String &p_path, const String &p_id);
String get_id_for_path(const String &p_path) const;
-#endif
Resource();
~Resource();
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index b4826c356e..109999d612 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -845,29 +845,27 @@ Error ResourceLoaderBinary::load() {
}
}
- if (ClassDB::has_property(res->get_class_name(), name)) {
- if (value.get_type() == Variant::ARRAY) {
- Array set_array = value;
- bool is_get_valid = false;
- Variant get_value = res->get(name, &is_get_valid);
- if (is_get_valid && get_value.get_type() == Variant::ARRAY) {
- Array get_array = get_value;
- if (!set_array.is_same_typed(get_array)) {
- value = Array(set_array, get_array.get_typed_builtin(), get_array.get_typed_class_name(), get_array.get_typed_script());
- }
+ if (value.get_type() == Variant::ARRAY) {
+ Array set_array = value;
+ bool is_get_valid = false;
+ Variant get_value = res->get(name, &is_get_valid);
+ if (is_get_valid && get_value.get_type() == Variant::ARRAY) {
+ Array get_array = get_value;
+ if (!set_array.is_same_typed(get_array)) {
+ value = Array(set_array, get_array.get_typed_builtin(), get_array.get_typed_class_name(), get_array.get_typed_script());
}
}
+ }
- if (value.get_type() == Variant::DICTIONARY) {
- Dictionary set_dict = value;
- bool is_get_valid = false;
- Variant get_value = res->get(name, &is_get_valid);
- if (is_get_valid && get_value.get_type() == Variant::DICTIONARY) {
- Dictionary get_dict = get_value;
- if (!set_dict.is_same_typed(get_dict)) {
- value = Dictionary(set_dict, get_dict.get_typed_key_builtin(), get_dict.get_typed_key_class_name(), get_dict.get_typed_key_script(),
- get_dict.get_typed_value_builtin(), get_dict.get_typed_value_class_name(), get_dict.get_typed_value_script());
- }
+ if (value.get_type() == Variant::DICTIONARY) {
+ Dictionary set_dict = value;
+ bool is_get_valid = false;
+ Variant get_value = res->get(name, &is_get_valid);
+ if (is_get_valid && get_value.get_type() == Variant::DICTIONARY) {
+ Dictionary get_dict = get_value;
+ if (!set_dict.is_same_typed(get_dict)) {
+ value = Dictionary(set_dict, get_dict.get_typed_key_builtin(), get_dict.get_typed_key_class_name(), get_dict.get_typed_key_script(),
+ get_dict.get_typed_value_builtin(), get_dict.get_typed_value_class_name(), get_dict.get_typed_value_script());
}
}
}
@@ -2136,6 +2134,8 @@ static String _resource_get_class(Ref<Resource> p_resource) {
}
Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) {
+ Resource::seed_scene_unique_id(p_path.hash());
+
Error err;
Ref<FileAccess> f;
if (p_flags & ResourceSaver::FLAG_COMPRESS) {
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index a572dd562e..1ae50d2d0d 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -507,7 +507,7 @@ bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) con
for (int i = 0; i < importers.size(); i++) {
if (importers[i]->get_importer_name() == pat.importer) {
- if (!importers[i]->are_import_settings_valid(p_path)) { //importer thinks this is not valid
+ if (!importers[i]->are_import_settings_valid(p_path, pat.metadata)) { //importer thinks this is not valid
return false;
}
}
diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h
index 6ea5d0972a..221f38494b 100644
--- a/core/io/resource_importer.h
+++ b/core/io/resource_importer.h
@@ -153,7 +153,7 @@ public:
virtual void import_threaded_end() {}
virtual Error import_group_file(const String &p_group_file, const HashMap<String, HashMap<StringName, Variant>> &p_source_file_options, const HashMap<String, String> &p_base_paths) { return ERR_UNAVAILABLE; }
- virtual bool are_import_settings_valid(const String &p_path) const { return true; }
+ virtual bool are_import_settings_valid(const String &p_path, const Dictionary &p_meta) const { return true; }
virtual String get_import_settings_string() const { return String(); }
};