feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -42,6 +42,12 @@
|
|||
#include <brotli/decode.h>
|
||||
#endif
|
||||
|
||||
// Caches for zstd.
|
||||
static BinaryMutex mutex;
|
||||
static ZSTD_DCtx *current_zstd_d_ctx = nullptr;
|
||||
static bool current_zstd_long_distance_matching;
|
||||
static int current_zstd_window_log_size;
|
||||
|
||||
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) {
|
||||
switch (p_mode) {
|
||||
case MODE_BROTLI: {
|
||||
|
|
@ -187,12 +193,22 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
|
|||
return total;
|
||||
} break;
|
||||
case MODE_ZSTD: {
|
||||
ZSTD_DCtx *dctx = ZSTD_createDCtx();
|
||||
if (zstd_long_distance_matching) {
|
||||
ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, zstd_window_log_size);
|
||||
MutexLock lock(mutex);
|
||||
|
||||
if (!current_zstd_d_ctx || current_zstd_long_distance_matching != zstd_long_distance_matching || current_zstd_window_log_size != zstd_window_log_size) {
|
||||
if (current_zstd_d_ctx) {
|
||||
ZSTD_freeDCtx(current_zstd_d_ctx);
|
||||
}
|
||||
|
||||
current_zstd_d_ctx = ZSTD_createDCtx();
|
||||
if (zstd_long_distance_matching) {
|
||||
ZSTD_DCtx_setParameter(current_zstd_d_ctx, ZSTD_d_windowLogMax, zstd_window_log_size);
|
||||
}
|
||||
current_zstd_long_distance_matching = zstd_long_distance_matching;
|
||||
current_zstd_window_log_size = zstd_window_log_size;
|
||||
}
|
||||
int ret = ZSTD_decompressDCtx(dctx, p_dst, p_dst_max_size, p_src, p_src_size);
|
||||
ZSTD_freeDCtx(dctx);
|
||||
|
||||
int ret = ZSTD_decompressDCtx(current_zstd_d_ctx, p_dst, p_dst_max_size, p_src, p_src_size);
|
||||
return ret;
|
||||
} break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef COMPRESSION_H
|
||||
#define COMPRESSION_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/vector.h"
|
||||
#include "core/typedefs.h"
|
||||
|
|
@ -56,5 +55,3 @@ public:
|
|||
static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD);
|
||||
static int decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode);
|
||||
};
|
||||
|
||||
#endif // COMPRESSION_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CONFIG_FILE_H
|
||||
#define CONFIG_FILE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
|
@ -78,5 +77,3 @@ public:
|
|||
Error save_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
|
||||
Error save_encrypted_pass(const String &p_path, const String &p_pass);
|
||||
};
|
||||
|
||||
#endif // CONFIG_FILE_H
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ Error DirAccess::make_dir_recursive(const String &p_dir) {
|
|||
full_dir = p_dir;
|
||||
}
|
||||
|
||||
full_dir = full_dir.replace("\\", "/");
|
||||
full_dir = full_dir.replace_char('\\', '/');
|
||||
|
||||
String base;
|
||||
|
||||
|
|
@ -336,7 +336,7 @@ Ref<DirAccess> DirAccess::create_temp(const String &p_prefix, bool p_keep, Error
|
|||
uint32_t suffix_i = 0;
|
||||
String path;
|
||||
while (true) {
|
||||
String datetime = Time::get_singleton()->get_datetime_string_from_system().replace("-", "").replace("T", "").replace(":", "");
|
||||
String datetime = Time::get_singleton()->get_datetime_string_from_system().remove_chars("-T:");
|
||||
datetime += itos(Time::get_singleton()->get_ticks_usec());
|
||||
String suffix = datetime + (suffix_i > 0 ? itos(suffix_i) : "");
|
||||
path = (p_prefix.is_empty() ? "" : p_prefix + "-") + suffix;
|
||||
|
|
@ -626,6 +626,10 @@ bool DirAccess::is_case_sensitive(const String &p_path) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DirAccess::is_equivalent(const String &p_path_a, const String &p_path_b) const {
|
||||
return p_path_a == p_path_b;
|
||||
}
|
||||
|
||||
void DirAccess::_bind_methods() {
|
||||
ClassDB::bind_static_method("DirAccess", D_METHOD("open", "path"), &DirAccess::_open);
|
||||
ClassDB::bind_static_method("DirAccess", D_METHOD("get_open_error"), &DirAccess::get_open_error);
|
||||
|
|
@ -671,6 +675,7 @@ void DirAccess::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_include_hidden"), &DirAccess::get_include_hidden);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_case_sensitive", "path"), &DirAccess::is_case_sensitive);
|
||||
ClassDB::bind_method(D_METHOD("is_equivalent", "path_a", "path_b"), &DirAccess::is_equivalent);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_navigational"), "set_include_navigational", "get_include_navigational");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_hidden"), "set_include_hidden", "get_include_hidden");
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DIR_ACCESS_H
|
||||
#define DIR_ACCESS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/ref_counted.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
|
@ -169,10 +168,9 @@ public:
|
|||
|
||||
virtual bool is_case_sensitive(const String &p_path) const;
|
||||
virtual bool is_bundle(const String &p_file) const { return false; }
|
||||
virtual bool is_equivalent(const String &p_path_a, const String &p_path_b) const;
|
||||
|
||||
public:
|
||||
DirAccess() {}
|
||||
virtual ~DirAccess();
|
||||
};
|
||||
|
||||
#endif // DIR_ACCESS_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DTLS_SERVER_H
|
||||
#define DTLS_SERVER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/net_socket.h"
|
||||
#include "core/io/packet_peer_dtls.h"
|
||||
|
|
@ -53,5 +52,3 @@ public:
|
|||
|
||||
DTLSServer() {}
|
||||
};
|
||||
|
||||
#endif // DTLS_SERVER_H
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ Ref<FileAccess> FileAccess::create_temp(int p_mode_flags, const String &p_prefix
|
|||
uint32_t suffix_i = 0;
|
||||
String path;
|
||||
while (true) {
|
||||
String datetime = Time::get_singleton()->get_datetime_string_from_system().replace("-", "").replace("T", "").replace(":", "");
|
||||
String datetime = Time::get_singleton()->get_datetime_string_from_system().remove_chars("-T:");
|
||||
datetime += itos(Time::get_singleton()->get_ticks_usec());
|
||||
String suffix = datetime + (suffix_i > 0 ? itos(suffix_i) : "");
|
||||
path = TEMP_DIR.path_join((p_prefix.is_empty() ? "" : p_prefix + "-") + suffix + (extension.is_empty() ? "" : "." + extension));
|
||||
|
|
@ -259,7 +259,7 @@ FileAccess::AccessType FileAccess::get_access_type() const {
|
|||
String FileAccess::fix_path(const String &p_path) const {
|
||||
// Helper used by file accesses that use a single filesystem.
|
||||
|
||||
String r_path = p_path.replace("\\", "/");
|
||||
String r_path = p_path.replace_char('\\', '/');
|
||||
|
||||
switch (_access_type) {
|
||||
case ACCESS_RESOURCES: {
|
||||
|
|
@ -313,9 +313,15 @@ uint16_t FileAccess::get_16() const {
|
|||
uint16_t data = 0;
|
||||
get_buffer(reinterpret_cast<uint8_t *>(&data), sizeof(uint16_t));
|
||||
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
data = BSWAP16(data);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
data = BSWAP16(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
@ -324,9 +330,15 @@ uint32_t FileAccess::get_32() const {
|
|||
uint32_t data = 0;
|
||||
get_buffer(reinterpret_cast<uint8_t *>(&data), sizeof(uint32_t));
|
||||
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
data = BSWAP32(data);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
data = BSWAP32(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
@ -335,9 +347,15 @@ uint64_t FileAccess::get_64() const {
|
|||
uint64_t data = 0;
|
||||
get_buffer(reinterpret_cast<uint8_t *>(&data), sizeof(uint64_t));
|
||||
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
data = BSWAP64(data);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
data = BSWAP64(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
@ -429,7 +447,7 @@ class CharBuffer {
|
|||
public:
|
||||
_FORCE_INLINE_ CharBuffer() :
|
||||
buffer(stack_buffer),
|
||||
capacity(sizeof(stack_buffer) / sizeof(char)) {
|
||||
capacity(std::size(stack_buffer)) {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void push_back(char c) {
|
||||
|
|
@ -565,7 +583,7 @@ String FileAccess::get_as_utf8_string(bool p_skip_cr) const {
|
|||
w[len] = 0;
|
||||
|
||||
String s;
|
||||
s.parse_utf8((const char *)w, len, p_skip_cr);
|
||||
s.append_utf8((const char *)w, len, p_skip_cr);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
@ -574,25 +592,43 @@ bool FileAccess::store_8(uint8_t p_dest) {
|
|||
}
|
||||
|
||||
bool FileAccess::store_16(uint16_t p_dest) {
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
p_dest = BSWAP16(p_dest);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
p_dest = BSWAP16(p_dest);
|
||||
}
|
||||
#endif
|
||||
|
||||
return store_buffer(reinterpret_cast<uint8_t *>(&p_dest), sizeof(uint16_t));
|
||||
}
|
||||
|
||||
bool FileAccess::store_32(uint32_t p_dest) {
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
p_dest = BSWAP32(p_dest);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
p_dest = BSWAP32(p_dest);
|
||||
}
|
||||
#endif
|
||||
|
||||
return store_buffer(reinterpret_cast<uint8_t *>(&p_dest), sizeof(uint32_t));
|
||||
}
|
||||
|
||||
bool FileAccess::store_64(uint64_t p_dest) {
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
p_dest = BSWAP64(p_dest);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
p_dest = BSWAP64(p_dest);
|
||||
}
|
||||
#endif
|
||||
|
||||
return store_buffer(reinterpret_cast<uint8_t *>(&p_dest), sizeof(uint64_t));
|
||||
}
|
||||
|
|
@ -629,8 +665,29 @@ uint64_t FileAccess::get_modified_time(const String &p_file) {
|
|||
Ref<FileAccess> fa = create_for_path(p_file);
|
||||
ERR_FAIL_COND_V_MSG(fa.is_null(), 0, vformat("Cannot create FileAccess for path '%s'.", p_file));
|
||||
|
||||
uint64_t mt = fa->_get_modified_time(p_file);
|
||||
return mt;
|
||||
return fa->_get_modified_time(p_file);
|
||||
}
|
||||
|
||||
uint64_t FileAccess::get_access_time(const String &p_file) {
|
||||
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ref<FileAccess> fa = create_for_path(p_file);
|
||||
ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'.");
|
||||
|
||||
return fa->_get_access_time(p_file);
|
||||
}
|
||||
|
||||
int64_t FileAccess::get_size(const String &p_file) {
|
||||
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
|
||||
return PackedData::get_singleton()->get_size(p_file);
|
||||
}
|
||||
|
||||
Ref<FileAccess> fa = create_for_path(p_file);
|
||||
ERR_FAIL_COND_V_MSG(fa.is_null(), -1, "Cannot create FileAccess for path '" + p_file + "'.");
|
||||
|
||||
return fa->_get_size(p_file);
|
||||
}
|
||||
|
||||
BitField<FileAccess::UnixPermissionFlags> FileAccess::get_unix_permissions(const String &p_file) {
|
||||
|
|
@ -723,9 +780,7 @@ String FileAccess::get_pascal_string() {
|
|||
get_buffer((uint8_t *)cs.ptr(), sl);
|
||||
cs[sl] = 0;
|
||||
|
||||
String ret;
|
||||
ret.parse_utf8(cs.ptr(), sl);
|
||||
return ret;
|
||||
return String::utf8(cs.ptr(), sl);
|
||||
}
|
||||
|
||||
bool FileAccess::store_line(const String &p_line) {
|
||||
|
|
@ -817,7 +872,7 @@ String FileAccess::get_file_as_string(const String &p_path, Error *r_error) {
|
|||
}
|
||||
|
||||
String ret;
|
||||
ret.parse_utf8((const char *)array.ptr(), array.size());
|
||||
ret.append_utf8((const char *)array.ptr(), array.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -931,7 +986,7 @@ void FileAccess::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_float"), &FileAccess::get_float);
|
||||
ClassDB::bind_method(D_METHOD("get_double"), &FileAccess::get_double);
|
||||
ClassDB::bind_method(D_METHOD("get_real"), &FileAccess::get_real);
|
||||
ClassDB::bind_method(D_METHOD("get_buffer", "length"), (Vector<uint8_t>(FileAccess::*)(int64_t) const) & FileAccess::get_buffer);
|
||||
ClassDB::bind_method(D_METHOD("get_buffer", "length"), (Vector<uint8_t> (FileAccess::*)(int64_t) const) & FileAccess::get_buffer);
|
||||
ClassDB::bind_method(D_METHOD("get_line"), &FileAccess::get_line);
|
||||
ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &FileAccess::get_csv_line, DEFVAL(","));
|
||||
ClassDB::bind_method(D_METHOD("get_as_text", "skip_cr"), &FileAccess::get_as_text, DEFVAL(false));
|
||||
|
|
@ -950,7 +1005,7 @@ void FileAccess::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("store_float", "value"), &FileAccess::store_float);
|
||||
ClassDB::bind_method(D_METHOD("store_double", "value"), &FileAccess::store_double);
|
||||
ClassDB::bind_method(D_METHOD("store_real", "value"), &FileAccess::store_real);
|
||||
ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), (bool(FileAccess::*)(const Vector<uint8_t> &)) & FileAccess::store_buffer);
|
||||
ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), (bool (FileAccess::*)(const Vector<uint8_t> &))&FileAccess::store_buffer);
|
||||
ClassDB::bind_method(D_METHOD("store_line", "line"), &FileAccess::store_line);
|
||||
ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &FileAccess::store_csv_line, DEFVAL(","));
|
||||
ClassDB::bind_method(D_METHOD("store_string", "string"), &FileAccess::store_string);
|
||||
|
|
@ -963,6 +1018,8 @@ void FileAccess::_bind_methods() {
|
|||
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("file_exists", "path"), &FileAccess::exists);
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("get_modified_time", "file"), &FileAccess::get_modified_time);
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("get_access_time", "file"), &FileAccess::get_access_time);
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("get_size", "file"), &FileAccess::get_size);
|
||||
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("get_unix_permissions", "file"), &FileAccess::get_unix_permissions);
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("set_unix_permissions", "file", "permissions"), &FileAccess::set_unix_permissions);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_H
|
||||
#define FILE_ACCESS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/compression.h"
|
||||
#include "core/math/math_defs.h"
|
||||
|
|
@ -87,7 +86,11 @@ public:
|
|||
typedef void (*FileCloseFailNotify)(const String &);
|
||||
|
||||
typedef Ref<FileAccess> (*CreateFunc)();
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
bool big_endian = true;
|
||||
#else
|
||||
bool big_endian = false;
|
||||
#endif
|
||||
bool real_is_double = false;
|
||||
|
||||
virtual BitField<UnixPermissionFlags> _get_unix_permissions(const String &p_file) = 0;
|
||||
|
|
@ -105,6 +108,8 @@ protected:
|
|||
virtual String fix_path(const String &p_path) const;
|
||||
virtual Error open_internal(const String &p_path, int p_mode_flags) = 0; ///< open a file
|
||||
virtual uint64_t _get_modified_time(const String &p_file) = 0;
|
||||
virtual uint64_t _get_access_time(const String &p_file) = 0;
|
||||
virtual int64_t _get_size(const String &p_file) = 0;
|
||||
virtual void _set_access_type(AccessType p_access);
|
||||
|
||||
static FileCloseFailNotify close_fail_notify;
|
||||
|
|
@ -239,6 +244,8 @@ public:
|
|||
static CreateFunc get_create_func(AccessType p_access);
|
||||
static bool exists(const String &p_name); ///< return true if a file exists
|
||||
static uint64_t get_modified_time(const String &p_file);
|
||||
static uint64_t get_access_time(const String &p_file);
|
||||
static int64_t get_size(const String &p_file);
|
||||
static BitField<FileAccess::UnixPermissionFlags> get_unix_permissions(const String &p_file);
|
||||
static Error set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions);
|
||||
|
||||
|
|
@ -273,5 +280,3 @@ public:
|
|||
VARIANT_ENUM_CAST(FileAccess::CompressionMode);
|
||||
VARIANT_ENUM_CAST(FileAccess::ModeFlags);
|
||||
VARIANT_BITFIELD_CAST(FileAccess::UnixPermissionFlags);
|
||||
|
||||
#endif // FILE_ACCESS_H
|
||||
|
|
|
|||
|
|
@ -247,7 +247,11 @@ bool FileAccessCompressed::eof_reached() const {
|
|||
}
|
||||
|
||||
uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
|
||||
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
|
||||
if (p_length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ERR_FAIL_NULL_V(p_dst, -1);
|
||||
ERR_FAIL_COND_V_MSG(f.is_null(), -1, "File must be opened before use.");
|
||||
ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode.");
|
||||
|
||||
|
|
@ -256,29 +260,38 @@ uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) con
|
|||
return 0;
|
||||
}
|
||||
|
||||
for (uint64_t i = 0; i < p_length; i++) {
|
||||
p_dst[i] = read_ptr[read_pos];
|
||||
read_pos++;
|
||||
if (read_pos >= read_block_size) {
|
||||
read_block++;
|
||||
uint64_t dst_idx = 0;
|
||||
while (true) {
|
||||
// Copy over as much of our current block as possible.
|
||||
const uint32_t copied_bytes_count = MIN(p_length - dst_idx, read_block_size - read_pos);
|
||||
memcpy(p_dst + dst_idx, read_ptr + read_pos, copied_bytes_count);
|
||||
dst_idx += copied_bytes_count;
|
||||
read_pos += copied_bytes_count;
|
||||
|
||||
if (read_block < read_block_count) {
|
||||
//read another block of compressed data
|
||||
f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize);
|
||||
int ret = Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode);
|
||||
ERR_FAIL_COND_V_MSG(ret == -1, -1, "Compressed file is corrupt.");
|
||||
read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size;
|
||||
read_pos = 0;
|
||||
|
||||
} else {
|
||||
read_block--;
|
||||
at_end = true;
|
||||
if (i + 1 < p_length) {
|
||||
read_eof = true;
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
if (dst_idx == p_length) {
|
||||
// We're done! We read back all that was requested.
|
||||
return p_length;
|
||||
}
|
||||
|
||||
// We're not done yet; try reading the next block.
|
||||
read_block++;
|
||||
|
||||
if (read_block >= read_block_count) {
|
||||
// We're done! We read back the whole file.
|
||||
read_block--;
|
||||
at_end = true;
|
||||
if (dst_idx + 1 < p_length) {
|
||||
read_eof = true;
|
||||
}
|
||||
return dst_idx;
|
||||
}
|
||||
|
||||
// Read the next block of compressed data.
|
||||
f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize);
|
||||
int ret = Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode);
|
||||
ERR_FAIL_COND_V_MSG(ret == -1, -1, "Compressed file is corrupt.");
|
||||
read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size;
|
||||
read_pos = 0;
|
||||
}
|
||||
|
||||
return p_length;
|
||||
|
|
@ -332,6 +345,22 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t FileAccessCompressed::_get_access_time(const String &p_file) {
|
||||
if (f.is_valid()) {
|
||||
return f->get_access_time(p_file);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t FileAccessCompressed::_get_size(const String &p_file) {
|
||||
if (f.is_valid()) {
|
||||
return f->get_size(p_file);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
BitField<FileAccess::UnixPermissionFlags> FileAccessCompressed::_get_unix_permissions(const String &p_file) {
|
||||
if (f.is_valid()) {
|
||||
return f->_get_unix_permissions(p_file);
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_COMPRESSED_H
|
||||
#define FILE_ACCESS_COMPRESSED_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/compression.h"
|
||||
#include "core/io/file_access.h"
|
||||
|
||||
class FileAccessCompressed : public FileAccess {
|
||||
GDSOFTCLASS(FileAccessCompressed, FileAccess);
|
||||
Compression::Mode cmode = Compression::MODE_ZSTD;
|
||||
bool writing = false;
|
||||
uint64_t write_pos = 0;
|
||||
|
|
@ -94,6 +94,8 @@ public:
|
|||
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
|
||||
|
||||
virtual uint64_t _get_modified_time(const String &p_file) override;
|
||||
virtual uint64_t _get_access_time(const String &p_file) override;
|
||||
virtual int64_t _get_size(const String &p_file) override;
|
||||
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
|
||||
|
||||
|
|
@ -107,5 +109,3 @@ public:
|
|||
FileAccessCompressed() {}
|
||||
virtual ~FileAccessCompressed();
|
||||
};
|
||||
|
||||
#endif // FILE_ACCESS_COMPRESSED_H
|
||||
|
|
|
|||
|
|
@ -30,9 +30,17 @@
|
|||
|
||||
#include "file_access_encrypted.h"
|
||||
|
||||
#include "core/crypto/crypto_core.h"
|
||||
#include "core/variant/variant.h"
|
||||
|
||||
CryptoCore::RandomGenerator *FileAccessEncrypted::_fae_static_rng = nullptr;
|
||||
|
||||
void FileAccessEncrypted::deinitialize() {
|
||||
if (_fae_static_rng) {
|
||||
memdelete(_fae_static_rng);
|
||||
_fae_static_rng = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic, const Vector<uint8_t> &p_iv) {
|
||||
ERR_FAIL_COND_V_MSG(file.is_valid(), ERR_ALREADY_IN_USE, vformat("Can't open file while another file from path '%s' is open.", file->get_path_absolute()));
|
||||
ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
|
||||
|
|
@ -48,9 +56,15 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u
|
|||
key = p_key;
|
||||
if (p_iv.is_empty()) {
|
||||
iv.resize(16);
|
||||
CryptoCore::RandomGenerator rng;
|
||||
ERR_FAIL_COND_V_MSG(rng.init(), FAILED, "Failed to initialize random number generator.");
|
||||
Error err = rng.get_random_bytes(iv.ptrw(), 16);
|
||||
if (unlikely(!_fae_static_rng)) {
|
||||
_fae_static_rng = memnew(CryptoCore::RandomGenerator);
|
||||
if (_fae_static_rng->init() != OK) {
|
||||
memdelete(_fae_static_rng);
|
||||
_fae_static_rng = nullptr;
|
||||
ERR_FAIL_V_MSG(FAILED, "Failed to initialize random number generator.");
|
||||
}
|
||||
}
|
||||
Error err = _fae_static_rng->get_random_bytes(iv.ptrw(), 16);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
} else {
|
||||
ERR_FAIL_COND_V(p_iv.size() != 16, ERR_INVALID_PARAMETER);
|
||||
|
|
@ -265,7 +279,27 @@ bool FileAccessEncrypted::file_exists(const String &p_name) {
|
|||
}
|
||||
|
||||
uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
|
||||
return 0;
|
||||
if (file.is_valid()) {
|
||||
return file->get_modified_time(p_file);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t FileAccessEncrypted::_get_access_time(const String &p_file) {
|
||||
if (file.is_valid()) {
|
||||
return file->get_access_time(p_file);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t FileAccessEncrypted::_get_size(const String &p_file) {
|
||||
if (file.is_valid()) {
|
||||
return file->get_size(p_file);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
BitField<FileAccess::UnixPermissionFlags> FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
|
||||
|
|
|
|||
|
|
@ -28,14 +28,16 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_ENCRYPTED_H
|
||||
#define FILE_ACCESS_ENCRYPTED_H
|
||||
#pragma once
|
||||
|
||||
#include "core/crypto/crypto_core.h"
|
||||
#include "core/io/file_access.h"
|
||||
|
||||
#define ENCRYPTED_HEADER_MAGIC 0x43454447
|
||||
|
||||
class FileAccessEncrypted : public FileAccess {
|
||||
GDSOFTCLASS(FileAccessEncrypted, FileAccess);
|
||||
|
||||
public:
|
||||
enum Mode : int32_t {
|
||||
MODE_READ,
|
||||
|
|
@ -57,6 +59,8 @@ private:
|
|||
|
||||
void _close();
|
||||
|
||||
static CryptoCore::RandomGenerator *_fae_static_rng;
|
||||
|
||||
public:
|
||||
Error open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true, const Vector<uint8_t> &p_iv = Vector<uint8_t>());
|
||||
Error open_and_parse_password(Ref<FileAccess> p_base, const String &p_key, Mode p_mode);
|
||||
|
|
@ -87,6 +91,8 @@ public:
|
|||
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
|
||||
|
||||
virtual uint64_t _get_modified_time(const String &p_file) override;
|
||||
virtual uint64_t _get_access_time(const String &p_file) override;
|
||||
virtual int64_t _get_size(const String &p_file) override;
|
||||
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
|
||||
|
||||
|
|
@ -97,8 +103,8 @@ public:
|
|||
|
||||
virtual void close() override;
|
||||
|
||||
static void deinitialize();
|
||||
|
||||
FileAccessEncrypted() {}
|
||||
~FileAccessEncrypted();
|
||||
};
|
||||
|
||||
#endif // FILE_ACCESS_ENCRYPTED_H
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_MEMORY_H
|
||||
#define FILE_ACCESS_MEMORY_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
|
||||
class FileAccessMemory : public FileAccess {
|
||||
GDSOFTCLASS(FileAccessMemory, FileAccess);
|
||||
uint8_t *data = nullptr;
|
||||
uint64_t length = 0;
|
||||
mutable uint64_t pos = 0;
|
||||
|
|
@ -66,6 +66,9 @@ public:
|
|||
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
|
||||
|
||||
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
|
||||
virtual uint64_t _get_access_time(const String &p_file) override { return 0; }
|
||||
virtual int64_t _get_size(const String &p_file) override { return -1; }
|
||||
|
||||
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
|
||||
|
||||
|
|
@ -78,5 +81,3 @@ public:
|
|||
|
||||
FileAccessMemory() {}
|
||||
};
|
||||
|
||||
#endif // FILE_ACCESS_MEMORY_H
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
|
|||
f->get_32(); // patch number, not used for validation.
|
||||
|
||||
ERR_FAIL_COND_V_MSG(version != PACK_FORMAT_VERSION, false, vformat("Pack version unsupported: %d.", version));
|
||||
ERR_FAIL_COND_V_MSG(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false, vformat("Pack created with a newer version of the engine: %d.%d.", ver_major, ver_minor));
|
||||
ERR_FAIL_COND_V_MSG(ver_major > GODOT_VERSION_MAJOR || (ver_major == GODOT_VERSION_MAJOR && ver_minor > GODOT_VERSION_MINOR), false, vformat("Pack created with a newer version of the engine: %d.%d.", ver_major, ver_minor));
|
||||
|
||||
uint32_t pack_flags = f->get_32();
|
||||
uint64_t file_base = f->get_64();
|
||||
|
|
@ -306,9 +306,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
|
|||
f->get_buffer((uint8_t *)cs.ptr(), sl);
|
||||
cs[sl] = 0;
|
||||
|
||||
String path;
|
||||
path.parse_utf8(cs.ptr(), sl);
|
||||
|
||||
String path = String::utf8(cs.ptr(), sl);
|
||||
uint64_t ofs = f->get_64();
|
||||
uint64_t size = f->get_64();
|
||||
uint8_t md5[16];
|
||||
|
|
@ -550,7 +548,7 @@ String DirAccessPack::get_drive(int p_drive) {
|
|||
}
|
||||
|
||||
PackedData::PackedDir *DirAccessPack::_find_dir(const String &p_dir) {
|
||||
String nd = p_dir.replace("\\", "/");
|
||||
String nd = p_dir.replace_char('\\', '/');
|
||||
|
||||
// Special handling since simplify_path() will forbid it
|
||||
if (p_dir == "..") {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_PACK_H
|
||||
#define FILE_ACCESS_PACK_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/io/file_access.h"
|
||||
|
|
@ -127,6 +126,8 @@ public:
|
|||
_FORCE_INLINE_ Ref<FileAccess> try_open_path(const String &p_path);
|
||||
_FORCE_INLINE_ bool has_path(const String &p_path);
|
||||
|
||||
_FORCE_INLINE_ int64_t get_size(const String &p_path);
|
||||
|
||||
_FORCE_INLINE_ Ref<DirAccess> try_open_directory(const String &p_path);
|
||||
_FORCE_INLINE_ bool has_directory(const String &p_path);
|
||||
|
||||
|
|
@ -156,6 +157,7 @@ public:
|
|||
};
|
||||
|
||||
class FileAccessPack : public FileAccess {
|
||||
GDSOFTCLASS(FileAccessPack, FileAccess);
|
||||
PackedData::PackedFile pf;
|
||||
|
||||
mutable uint64_t pos;
|
||||
|
|
@ -165,6 +167,8 @@ class FileAccessPack : public FileAccess {
|
|||
Ref<FileAccess> f;
|
||||
virtual Error open_internal(const String &p_path, int p_mode_flags) override;
|
||||
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
|
||||
virtual uint64_t _get_access_time(const String &p_file) override { return 0; }
|
||||
virtual int64_t _get_size(const String &p_file) override { return -1; }
|
||||
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
|
||||
|
||||
|
|
@ -200,6 +204,19 @@ public:
|
|||
FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file);
|
||||
};
|
||||
|
||||
int64_t PackedData::get_size(const String &p_path) {
|
||||
String simplified_path = p_path.simplify_path();
|
||||
PathMD5 pmd5(simplified_path.md5_buffer());
|
||||
HashMap<PathMD5, PackedFile, PathMD5>::Iterator E = files.find(pmd5);
|
||||
if (!E) {
|
||||
return -1; // File not found.
|
||||
}
|
||||
if (E->value.offset == 0) {
|
||||
return -1; // File was erased.
|
||||
}
|
||||
return E->value.size;
|
||||
}
|
||||
|
||||
Ref<FileAccess> PackedData::try_open_path(const String &p_path) {
|
||||
String simplified_path = p_path.simplify_path().trim_prefix("res://");
|
||||
PathMD5 pmd5(simplified_path.md5_buffer());
|
||||
|
|
@ -225,6 +242,7 @@ bool PackedData::has_directory(const String &p_path) {
|
|||
}
|
||||
|
||||
class DirAccessPack : public DirAccess {
|
||||
GDSOFTCLASS(DirAccessPack, DirAccess);
|
||||
PackedData::PackedDir *current;
|
||||
|
||||
List<String> list_dirs;
|
||||
|
|
@ -272,5 +290,3 @@ Ref<DirAccess> PackedData::try_open_directory(const String &p_path) {
|
|||
}
|
||||
return da;
|
||||
}
|
||||
|
||||
#endif // FILE_ACCESS_PACK_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_ZIP_H
|
||||
#define FILE_ACCESS_ZIP_H
|
||||
#pragma once
|
||||
|
||||
#ifdef MINIZIP_ENABLED
|
||||
|
||||
|
|
@ -74,6 +73,7 @@ public:
|
|||
};
|
||||
|
||||
class FileAccessZip : public FileAccess {
|
||||
GDSOFTCLASS(FileAccessZip, FileAccess);
|
||||
unzFile zfile = nullptr;
|
||||
unz_file_info64 file_info;
|
||||
|
||||
|
|
@ -102,7 +102,9 @@ public:
|
|||
|
||||
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
|
||||
|
||||
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } // todo
|
||||
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
|
||||
virtual uint64_t _get_access_time(const String &p_file) override { return 0; }
|
||||
virtual int64_t _get_size(const String &p_file) override { return -1; }
|
||||
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
|
||||
|
||||
|
|
@ -118,5 +120,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // MINIZIP_ENABLED
|
||||
|
||||
#endif // FILE_ACCESS_ZIP_H
|
||||
|
|
|
|||
|
|
@ -70,10 +70,9 @@ Error HTTPClient::_request(Method p_method, const String &p_url, const Vector<St
|
|||
|
||||
String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
|
||||
String query = "";
|
||||
Array keys = p_dict.keys();
|
||||
for (int i = 0; i < keys.size(); ++i) {
|
||||
String encoded_key = String(keys[i]).uri_encode();
|
||||
const Variant &value = p_dict[keys[i]];
|
||||
for (const KeyValue<Variant, Variant> &kv : p_dict) {
|
||||
String encoded_key = String(kv.key).uri_encode();
|
||||
const Variant &value = kv.value;
|
||||
switch (value.get_type()) {
|
||||
case Variant::ARRAY: {
|
||||
// Repeat the key with every values
|
||||
|
|
@ -118,7 +117,7 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() {
|
|||
continue;
|
||||
}
|
||||
String key = s.substr(0, sp).strip_edges();
|
||||
String value = s.substr(sp + 1, s.length()).strip_edges();
|
||||
String value = s.substr(sp + 1).strip_edges();
|
||||
ret[key] = value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef HTTP_CLIENT_H
|
||||
#define HTTP_CLIENT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/crypto/crypto.h"
|
||||
#include "core/io/ip.h"
|
||||
|
|
@ -205,5 +204,3 @@ public:
|
|||
VARIANT_ENUM_CAST(HTTPClient::ResponseCode)
|
||||
VARIANT_ENUM_CAST(HTTPClient::Method);
|
||||
VARIANT_ENUM_CAST(HTTPClient::Status);
|
||||
|
||||
#endif // HTTP_CLIENT_H
|
||||
|
|
|
|||
|
|
@ -50,13 +50,13 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, Ref<TLSOp
|
|||
|
||||
String host_lower = conn_host.to_lower();
|
||||
if (host_lower.begins_with("http://")) {
|
||||
conn_host = conn_host.substr(7, conn_host.length() - 7);
|
||||
conn_host = conn_host.substr(7);
|
||||
tls_options.unref();
|
||||
} else if (host_lower.begins_with("https://")) {
|
||||
if (tls_options.is_null()) {
|
||||
tls_options = TLSOptions::client();
|
||||
}
|
||||
conn_host = conn_host.substr(8, conn_host.length() - 8);
|
||||
conn_host = conn_host.substr(8);
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(tls_options.is_valid() && tls_options->is_server(), ERR_INVALID_PARAMETER);
|
||||
|
|
@ -196,7 +196,7 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector<
|
|||
// Should it add utf8 encoding?
|
||||
}
|
||||
if (add_uagent) {
|
||||
request += "User-Agent: GodotEngine/" + String(VERSION_FULL_BUILD) + " (" + OS::get_singleton()->get_name() + ")\r\n";
|
||||
request += "User-Agent: GodotEngine/" + String(GODOT_VERSION_FULL_BUILD) + " (" + OS::get_singleton()->get_name() + ")\r\n";
|
||||
}
|
||||
if (add_accept) {
|
||||
request += "Accept: */*\r\n";
|
||||
|
|
@ -483,8 +483,7 @@ Error HTTPClientTCP::poll() {
|
|||
(rs >= 4 && response_str[rs - 4] == '\r' && response_str[rs - 3] == '\n' && response_str[rs - 2] == '\r' && response_str[rs - 1] == '\n')) {
|
||||
// End of response, parse.
|
||||
response_str.push_back(0);
|
||||
String response;
|
||||
response.parse_utf8((const char *)response_str.ptr(), response_str.size());
|
||||
String response = String::utf8((const char *)response_str.ptr(), response_str.size());
|
||||
Vector<String> responses = response.split("\n");
|
||||
body_size = -1;
|
||||
chunked = false;
|
||||
|
|
@ -508,11 +507,11 @@ Error HTTPClientTCP::poll() {
|
|||
continue;
|
||||
}
|
||||
if (s.begins_with("content-length:")) {
|
||||
body_size = s.substr(s.find_char(':') + 1, s.length()).strip_edges().to_int();
|
||||
body_size = s.substr(s.find_char(':') + 1).strip_edges().to_int();
|
||||
body_left = body_size;
|
||||
|
||||
} else if (s.begins_with("transfer-encoding:")) {
|
||||
String encoding = header.substr(header.find_char(':') + 1, header.length()).strip_edges();
|
||||
String encoding = header.substr(header.find_char(':') + 1).strip_edges();
|
||||
if (encoding == "chunked") {
|
||||
chunked = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef HTTP_CLIENT_TCP_H
|
||||
#define HTTP_CLIENT_TCP_H
|
||||
#pragma once
|
||||
|
||||
#include "http_client.h"
|
||||
|
||||
|
|
@ -100,5 +99,3 @@ public:
|
|||
void set_https_proxy(const String &p_host, int p_port) override;
|
||||
HTTPClientTCP();
|
||||
};
|
||||
|
||||
#endif // HTTP_CLIENT_TCP_H
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#include "image.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/error/error_list.h"
|
||||
#include "core/error/error_macros.h"
|
||||
#include "core/io/image_loader.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
|
|
@ -89,11 +88,13 @@ SavePNGFunc Image::save_png_func = nullptr;
|
|||
SaveJPGFunc Image::save_jpg_func = nullptr;
|
||||
SaveEXRFunc Image::save_exr_func = nullptr;
|
||||
SaveWebPFunc Image::save_webp_func = nullptr;
|
||||
SaveDDSFunc Image::save_dds_func = nullptr;
|
||||
|
||||
SavePNGBufferFunc Image::save_png_buffer_func = nullptr;
|
||||
SaveJPGBufferFunc Image::save_jpg_buffer_func = nullptr;
|
||||
SaveEXRBufferFunc Image::save_exr_buffer_func = nullptr;
|
||||
SaveWebPBufferFunc Image::save_webp_buffer_func = nullptr;
|
||||
SaveDDSBufferFunc Image::save_dds_buffer_func = nullptr;
|
||||
|
||||
// External loader function pointers.
|
||||
|
||||
|
|
@ -105,6 +106,7 @@ ImageMemLoadFunc Image::_tga_mem_loader_func = nullptr;
|
|||
ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr;
|
||||
ScalableImageMemLoadFunc Image::_svg_scalable_mem_loader_func = nullptr;
|
||||
ImageMemLoadFunc Image::_ktx_mem_loader_func = nullptr;
|
||||
ImageMemLoadFunc Image::_dds_mem_loader_func = nullptr;
|
||||
|
||||
// External VRAM compression function pointers.
|
||||
|
||||
|
|
@ -571,7 +573,7 @@ static bool _are_formats_compatible(Image::Format p_format0, Image::Format p_for
|
|||
void Image::convert(Format p_new_format) {
|
||||
ERR_FAIL_INDEX_MSG(p_new_format, FORMAT_MAX, vformat("The Image format specified (%d) is out of range. See Image's Format enum.", p_new_format));
|
||||
|
||||
if (data.size() == 0 || p_new_format == format) {
|
||||
if (data.is_empty() || p_new_format == format) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -796,7 +798,7 @@ Image::Format Image::get_format() const {
|
|||
}
|
||||
|
||||
static double _bicubic_interp_kernel(double x) {
|
||||
x = ABS(x);
|
||||
x = Math::abs(x);
|
||||
|
||||
double bc = 0;
|
||||
|
||||
|
|
@ -1139,7 +1141,7 @@ bool Image::is_size_po2() const {
|
|||
}
|
||||
|
||||
void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot resize in compressed image formats.");
|
||||
|
||||
int w = next_power_of_2(width);
|
||||
int h = next_power_of_2(height);
|
||||
|
|
@ -1158,7 +1160,7 @@ void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) {
|
|||
|
||||
void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
|
||||
ERR_FAIL_COND_MSG(data.is_empty(), "Cannot resize image before creating it, use set_data() first.");
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot resize in compressed image formats.");
|
||||
|
||||
bool mipmap_aware = p_interpolation == INTERPOLATE_TRILINEAR /* || p_interpolation == INTERPOLATE_TRICUBIC */;
|
||||
|
||||
|
|
@ -1461,8 +1463,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
|
|||
}
|
||||
|
||||
void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot crop in compressed or custom image formats.");
|
||||
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot crop in compressed image formats.");
|
||||
ERR_FAIL_COND_MSG(p_x < 0, "Start x position cannot be smaller than 0.");
|
||||
ERR_FAIL_COND_MSG(p_y < 0, "Start y position cannot be smaller than 0.");
|
||||
ERR_FAIL_COND_MSG(p_width <= 0, "Width of image must be greater than 0.");
|
||||
|
|
@ -1515,7 +1516,7 @@ void Image::crop(int p_width, int p_height) {
|
|||
}
|
||||
|
||||
void Image::rotate_90(ClockDirection p_direction) {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot rotate in compressed image formats.");
|
||||
ERR_FAIL_COND_MSG(width <= 0, vformat("The Image width specified (%d pixels) must be greater than 0 pixels.", width));
|
||||
ERR_FAIL_COND_MSG(height <= 0, vformat("The Image height specified (%d pixels) must be greater than 0 pixels.", height));
|
||||
|
||||
|
|
@ -1633,7 +1634,7 @@ void Image::rotate_90(ClockDirection p_direction) {
|
|||
}
|
||||
|
||||
void Image::rotate_180() {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot rotate in compressed image formats.");
|
||||
ERR_FAIL_COND_MSG(width <= 0, vformat("The Image width specified (%d pixels) must be greater than 0 pixels.", width));
|
||||
ERR_FAIL_COND_MSG(height <= 0, vformat("The Image height specified (%d pixels) must be greater than 0 pixels.", height));
|
||||
|
||||
|
|
@ -1667,7 +1668,7 @@ void Image::rotate_180() {
|
|||
}
|
||||
|
||||
void Image::flip_y() {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_y in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot flip_y in compressed image formats.");
|
||||
|
||||
bool used_mipmaps = has_mipmaps();
|
||||
if (used_mipmaps) {
|
||||
|
|
@ -1697,7 +1698,7 @@ void Image::flip_y() {
|
|||
}
|
||||
|
||||
void Image::flip_x() {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_x in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot flip_x in compressed image formats.");
|
||||
|
||||
bool used_mipmaps = has_mipmaps();
|
||||
if (used_mipmaps) {
|
||||
|
|
@ -1789,10 +1790,6 @@ int64_t Image::_get_dst_image_size(int p_width, int p_height, Format p_format, i
|
|||
return size;
|
||||
}
|
||||
|
||||
bool Image::_can_modify(Format p_format) const {
|
||||
return !Image::is_format_compressed(p_format);
|
||||
}
|
||||
|
||||
template <typename Component, int CC, bool renormalize,
|
||||
void (*average_func)(Component &, const Component &, const Component &, const Component &, const Component &),
|
||||
void (*renormalize_func)(Component *)>
|
||||
|
|
@ -1926,7 +1923,7 @@ void Image::shrink_x2() {
|
|||
memcpy(new_data.ptrw(), data.ptr() + ofs, new_size);
|
||||
} else {
|
||||
// Generate a mipmap and replace the original.
|
||||
ERR_FAIL_COND(!_can_modify(format));
|
||||
ERR_FAIL_COND(is_compressed());
|
||||
|
||||
new_data.resize((width / 2) * (height / 2) * get_format_pixel_size(format));
|
||||
ERR_FAIL_COND(data.is_empty() || new_data.is_empty());
|
||||
|
|
@ -1963,7 +1960,7 @@ void Image::normalize() {
|
|||
}
|
||||
|
||||
Error Image::generate_mipmaps(bool p_renormalize) {
|
||||
ERR_FAIL_COND_V_MSG(!_can_modify(format), ERR_UNAVAILABLE, "Cannot generate mipmaps in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_V_MSG(is_compressed(), ERR_UNAVAILABLE, "Cannot generate mipmaps from compressed image formats.");
|
||||
ERR_FAIL_COND_V_MSG(format == FORMAT_RGBA4444, ERR_UNAVAILABLE, "Cannot generate mipmaps from RGBA4444 format.");
|
||||
ERR_FAIL_COND_V_MSG(width == 0 || height == 0, ERR_UNCONFIGURED, "Cannot generate mipmaps with width or height equal to 0.");
|
||||
|
||||
|
|
@ -2180,7 +2177,7 @@ void Image::clear_mipmaps() {
|
|||
}
|
||||
|
||||
bool Image::is_empty() const {
|
||||
return (data.size() == 0);
|
||||
return (data.is_empty());
|
||||
}
|
||||
|
||||
Vector<uint8_t> Image::get_data() const {
|
||||
|
|
@ -2297,7 +2294,7 @@ void Image::initialize_data(const char **p_xpm) {
|
|||
switch (status) {
|
||||
case READING_HEADER: {
|
||||
String line_str = line_ptr;
|
||||
line_str.replace("\t", " ");
|
||||
line_str.replace_char('\t', ' ');
|
||||
|
||||
size_width = line_str.get_slicec(' ', 0).to_int();
|
||||
size_height = line_str.get_slicec(' ', 1).to_int();
|
||||
|
|
@ -2441,47 +2438,75 @@ void Image::initialize_data(const char **p_xpm) {
|
|||
}
|
||||
|
||||
bool Image::is_invisible() const {
|
||||
if (format == FORMAT_L8 || format == FORMAT_RGB8 || format == FORMAT_RG8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t len = data.size();
|
||||
int w, h;
|
||||
int64_t len;
|
||||
_get_mipmap_offset_and_size(1, len, w, h);
|
||||
|
||||
if (len == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int w, h;
|
||||
_get_mipmap_offset_and_size(1, len, w, h);
|
||||
|
||||
const uint8_t *r = data.ptr();
|
||||
const unsigned char *data_ptr = r;
|
||||
|
||||
bool detected = false;
|
||||
|
||||
switch (format) {
|
||||
case FORMAT_LA8: {
|
||||
for (int i = 0; i < (len >> 1); i++) {
|
||||
DETECT_NON_ALPHA(data_ptr[(i << 1) + 1]);
|
||||
}
|
||||
const int pixel_count = len / 2;
|
||||
const uint16_t *pixeldata = reinterpret_cast<const uint16_t *>(data.ptr());
|
||||
|
||||
for (int i = 0; i < pixel_count; i++) {
|
||||
if ((pixeldata[i] & 0xFF00) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case FORMAT_RGBA8: {
|
||||
for (int i = 0; i < (len >> 2); i++) {
|
||||
DETECT_NON_ALPHA(data_ptr[(i << 2) + 3])
|
||||
const int pixel_count = len / 4;
|
||||
const uint32_t *pixeldata = reinterpret_cast<const uint32_t *>(data.ptr());
|
||||
|
||||
for (int i = 0; i < pixel_count; i++) {
|
||||
if ((pixeldata[i] & 0xFF000000) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
case FORMAT_RGBA4444: {
|
||||
const int pixel_count = len / 2;
|
||||
const uint16_t *pixeldata = reinterpret_cast<const uint16_t *>(data.ptr());
|
||||
|
||||
case FORMAT_DXT3:
|
||||
case FORMAT_DXT5: {
|
||||
detected = true;
|
||||
for (int i = 0; i < pixel_count; i++) {
|
||||
if ((pixeldata[i] & 0x000F) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case FORMAT_RGBAH: {
|
||||
// The alpha mask accounts for the sign bit.
|
||||
const int pixel_count = len / 4;
|
||||
const uint16_t *pixeldata = reinterpret_cast<const uint16_t *>(data.ptr());
|
||||
|
||||
for (int i = 0; i < pixel_count; i += 4) {
|
||||
if ((pixeldata[i + 3] & 0x7FFF) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case FORMAT_RGBAF: {
|
||||
// The alpha mask accounts for the sign bit.
|
||||
const int pixel_count = len / 4;
|
||||
const uint32_t *pixeldata = reinterpret_cast<const uint32_t *>(data.ptr());
|
||||
|
||||
for (int i = 0; i < pixel_count; i += 4) {
|
||||
if ((pixeldata[i + 3] & 0x7FFFFFFF) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
// Formats that are compressed or don't support alpha channels are presumed to be visible.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !detected;
|
||||
// Every pixel has been checked, the image is invisible.
|
||||
return true;
|
||||
}
|
||||
|
||||
Image::AlphaMode Image::detect_alpha() const {
|
||||
|
|
@ -2603,6 +2628,21 @@ Vector<uint8_t> Image::save_exr_to_buffer(bool p_grayscale) const {
|
|||
return save_exr_buffer_func(Ref<Image>((Image *)this), p_grayscale);
|
||||
}
|
||||
|
||||
Error Image::save_dds(const String &p_path) const {
|
||||
if (save_dds_func == nullptr) {
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
return save_dds_func(p_path, Ref<Image>((Image *)this));
|
||||
}
|
||||
|
||||
Vector<uint8_t> Image::save_dds_to_buffer() const {
|
||||
if (save_dds_buffer_func == nullptr) {
|
||||
return Vector<uint8_t>();
|
||||
}
|
||||
return save_dds_buffer_func(Ref<Image>((Image *)this));
|
||||
}
|
||||
|
||||
Error Image::save_webp(const String &p_path, const bool p_lossy, const float p_quality) const {
|
||||
if (save_webp_func == nullptr) {
|
||||
return ERR_UNAVAILABLE;
|
||||
|
|
@ -2682,6 +2722,19 @@ Error Image::decompress() {
|
|||
return OK;
|
||||
}
|
||||
|
||||
bool Image::can_decompress(const String &p_format_tag) {
|
||||
if (p_format_tag == "astc") {
|
||||
return _image_decompress_astc != nullptr;
|
||||
} else if (p_format_tag == "bptc") {
|
||||
return _image_decompress_bptc != nullptr;
|
||||
} else if (p_format_tag == "etc2") {
|
||||
return _image_decompress_etc2 != nullptr;
|
||||
} else if (p_format_tag == "s3tc") {
|
||||
return _image_decompress_bc != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Error Image::compress(CompressMode p_mode, CompressSource p_source, ASTCFormat p_astc_format) {
|
||||
ERR_FAIL_INDEX_V_MSG(p_mode, COMPRESS_MAX, ERR_INVALID_PARAMETER, "Invalid compress mode.");
|
||||
ERR_FAIL_INDEX_V_MSG(p_source, COMPRESS_SOURCE_MAX, ERR_INVALID_PARAMETER, "Invalid compress source.");
|
||||
|
|
@ -2863,7 +2916,7 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2i &p_src_rect, const P
|
|||
ERR_FAIL_COND(dsize == 0);
|
||||
ERR_FAIL_COND(srcdsize == 0);
|
||||
ERR_FAIL_COND(format != p_src->format);
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot blit_rect in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot blit_rect in compressed image formats.");
|
||||
|
||||
Rect2i src_rect;
|
||||
Rect2i dest_rect;
|
||||
|
|
@ -3043,10 +3096,10 @@ void Image::_repeat_pixel_over_subsequent_memory(uint8_t *p_pixel, int p_pixel_s
|
|||
}
|
||||
|
||||
void Image::fill(const Color &p_color) {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot fill in compressed image formats.");
|
||||
|
||||
uint8_t *dst_data_ptr = data.ptrw();
|
||||
|
||||
|
|
@ -3059,10 +3112,10 @@ void Image::fill(const Color &p_color) {
|
|||
}
|
||||
|
||||
void Image::fill_rect(const Rect2i &p_rect, const Color &p_color) {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill rect in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot fill rect in compressed image formats.");
|
||||
|
||||
Rect2i r = Rect2i(0, 0, width, height).intersection(p_rect.abs());
|
||||
if (!r.has_area()) {
|
||||
|
|
@ -3278,7 +3331,7 @@ void Image::_set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color)
|
|||
uint16_t rgba = 0;
|
||||
|
||||
rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31));
|
||||
rgba |= uint16_t(CLAMP(p_color.g * 63.0, 0, 33)) << 5;
|
||||
rgba |= uint16_t(CLAMP(p_color.g * 63.0, 0, 63)) << 5;
|
||||
rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31)) << 11;
|
||||
|
||||
((uint16_t *)ptr)[ofs] = rgba;
|
||||
|
|
@ -3366,7 +3419,7 @@ int64_t Image::get_data_size() const {
|
|||
}
|
||||
|
||||
void Image::adjust_bcs(float p_brightness, float p_contrast, float p_saturation) {
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot adjust_bcs in compressed or custom image formats.");
|
||||
ERR_FAIL_COND_MSG(is_compressed(), "Cannot adjust_bcs in compressed image formats.");
|
||||
|
||||
uint8_t *w = data.ptrw();
|
||||
uint32_t pixel_size = get_format_pixel_size(format);
|
||||
|
|
@ -3524,6 +3577,9 @@ void Image::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("save_jpg_to_buffer", "quality"), &Image::save_jpg_to_buffer, DEFVAL(0.75));
|
||||
ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("save_exr_to_buffer", "grayscale"), &Image::save_exr_to_buffer, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("save_dds", "path"), &Image::save_dds);
|
||||
ClassDB::bind_method(D_METHOD("save_dds_to_buffer"), &Image::save_dds_to_buffer);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("save_webp", "path", "lossy", "quality"), &Image::save_webp, DEFVAL(false), DEFVAL(0.75f));
|
||||
ClassDB::bind_method(D_METHOD("save_webp_to_buffer", "lossy", "quality"), &Image::save_webp_to_buffer, DEFVAL(false), DEFVAL(0.75f));
|
||||
|
||||
|
|
@ -3577,6 +3633,7 @@ void Image::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("load_tga_from_buffer", "buffer"), &Image::load_tga_from_buffer);
|
||||
ClassDB::bind_method(D_METHOD("load_bmp_from_buffer", "buffer"), &Image::load_bmp_from_buffer);
|
||||
ClassDB::bind_method(D_METHOD("load_ktx_from_buffer", "buffer"), &Image::load_ktx_from_buffer);
|
||||
ClassDB::bind_method(D_METHOD("load_dds_from_buffer", "buffer"), &Image::load_dds_from_buffer);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("load_svg_from_buffer", "buffer", "scale"), &Image::load_svg_from_buffer, DEFVAL(1.0));
|
||||
ClassDB::bind_method(D_METHOD("load_svg_from_string", "svg_str", "scale"), &Image::load_svg_from_string, DEFVAL(1.0));
|
||||
|
|
@ -3677,7 +3734,7 @@ void Image::normal_map_to_xy() {
|
|||
}
|
||||
|
||||
Ref<Image> Image::rgbe_to_srgb() {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return Ref<Image>();
|
||||
}
|
||||
|
||||
|
|
@ -3724,7 +3781,7 @@ Ref<Image> Image::get_image_from_mipmap(int p_mipmap) const {
|
|||
}
|
||||
|
||||
void Image::bump_map_to_normal_map(float bump_scale) {
|
||||
ERR_FAIL_COND(!_can_modify(format));
|
||||
ERR_FAIL_COND(is_compressed());
|
||||
clear_mipmaps();
|
||||
convert(Image::FORMAT_RF);
|
||||
|
||||
|
|
@ -3799,7 +3856,7 @@ bool Image::detect_signed(bool p_include_mips) const {
|
|||
}
|
||||
|
||||
void Image::srgb_to_linear() {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3830,7 +3887,7 @@ void Image::srgb_to_linear() {
|
|||
}
|
||||
|
||||
void Image::linear_to_srgb() {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3861,7 +3918,7 @@ void Image::linear_to_srgb() {
|
|||
}
|
||||
|
||||
void Image::premultiply_alpha() {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3883,7 +3940,7 @@ void Image::premultiply_alpha() {
|
|||
}
|
||||
|
||||
void Image::fix_alpha_edges() {
|
||||
if (data.size() == 0) {
|
||||
if (data.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4072,6 +4129,14 @@ Error Image::load_bmp_from_buffer(const Vector<uint8_t> &p_array) {
|
|||
return _load_from_buffer(p_array, _bmp_mem_loader_func);
|
||||
}
|
||||
|
||||
Error Image::load_dds_from_buffer(const Vector<uint8_t> &p_array) {
|
||||
ERR_FAIL_NULL_V_MSG(
|
||||
_dds_mem_loader_func,
|
||||
ERR_UNAVAILABLE,
|
||||
"The DDS module isn't enabled. Recompile the Godot editor or export template binary with the `module_dds_enabled=yes` SCons option.");
|
||||
return _load_from_buffer(p_array, _dds_mem_loader_func);
|
||||
}
|
||||
|
||||
Error Image::load_svg_from_buffer(const Vector<uint8_t> &p_array, float scale) {
|
||||
ERR_FAIL_NULL_V_MSG(
|
||||
_svg_scalable_mem_loader_func,
|
||||
|
|
@ -4266,10 +4331,10 @@ Dictionary Image::compute_image_metrics(const Ref<Image> p_compared_image, bool
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Dictionary result;
|
||||
result["max"] = INFINITY;
|
||||
result["mean"] = INFINITY;
|
||||
result["mean_squared"] = INFINITY;
|
||||
result["root_mean_squared"] = INFINITY;
|
||||
result["max"] = Math::INF;
|
||||
result["mean"] = Math::INF;
|
||||
result["mean_squared"] = Math::INF;
|
||||
result["root_mean_squared"] = Math::INF;
|
||||
result["peak_snr"] = 0.0f;
|
||||
|
||||
ERR_FAIL_COND_V(p_compared_image.is_null(), result);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IMAGE_H
|
||||
#define IMAGE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource.h"
|
||||
#include "core/math/color.h"
|
||||
|
|
@ -59,6 +58,9 @@ typedef Vector<uint8_t> (*SaveWebPBufferFunc)(const Ref<Image> &p_img, const boo
|
|||
typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
|
||||
typedef Vector<uint8_t> (*SaveEXRBufferFunc)(const Ref<Image> &p_img, bool p_grayscale);
|
||||
|
||||
typedef Error (*SaveDDSFunc)(const String &p_path, const Ref<Image> &p_img);
|
||||
typedef Vector<uint8_t> (*SaveDDSBufferFunc)(const Ref<Image> &p_img);
|
||||
|
||||
class Image : public Resource {
|
||||
GDCLASS(Image, Resource);
|
||||
|
||||
|
|
@ -186,10 +188,12 @@ public:
|
|||
static SaveJPGFunc save_jpg_func;
|
||||
static SaveEXRFunc save_exr_func;
|
||||
static SaveWebPFunc save_webp_func;
|
||||
static SaveDDSFunc save_dds_func;
|
||||
static SavePNGBufferFunc save_png_buffer_func;
|
||||
static SaveEXRBufferFunc save_exr_buffer_func;
|
||||
static SaveJPGBufferFunc save_jpg_buffer_func;
|
||||
static SaveWebPBufferFunc save_webp_buffer_func;
|
||||
static SaveDDSBufferFunc save_dds_buffer_func;
|
||||
|
||||
// External loader function pointers.
|
||||
|
||||
|
|
@ -201,6 +205,7 @@ public:
|
|||
static ImageMemLoadFunc _bmp_mem_loader_func;
|
||||
static ScalableImageMemLoadFunc _svg_scalable_mem_loader_func;
|
||||
static ImageMemLoadFunc _ktx_mem_loader_func;
|
||||
static ImageMemLoadFunc _dds_mem_loader_func;
|
||||
|
||||
// External VRAM compression function pointers.
|
||||
|
||||
|
|
@ -251,7 +256,6 @@ private:
|
|||
_FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap, int64_t &r_offset, int &r_width, int &r_height) const; // Get where the mipmap begins in data.
|
||||
|
||||
static int64_t _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1, int *r_mm_width = nullptr, int *r_mm_height = nullptr);
|
||||
bool _can_modify(Format p_format) const;
|
||||
|
||||
_FORCE_INLINE_ void _get_clipped_src_and_dest_rects(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest, Rect2i &r_clipped_src_rect, Rect2i &r_clipped_dest_rect) const;
|
||||
|
||||
|
|
@ -334,9 +338,11 @@ public:
|
|||
static Ref<Image> load_from_file(const String &p_path);
|
||||
Error save_png(const String &p_path) const;
|
||||
Error save_jpg(const String &p_path, float p_quality = 0.75) const;
|
||||
Error save_dds(const String &p_path) const;
|
||||
Vector<uint8_t> save_png_to_buffer() const;
|
||||
Vector<uint8_t> save_jpg_to_buffer(float p_quality = 0.75) const;
|
||||
Vector<uint8_t> save_exr_to_buffer(bool p_grayscale = false) const;
|
||||
Vector<uint8_t> save_dds_to_buffer() const;
|
||||
Error save_exr(const String &p_path, bool p_grayscale = false) const;
|
||||
Error save_webp(const String &p_path, const bool p_lossy = false, const float p_quality = 0.75f) const;
|
||||
Vector<uint8_t> save_webp_to_buffer(const bool p_lossy = false, const float p_quality = 0.75f) const;
|
||||
|
|
@ -373,6 +379,8 @@ public:
|
|||
bool is_compressed() const;
|
||||
static bool is_format_compressed(Format p_format);
|
||||
|
||||
static bool can_decompress(const String &p_format_tag);
|
||||
|
||||
void fix_alpha_edges();
|
||||
void premultiply_alpha();
|
||||
void srgb_to_linear();
|
||||
|
|
@ -403,6 +411,7 @@ public:
|
|||
Error load_tga_from_buffer(const Vector<uint8_t> &p_array);
|
||||
Error load_bmp_from_buffer(const Vector<uint8_t> &p_array);
|
||||
Error load_ktx_from_buffer(const Vector<uint8_t> &p_array);
|
||||
Error load_dds_from_buffer(const Vector<uint8_t> &p_array);
|
||||
|
||||
Error load_svg_from_buffer(const Vector<uint8_t> &p_array, float scale = 1.0);
|
||||
Error load_svg_from_string(const String &p_svg_str, float scale = 1.0);
|
||||
|
|
@ -442,5 +451,3 @@ VARIANT_ENUM_CAST(Image::UsedChannels)
|
|||
VARIANT_ENUM_CAST(Image::AlphaMode)
|
||||
VARIANT_ENUM_CAST(Image::RoughnessChannel)
|
||||
VARIANT_ENUM_CAST(Image::ASTCFormat)
|
||||
|
||||
#endif // IMAGE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IMAGE_LOADER_H
|
||||
#define IMAGE_LOADER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/core_bind.h"
|
||||
#include "core/io/file_access.h"
|
||||
|
|
@ -108,5 +107,3 @@ public:
|
|||
virtual bool handles_type(const String &p_type) const override;
|
||||
virtual String get_resource_type(const String &p_path) const override;
|
||||
};
|
||||
|
||||
#endif // IMAGE_LOADER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IP_H
|
||||
#define IP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/ip_address.h"
|
||||
#include "core/os/os.h"
|
||||
|
|
@ -110,5 +109,3 @@ public:
|
|||
|
||||
VARIANT_ENUM_CAST(IP::Type);
|
||||
VARIANT_ENUM_CAST(IP::ResolverStatus);
|
||||
|
||||
#endif // IP_H
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ void IPAddress::_parse_ipv6(const String &p_string) {
|
|||
void IPAddress::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret) {
|
||||
String ip;
|
||||
if (p_start != 0) {
|
||||
ip = p_string.substr(p_start, p_string.length() - p_start);
|
||||
ip = p_string.substr(p_start);
|
||||
} else {
|
||||
ip = p_string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IP_ADDRESS_H
|
||||
#define IP_ADDRESS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/ustring.h"
|
||||
|
||||
|
|
@ -96,4 +95,6 @@ public:
|
|||
IPAddress() { clear(); }
|
||||
};
|
||||
|
||||
#endif // IP_ADDRESS_H
|
||||
// Zero-constructing IPAddress initializes field, valid, and wildcard to 0 (and thus empty).
|
||||
template <>
|
||||
struct is_zero_constructible<IPAddress> : std::true_type {};
|
||||
|
|
|
|||
|
|
@ -122,8 +122,7 @@ String JSON::_stringify(const Variant &p_var, const String &p_indent, int p_cur_
|
|||
ERR_FAIL_COND_V_MSG(p_markers.has(d.id()), "\"{...}\"", "Converting circular structure to JSON.");
|
||||
p_markers.insert(d.id());
|
||||
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
LocalVector<Variant> keys = d.get_key_list();
|
||||
|
||||
if (p_sort_keys) {
|
||||
keys.sort_custom<StringLikeVariantOrder>();
|
||||
|
|
@ -664,201 +663,96 @@ Variant JSON::_from_native(const Variant &p_variant, bool p_full_objects, int p_
|
|||
|
||||
case Variant::VECTOR2: {
|
||||
const Vector2 v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
|
||||
Array args = { v.x, v.y };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::VECTOR2I: {
|
||||
const Vector2i v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
|
||||
Array args = { v.x, v.y };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::RECT2: {
|
||||
const Rect2 r = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(r.position.x);
|
||||
args.push_back(r.position.y);
|
||||
args.push_back(r.size.width);
|
||||
args.push_back(r.size.height);
|
||||
|
||||
Array args = { r.position.x, r.position.y, r.size.width, r.size.height };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::RECT2I: {
|
||||
const Rect2i r = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(r.position.x);
|
||||
args.push_back(r.position.y);
|
||||
args.push_back(r.size.width);
|
||||
args.push_back(r.size.height);
|
||||
|
||||
Array args = { r.position.x, r.position.y, r.size.width, r.size.height };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::VECTOR3: {
|
||||
const Vector3 v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
args.push_back(v.z);
|
||||
|
||||
Array args = { v.x, v.y, v.z };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::VECTOR3I: {
|
||||
const Vector3i v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
args.push_back(v.z);
|
||||
|
||||
Array args = { v.x, v.y, v.z };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::TRANSFORM2D: {
|
||||
const Transform2D t = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(t[0].x);
|
||||
args.push_back(t[0].y);
|
||||
args.push_back(t[1].x);
|
||||
args.push_back(t[1].y);
|
||||
args.push_back(t[2].x);
|
||||
args.push_back(t[2].y);
|
||||
|
||||
Array args = { t[0].x, t[0].y, t[1].x, t[1].y, t[2].x, t[2].y };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::VECTOR4: {
|
||||
const Vector4 v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
args.push_back(v.z);
|
||||
args.push_back(v.w);
|
||||
|
||||
Array args = { v.x, v.y, v.z, v.w };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::VECTOR4I: {
|
||||
const Vector4i v = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(v.x);
|
||||
args.push_back(v.y);
|
||||
args.push_back(v.z);
|
||||
args.push_back(v.w);
|
||||
|
||||
Array args = { v.x, v.y, v.z, v.w };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::PLANE: {
|
||||
const Plane p = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(p.normal.x);
|
||||
args.push_back(p.normal.y);
|
||||
args.push_back(p.normal.z);
|
||||
args.push_back(p.d);
|
||||
|
||||
Array args = { p.normal.x, p.normal.y, p.normal.z, p.d };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::QUATERNION: {
|
||||
const Quaternion q = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(q.x);
|
||||
args.push_back(q.y);
|
||||
args.push_back(q.z);
|
||||
args.push_back(q.w);
|
||||
|
||||
Array args = { q.x, q.y, q.z, q.w };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::AABB: {
|
||||
const AABB aabb = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(aabb.position.x);
|
||||
args.push_back(aabb.position.y);
|
||||
args.push_back(aabb.position.z);
|
||||
args.push_back(aabb.size.x);
|
||||
args.push_back(aabb.size.y);
|
||||
args.push_back(aabb.size.z);
|
||||
|
||||
Array args = { aabb.position.x, aabb.position.y, aabb.position.z, aabb.size.x, aabb.size.y, aabb.size.z };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::BASIS: {
|
||||
const Basis b = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(b.get_column(0).x);
|
||||
args.push_back(b.get_column(0).y);
|
||||
args.push_back(b.get_column(0).z);
|
||||
args.push_back(b.get_column(1).x);
|
||||
args.push_back(b.get_column(1).y);
|
||||
args.push_back(b.get_column(1).z);
|
||||
args.push_back(b.get_column(2).x);
|
||||
args.push_back(b.get_column(2).y);
|
||||
args.push_back(b.get_column(2).z);
|
||||
Array args = { b.get_column(0).x, b.get_column(0).y, b.get_column(0).z,
|
||||
b.get_column(1).x, b.get_column(1).y, b.get_column(1).z,
|
||||
b.get_column(2).x, b.get_column(2).y, b.get_column(2).z };
|
||||
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::TRANSFORM3D: {
|
||||
const Transform3D t = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(t.basis.get_column(0).x);
|
||||
args.push_back(t.basis.get_column(0).y);
|
||||
args.push_back(t.basis.get_column(0).z);
|
||||
args.push_back(t.basis.get_column(1).x);
|
||||
args.push_back(t.basis.get_column(1).y);
|
||||
args.push_back(t.basis.get_column(1).z);
|
||||
args.push_back(t.basis.get_column(2).x);
|
||||
args.push_back(t.basis.get_column(2).y);
|
||||
args.push_back(t.basis.get_column(2).z);
|
||||
args.push_back(t.origin.x);
|
||||
args.push_back(t.origin.y);
|
||||
args.push_back(t.origin.z);
|
||||
Array args = { t.basis.get_column(0).x, t.basis.get_column(0).y, t.basis.get_column(0).z,
|
||||
t.basis.get_column(1).x, t.basis.get_column(1).y, t.basis.get_column(1).z,
|
||||
t.basis.get_column(2).x, t.basis.get_column(2).y, t.basis.get_column(2).z,
|
||||
t.origin.x, t.origin.y, t.origin.z };
|
||||
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::PROJECTION: {
|
||||
const Projection p = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(p[0].x);
|
||||
args.push_back(p[0].y);
|
||||
args.push_back(p[0].z);
|
||||
args.push_back(p[0].w);
|
||||
args.push_back(p[1].x);
|
||||
args.push_back(p[1].y);
|
||||
args.push_back(p[1].z);
|
||||
args.push_back(p[1].w);
|
||||
args.push_back(p[2].x);
|
||||
args.push_back(p[2].y);
|
||||
args.push_back(p[2].z);
|
||||
args.push_back(p[2].w);
|
||||
args.push_back(p[3].x);
|
||||
args.push_back(p[3].y);
|
||||
args.push_back(p[3].z);
|
||||
args.push_back(p[3].w);
|
||||
Array args = { p[0].x, p[0].y, p[0].z, p[0].w,
|
||||
p[1].x, p[1].y, p[1].z, p[1].w,
|
||||
p[2].x, p[2].y, p[2].z, p[2].w,
|
||||
p[3].x, p[3].y, p[3].z, p[3].w };
|
||||
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
case Variant::COLOR: {
|
||||
const Color c = p_variant;
|
||||
|
||||
Array args;
|
||||
args.push_back(c.r);
|
||||
args.push_back(c.g);
|
||||
args.push_back(c.b);
|
||||
args.push_back(c.a);
|
||||
|
||||
Array args = { c.r, c.g, c.b, c.a };
|
||||
RETURN_ARGS;
|
||||
} break;
|
||||
|
||||
|
|
@ -922,12 +816,9 @@ Variant JSON::_from_native(const Variant &p_variant, bool p_full_objects, int p_
|
|||
|
||||
ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ret, "Variant is too deep. Bailing.");
|
||||
|
||||
List<Variant> keys;
|
||||
dict.get_key_list(&keys);
|
||||
|
||||
for (const Variant &key : keys) {
|
||||
args.push_back(_from_native(key, p_full_objects, p_depth + 1));
|
||||
args.push_back(_from_native(dict[key], p_full_objects, p_depth + 1));
|
||||
for (const KeyValue<Variant, Variant> &kv : dict) {
|
||||
args.push_back(_from_native(kv.key, p_full_objects, p_depth + 1));
|
||||
args.push_back(_from_native(kv.value, p_full_objects, p_depth + 1));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef JSON_H
|
||||
#define JSON_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
|
|
@ -125,5 +124,3 @@ public:
|
|||
virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const override;
|
||||
virtual bool recognize(const Ref<Resource> &p_resource) const override;
|
||||
};
|
||||
|
||||
#endif // JSON_H
|
||||
|
|
|
|||
|
|
@ -36,10 +36,9 @@
|
|||
#include "core/templates/rb_set.h"
|
||||
|
||||
#include "modules/modules_enabled.gen.h" // For regex.
|
||||
|
||||
#ifdef MODULE_REGEX_ENABLED
|
||||
#include "modules/regex/regex.h"
|
||||
#else
|
||||
class RegEx : public RefCounted {};
|
||||
#endif // MODULE_REGEX_ENABLED
|
||||
|
||||
#if defined(MINGW_ENABLED) || defined(_MSC_VER)
|
||||
|
|
@ -156,7 +155,7 @@ void RotatedFileLogger::rotate_file() {
|
|||
|
||||
if (FileAccess::exists(base_path)) {
|
||||
if (max_files > 1) {
|
||||
String timestamp = Time::get_singleton()->get_datetime_string_from_system().replace(":", ".");
|
||||
String timestamp = Time::get_singleton()->get_datetime_string_from_system().replace_char(':', '.');
|
||||
String backup_name = base_path.get_basename() + timestamp;
|
||||
if (!base_path.get_extension().is_empty()) {
|
||||
backup_name += "." + base_path.get_extension();
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
|
@ -109,5 +108,3 @@ public:
|
|||
|
||||
virtual ~CompositeLogger();
|
||||
};
|
||||
|
||||
#endif // LOGGER_H
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r
|
|||
ERR_FAIL_COND_V(strlen < 0 || strlen + pad > len, ERR_FILE_EOF);
|
||||
|
||||
String str;
|
||||
ERR_FAIL_COND_V(str.parse_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA);
|
||||
ERR_FAIL_COND_V(str.append_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA);
|
||||
r_string = str;
|
||||
|
||||
// Add padding.
|
||||
|
|
@ -1345,7 +1345,7 @@ static Error _encode_container_type(const ContainerType &p_type, uint8_t *&buf,
|
|||
_encode_string(EncodedObjectAsID::get_class_static(), buf, r_len);
|
||||
}
|
||||
} else if (p_type.class_name != StringName()) {
|
||||
_encode_string(p_full_objects ? p_type.class_name.operator String() : EncodedObjectAsID::get_class_static(), buf, r_len);
|
||||
_encode_string(p_full_objects ? p_type.class_name : EncodedObjectAsID::get_class_static(), buf, r_len);
|
||||
} else {
|
||||
// No need to check `p_full_objects` since `class_name` should be non-empty for `builtin_type == Variant::OBJECT`.
|
||||
if (buf) {
|
||||
|
|
@ -1849,19 +1849,16 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
|||
}
|
||||
r_len += 4;
|
||||
|
||||
List<Variant> keys;
|
||||
dict.get_key_list(&keys);
|
||||
|
||||
for (const Variant &key : keys) {
|
||||
for (const KeyValue<Variant, Variant> &kv : dict) {
|
||||
int len;
|
||||
Error err = encode_variant(key, buf, len, p_full_objects, p_depth + 1);
|
||||
Error err = encode_variant(kv.key, buf, len, p_full_objects, p_depth + 1);
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
ERR_FAIL_COND_V(len % 4, ERR_BUG);
|
||||
r_len += len;
|
||||
if (buf) {
|
||||
buf += len;
|
||||
}
|
||||
const Variant *value = dict.getptr(key);
|
||||
const Variant *value = dict.getptr(kv.key);
|
||||
ERR_FAIL_NULL_V(value, ERR_BUG);
|
||||
err = encode_variant(*value, buf, len, p_full_objects, p_depth + 1);
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef MARSHALLS_H
|
||||
#define MARSHALLS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/math_defs.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
|
@ -226,5 +225,3 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
|
|||
Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false, int p_depth = 0);
|
||||
|
||||
Vector<float> vector3_to_float32_array(const Vector3 *vecs, size_t count);
|
||||
|
||||
#endif // MARSHALLS_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef MISSING_RESOURCE_H
|
||||
#define MISSING_RESOURCE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource.h"
|
||||
|
||||
|
|
@ -61,5 +60,3 @@ public:
|
|||
|
||||
MissingResource();
|
||||
};
|
||||
|
||||
#endif // MISSING_RESOURCE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef NET_SOCKET_H
|
||||
#define NET_SOCKET_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/ip.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
|
|
@ -79,5 +78,3 @@ public:
|
|||
|
||||
virtual ~NetSocket() {}
|
||||
};
|
||||
|
||||
#endif // NET_SOCKET_H
|
||||
|
|
|
|||
|
|
@ -268,14 +268,12 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
|
|||
encode_uint32(TYPE_DICT, &tmpdata.write[pos + 0]);
|
||||
encode_uint32(len, &tmpdata.write[pos + 4]);
|
||||
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
List<DictKey> sortk;
|
||||
|
||||
for (const Variant &key : keys) {
|
||||
for (const KeyValue<Variant, Variant> &kv : d) {
|
||||
DictKey dk;
|
||||
dk.hash = key.hash();
|
||||
dk.key = key;
|
||||
dk.hash = kv.key.hash();
|
||||
dk.key = kv.key;
|
||||
sortk.push_back(dk);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PACKED_DATA_CONTAINER_H
|
||||
#define PACKED_DATA_CONTAINER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource.h"
|
||||
|
||||
|
|
@ -100,5 +99,3 @@ public:
|
|||
|
||||
PackedDataContainerRef() {}
|
||||
};
|
||||
|
||||
#endif // PACKED_DATA_CONTAINER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PACKET_PEER_H
|
||||
#define PACKET_PEER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/stream_peer.h"
|
||||
#include "core/object/class_db.h"
|
||||
|
|
@ -124,5 +123,3 @@ public:
|
|||
int get_output_buffer_max_size() const;
|
||||
PacketPeerStream();
|
||||
};
|
||||
|
||||
#endif // PACKET_PEER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PACKET_PEER_DTLS_H
|
||||
#define PACKET_PEER_DTLS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/crypto/crypto.h"
|
||||
#include "core/io/packet_peer_udp.h"
|
||||
|
|
@ -64,5 +63,3 @@ public:
|
|||
};
|
||||
|
||||
VARIANT_ENUM_CAST(PacketPeerDTLS::Status);
|
||||
|
||||
#endif // PACKET_PEER_DTLS_H
|
||||
|
|
|
|||
|
|
@ -105,18 +105,16 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
|
|||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* Bogus GCC warning here:
|
||||
* In member function 'int RingBuffer<T>::read(T*, int, bool) [with T = unsigned char]',
|
||||
* inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:112:9,
|
||||
* inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:99:7:
|
||||
* Error: ./core/ring_buffer.h:68:46: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=]
|
||||
* 68 | p_buf[dst++] = read[pos + i];
|
||||
* | ~~~~~~~~~~~~~^~~~~~~
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic warning "-Wstringop-overflow=0"
|
||||
#endif
|
||||
/* Bogus GCC warning here:
|
||||
* In member function 'int RingBuffer<T>::read(T*, int, bool) [with T = unsigned char]',
|
||||
* inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:112:9,
|
||||
* inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:99:7:
|
||||
* Error: ./core/ring_buffer.h:68:46: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=]
|
||||
* 68 | p_buf[dst++] = read[pos + i];
|
||||
* | ~~~~~~~~~~~~~^~~~~~~
|
||||
*/
|
||||
GODOT_GCC_WARNING_PUSH
|
||||
GODOT_GCC_PRAGMA(GCC diagnostic warning "-Wstringop-overflow=0") // Can't "ignore" this for some reason.
|
||||
|
||||
uint32_t size = 0;
|
||||
uint8_t ipv6[16] = {};
|
||||
|
|
@ -129,9 +127,7 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
|
|||
*r_buffer = packet_buffer;
|
||||
r_buffer_size = size;
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
GODOT_GCC_WARNING_POP
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PACKET_PEER_UDP_H
|
||||
#define PACKET_PEER_UDP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/ip.h"
|
||||
#include "core/io/net_socket.h"
|
||||
|
|
@ -97,5 +96,3 @@ public:
|
|||
PacketPeerUDP();
|
||||
~PacketPeerUDP();
|
||||
};
|
||||
|
||||
#endif // PACKET_PEER_UDP_H
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ Error PCKPacker::pck_start(const String &p_pck_path, int p_alignment, const Stri
|
|||
|
||||
file->store_32(PACK_HEADER_MAGIC);
|
||||
file->store_32(PACK_FORMAT_VERSION);
|
||||
file->store_32(VERSION_MAJOR);
|
||||
file->store_32(VERSION_MINOR);
|
||||
file->store_32(VERSION_PATCH);
|
||||
file->store_32(GODOT_VERSION_MAJOR);
|
||||
file->store_32(GODOT_VERSION_MINOR);
|
||||
file->store_32(GODOT_VERSION_PATCH);
|
||||
|
||||
uint32_t pack_flags = 0;
|
||||
if (enc_dir) {
|
||||
|
|
@ -118,8 +118,7 @@ Error PCKPacker::add_file_removal(const String &p_target_path) {
|
|||
pf.size = 0;
|
||||
pf.removal = true;
|
||||
|
||||
pf.md5.resize(16);
|
||||
pf.md5.fill(0);
|
||||
pf.md5.resize_zeroed(16);
|
||||
|
||||
files.push_back(pf);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PCK_PACKER_H
|
||||
#define PCK_PACKER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/ref_counted.h"
|
||||
|
||||
|
|
@ -66,5 +65,3 @@ public:
|
|||
|
||||
PCKPacker() {}
|
||||
};
|
||||
|
||||
#endif // PCK_PACKER_H
|
||||
|
|
|
|||
|
|
@ -383,14 +383,16 @@ void PListNode::store_text(String &p_stream, uint8_t p_indent) const {
|
|||
p_stream += String("\t").repeat(p_indent);
|
||||
p_stream += "<data>\n";
|
||||
p_stream += String("\t").repeat(p_indent);
|
||||
p_stream += data_string + "\n";
|
||||
// Data should be Base64 (i.e. ASCII only).
|
||||
p_stream += String::ascii(data_string) + "\n";
|
||||
p_stream += String("\t").repeat(p_indent);
|
||||
p_stream += "</data>\n";
|
||||
} break;
|
||||
case PList::PLNodeType::PL_NODE_TYPE_DATE: {
|
||||
p_stream += String("\t").repeat(p_indent);
|
||||
p_stream += "<date>";
|
||||
p_stream += data_string;
|
||||
// Data should be ISO 8601 (i.e. ASCII only).
|
||||
p_stream += String::ascii(data_string);
|
||||
p_stream += "</date>\n";
|
||||
} break;
|
||||
case PList::PLNodeType::PL_NODE_TYPE_STRING: {
|
||||
|
|
@ -629,7 +631,7 @@ bool PList::load_file(const String &p_filename) {
|
|||
unsigned char magic[8];
|
||||
fb->get_buffer(magic, 8);
|
||||
|
||||
if (String((const char *)magic, 8) == "bplist00") {
|
||||
if (String::ascii(Span((const char *)magic, 8)) == "bplist00") {
|
||||
fb->seek_end(-26);
|
||||
trailer.offset_size = fb->get_8();
|
||||
trailer.ref_size = fb->get_8();
|
||||
|
|
@ -645,10 +647,8 @@ bool PList::load_file(const String &p_filename) {
|
|||
Vector<uint8_t> array = FileAccess::get_file_as_bytes(p_filename, &err);
|
||||
ERR_FAIL_COND_V(err != OK, false);
|
||||
|
||||
String ret;
|
||||
ret.parse_utf8((const char *)array.ptr(), array.size());
|
||||
String err_str;
|
||||
bool ok = load_string(ret, err_str);
|
||||
bool ok = load_string(String::utf8((const char *)array.ptr(), array.size()), err_str);
|
||||
ERR_FAIL_COND_V_MSG(!ok, false, "PList: " + err_str);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PLIST_H
|
||||
#define PLIST_H
|
||||
#pragma once
|
||||
|
||||
// Property list file format (application/x-plist) parser, property list ASN-1 serialization.
|
||||
|
||||
|
|
@ -84,6 +83,8 @@ public:
|
|||
/*************************************************************************/
|
||||
|
||||
class PListNode : public RefCounted {
|
||||
GDSOFTCLASS(PListNode, RefCounted);
|
||||
|
||||
static int _asn1_size_len(uint8_t p_len_octets);
|
||||
|
||||
public:
|
||||
|
|
@ -122,5 +123,3 @@ public:
|
|||
PListNode() {}
|
||||
~PListNode() {}
|
||||
};
|
||||
|
||||
#endif // PLIST_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef REMOTE_FILESYSTEM_CLIENT_H
|
||||
#define REMOTE_FILESYSTEM_CLIENT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/ustring.h"
|
||||
#include "core/templates/hash_set.h"
|
||||
|
|
@ -60,5 +59,3 @@ public:
|
|||
Error synchronize_with_server(const String &p_host, int p_port, const String &p_password, String &r_cache_path);
|
||||
virtual ~RemoteFilesystemClient() {}
|
||||
};
|
||||
|
||||
#endif // REMOTE_FILESYSTEM_CLIENT_H
|
||||
|
|
|
|||
|
|
@ -32,10 +32,15 @@
|
|||
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "core/math/math_funcs.h"
|
||||
#include "core/math/random_pcg.h"
|
||||
#include "core/os/os.h"
|
||||
#include "scene/main/node.h" //only so casting works
|
||||
|
||||
void Resource::emit_changed() {
|
||||
if (emit_changed_state != EMIT_CHANGED_UNBLOCKED) {
|
||||
emit_changed_state = EMIT_CHANGED_BLOCKED_PENDING_EMIT;
|
||||
return;
|
||||
}
|
||||
if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) {
|
||||
ResourceLoader::resource_changed_emit(this);
|
||||
return;
|
||||
|
|
@ -44,6 +49,20 @@ void Resource::emit_changed() {
|
|||
emit_signal(CoreStringName(changed));
|
||||
}
|
||||
|
||||
void Resource::_block_emit_changed() {
|
||||
if (emit_changed_state == EMIT_CHANGED_UNBLOCKED) {
|
||||
emit_changed_state = EMIT_CHANGED_BLOCKED;
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::_unblock_emit_changed() {
|
||||
bool emit = (emit_changed_state == EMIT_CHANGED_BLOCKED_PENDING_EMIT);
|
||||
emit_changed_state = EMIT_CHANGED_UNBLOCKED;
|
||||
if (emit) {
|
||||
emit_changed();
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::_resource_path_changed() {
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +114,7 @@ void Resource::set_path_cache(const String &p_path) {
|
|||
GDVIRTUAL_CALL(_set_path_cache, p_path);
|
||||
}
|
||||
|
||||
static thread_local RandomPCG unique_id_gen(0, RandomPCG::DEFAULT_INC);
|
||||
static thread_local RandomPCG unique_id_gen = RandomPCG(0);
|
||||
|
||||
void Resource::seed_scene_unique_id(uint32_t p_seed) {
|
||||
unique_id_gen.seed(p_seed);
|
||||
|
|
@ -205,6 +224,8 @@ Error Resource::copy_from(const Ref<Resource> &p_resource) {
|
|||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
_block_emit_changed();
|
||||
|
||||
reset_state(); // May want to reset state.
|
||||
|
||||
List<PropertyInfo> pi;
|
||||
|
|
@ -220,6 +241,9 @@ Error Resource::copy_from(const Ref<Resource> &p_resource) {
|
|||
|
||||
set(E.name, p_resource->get(E.name));
|
||||
}
|
||||
|
||||
_unblock_emit_changed();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
@ -248,9 +272,7 @@ void Resource::_dupe_sub_resources(Variant &r_variant, Node *p_for_scene, HashMa
|
|||
} break;
|
||||
case Variant::DICTIONARY: {
|
||||
Dictionary d = r_variant;
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
for (Variant &k : keys) {
|
||||
for (Variant &k : d.get_key_list()) {
|
||||
if (k.get_type() == Variant::OBJECT) {
|
||||
// Replace in dictionary key.
|
||||
Ref<Resource> sr = k;
|
||||
|
|
@ -322,11 +344,9 @@ void Resource::_find_sub_resources(const Variant &p_variant, HashSet<Ref<Resourc
|
|||
} break;
|
||||
case Variant::DICTIONARY: {
|
||||
Dictionary d = p_variant;
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
for (const Variant &k : keys) {
|
||||
_find_sub_resources(k, p_resources_found);
|
||||
_find_sub_resources(d[k], p_resources_found);
|
||||
for (const KeyValue<Variant, Variant> &kv : d) {
|
||||
_find_sub_resources(kv.key, p_resources_found);
|
||||
_find_sub_resources(kv.value, p_resources_found);
|
||||
}
|
||||
} break;
|
||||
case Variant::OBJECT: {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RESOURCE_H
|
||||
#define RESOURCE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource_uid.h"
|
||||
#include "core/object/class_db.h"
|
||||
|
|
@ -72,6 +71,12 @@ private:
|
|||
String import_path;
|
||||
#endif
|
||||
|
||||
enum EmitChangedState {
|
||||
EMIT_CHANGED_UNBLOCKED,
|
||||
EMIT_CHANGED_BLOCKED,
|
||||
EMIT_CHANGED_BLOCKED_PENDING_EMIT,
|
||||
};
|
||||
EmitChangedState emit_changed_state = EMIT_CHANGED_UNBLOCKED;
|
||||
bool local_to_scene = false;
|
||||
friend class SceneState;
|
||||
Node *local_scene = nullptr;
|
||||
|
|
@ -85,6 +90,9 @@ protected:
|
|||
virtual void _resource_path_changed();
|
||||
static void _bind_methods();
|
||||
|
||||
void _block_emit_changed();
|
||||
void _unblock_emit_changed();
|
||||
|
||||
void _set_path(const String &p_path);
|
||||
void _take_over_path(const String &p_path);
|
||||
|
||||
|
|
@ -179,5 +187,3 @@ public:
|
|||
static void get_cached_resources(List<Ref<Resource>> *p_resources);
|
||||
static int get_cached_resource_count();
|
||||
};
|
||||
|
||||
#endif // RESOURCE_H
|
||||
|
|
|
|||
|
|
@ -162,9 +162,7 @@ StringName ResourceLoaderBinary::_get_string() {
|
|||
return StringName();
|
||||
}
|
||||
f->get_buffer((uint8_t *)&str_buf[0], len);
|
||||
String s;
|
||||
s.parse_utf8(&str_buf[0], len);
|
||||
return s;
|
||||
return String::utf8(&str_buf[0], len);
|
||||
}
|
||||
|
||||
return string_map[id];
|
||||
|
|
@ -918,9 +916,7 @@ static String get_ustring(Ref<FileAccess> f) {
|
|||
Vector<char> str_buf;
|
||||
str_buf.resize(len);
|
||||
f->get_buffer((uint8_t *)&str_buf[0], len);
|
||||
String s;
|
||||
s.parse_utf8(&str_buf[0], len);
|
||||
return s;
|
||||
return String::utf8(&str_buf[0], len);
|
||||
}
|
||||
|
||||
String ResourceLoaderBinary::get_unicode_string() {
|
||||
|
|
@ -932,9 +928,7 @@ String ResourceLoaderBinary::get_unicode_string() {
|
|||
return String();
|
||||
}
|
||||
f->get_buffer((uint8_t *)&str_buf[0], len);
|
||||
String s;
|
||||
s.parse_utf8(&str_buf[0], len);
|
||||
return s;
|
||||
return String::utf8(&str_buf[0], len);
|
||||
}
|
||||
|
||||
void ResourceLoaderBinary::get_classes_used(Ref<FileAccess> p_f, HashSet<StringName> *p_classes) {
|
||||
|
|
@ -1028,10 +1022,10 @@ void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p
|
|||
print_bl("minor: " + itos(ver_minor));
|
||||
print_bl("format: " + itos(ver_format));
|
||||
|
||||
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
|
||||
if (ver_format > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) {
|
||||
f.unref();
|
||||
ERR_FAIL_MSG(vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).",
|
||||
local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH));
|
||||
local_path, ver_format, ver_major, ver_minor, GODOT_VERSION_BRANCH));
|
||||
}
|
||||
|
||||
type = get_unicode_string();
|
||||
|
|
@ -1155,7 +1149,7 @@ String ResourceLoaderBinary::recognize(Ref<FileAccess> p_f) {
|
|||
f->get_32(); // ver_minor
|
||||
uint32_t ver_fmt = f->get_32();
|
||||
|
||||
if (ver_fmt > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
|
||||
if (ver_fmt > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) {
|
||||
f.unref();
|
||||
return "";
|
||||
}
|
||||
|
|
@ -1196,7 +1190,7 @@ String ResourceLoaderBinary::recognize_script_class(Ref<FileAccess> p_f) {
|
|||
f->get_32(); // ver_minor
|
||||
uint32_t ver_fmt = f->get_32();
|
||||
|
||||
if (ver_fmt > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
|
||||
if (ver_fmt > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) {
|
||||
f.unref();
|
||||
return "";
|
||||
}
|
||||
|
|
@ -1348,13 +1342,10 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
|
|||
bool use_real64 = f->get_32();
|
||||
|
||||
f->set_big_endian(big_endian != 0); //read big endian if saved as big endian
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
fw->store_32(!big_endian);
|
||||
#else
|
||||
|
||||
fw->store_32(big_endian);
|
||||
#endif
|
||||
fw->set_big_endian(big_endian != 0);
|
||||
fw->store_32(use_real64); //use real64
|
||||
fw->set_big_endian(big_endian != 0);
|
||||
|
||||
uint32_t ver_major = f->get_32();
|
||||
uint32_t ver_minor = f->get_32();
|
||||
|
|
@ -1392,10 +1383,10 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
|
|||
return ResourceFormatSaverBinary::singleton->save(res, p_path);
|
||||
}
|
||||
|
||||
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
|
||||
if (ver_format > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) {
|
||||
ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED,
|
||||
vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).",
|
||||
local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH));
|
||||
local_path, ver_format, ver_major, ver_minor, GODOT_VERSION_BRANCH));
|
||||
}
|
||||
|
||||
// Since we're not actually converting the file contents, leave the version
|
||||
|
|
@ -1876,12 +1867,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V
|
|||
Dictionary d = p_property;
|
||||
f->store_32(uint32_t(d.size()));
|
||||
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
|
||||
for (const Variant &E : keys) {
|
||||
write_variant(f, E, resource_map, external_resources, string_map);
|
||||
write_variant(f, d[E], resource_map, external_resources, string_map);
|
||||
for (const KeyValue<Variant, Variant> &kv : d) {
|
||||
write_variant(f, kv.key, resource_map, external_resources, string_map);
|
||||
write_variant(f, kv.value, resource_map, external_resources, string_map);
|
||||
}
|
||||
|
||||
} break;
|
||||
|
|
@ -2086,12 +2074,9 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
|
|||
Dictionary d = p_variant;
|
||||
_find_resources(d.get_typed_key_script());
|
||||
_find_resources(d.get_typed_value_script());
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
for (const Variant &E : keys) {
|
||||
_find_resources(E);
|
||||
Variant v = d[E];
|
||||
_find_resources(v);
|
||||
for (const KeyValue<Variant, Variant> &kv : d) {
|
||||
_find_resources(kv.key);
|
||||
_find_resources(kv.value);
|
||||
}
|
||||
} break;
|
||||
case Variant::NODE_PATH: {
|
||||
|
|
@ -2180,14 +2165,14 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re
|
|||
|
||||
if (big_endian) {
|
||||
f->store_32(1);
|
||||
f->set_big_endian(true);
|
||||
} else {
|
||||
f->store_32(0);
|
||||
}
|
||||
|
||||
f->store_32(0); //64 bits file, false for now
|
||||
f->store_32(VERSION_MAJOR);
|
||||
f->store_32(VERSION_MINOR);
|
||||
f->set_big_endian(big_endian);
|
||||
|
||||
f->store_32(GODOT_VERSION_MAJOR);
|
||||
f->store_32(GODOT_VERSION_MINOR);
|
||||
f->store_32(FORMAT_VERSION);
|
||||
|
||||
if (f->get_error() != OK && f->get_error() != ERR_FILE_EOF) {
|
||||
|
|
@ -2424,13 +2409,10 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU
|
|||
big_endian = f->get_32();
|
||||
bool use_real64 = f->get_32();
|
||||
f->set_big_endian(big_endian != 0); //read big endian if saved as big endian
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
fw->store_32(!big_endian);
|
||||
#else
|
||||
|
||||
fw->store_32(big_endian);
|
||||
#endif
|
||||
fw->set_big_endian(big_endian != 0);
|
||||
fw->store_32(use_real64); //use real64
|
||||
fw->set_big_endian(big_endian != 0);
|
||||
|
||||
uint32_t ver_major = f->get_32();
|
||||
uint32_t ver_minor = f->get_32();
|
||||
|
|
@ -2450,10 +2432,10 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU
|
|||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
|
||||
if (ver_format > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) {
|
||||
ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED,
|
||||
vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).",
|
||||
local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH));
|
||||
local_path, ver_format, ver_major, ver_minor, GODOT_VERSION_BRANCH));
|
||||
}
|
||||
|
||||
// Since we're not actually converting the file contents, leave the version
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RESOURCE_FORMAT_BINARY_H
|
||||
#define RESOURCE_FORMAT_BINARY_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
|
|
@ -189,5 +188,3 @@ public:
|
|||
|
||||
ResourceFormatSaverBinary();
|
||||
};
|
||||
|
||||
#endif // RESOURCE_FORMAT_BINARY_H
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/config_file.h"
|
||||
#include "core/io/image.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/variant/variant_parser.h"
|
||||
|
||||
|
|
@ -41,7 +42,7 @@ bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceIm
|
|||
return p_a->get_importer_name() < p_b->get_importer_name();
|
||||
}
|
||||
|
||||
Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const {
|
||||
Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool p_load, bool *r_valid) const {
|
||||
Error err;
|
||||
Ref<FileAccess> f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
|
||||
|
||||
|
|
@ -65,7 +66,10 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
|
|||
|
||||
int lines = 0;
|
||||
String error_text;
|
||||
bool path_found = false; //first match must have priority
|
||||
bool path_found = false; // First match must have priority.
|
||||
|
||||
String decomp_path;
|
||||
bool decomp_path_found = false;
|
||||
while (true) {
|
||||
assign = Variant();
|
||||
next_tag.fields.clear();
|
||||
|
|
@ -73,6 +77,11 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
|
|||
|
||||
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true);
|
||||
if (err == ERR_FILE_EOF) {
|
||||
if (p_load && !path_found && decomp_path_found) {
|
||||
print_verbose(vformat("No natively supported texture format found for %s, using decompressable format %s.", p_path, decomp_path));
|
||||
r_path_and_type.path = decomp_path;
|
||||
}
|
||||
|
||||
return OK;
|
||||
} else if (err != OK) {
|
||||
ERR_PRINT(vformat("ResourceFormatImporter::load - %s.import:%d error: %s.", p_path, lines, error_text));
|
||||
|
|
@ -84,12 +93,15 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
|
|||
String feature = assign.get_slicec('.', 1);
|
||||
if (OS::get_singleton()->has_feature(feature)) {
|
||||
r_path_and_type.path = value;
|
||||
path_found = true; //first match must have priority
|
||||
path_found = true; // First match must have priority.
|
||||
} else if (p_load && Image::can_decompress(feature) && !decomp_path_found) { // When loading, check for decompressable formats and use first one found if nothing else is supported.
|
||||
decomp_path = value;
|
||||
decomp_path_found = true; // First match must have priority.
|
||||
}
|
||||
|
||||
} else if (!path_found && assign == "path") {
|
||||
r_path_and_type.path = value;
|
||||
path_found = true; //first match must have priority
|
||||
path_found = true; // First match must have priority.
|
||||
} else if (assign == "type") {
|
||||
r_path_and_type.type = ClassDB::get_compatibility_remapped_class(value);
|
||||
} else if (assign == "importer") {
|
||||
|
|
@ -154,7 +166,7 @@ Ref<Resource> ResourceFormatImporter::load(const String &p_path, const String &p
|
|||
|
||||
Ref<Resource> ResourceFormatImporter::load_internal(const String &p_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode, bool p_silence_errors) {
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
Error err = _get_path_and_type(p_path, pat, true);
|
||||
|
||||
if (err != OK) {
|
||||
if (r_error) {
|
||||
|
|
@ -244,13 +256,13 @@ Error ResourceFormatImporter::get_import_order_threads_and_importer(const String
|
|||
|
||||
if (FileAccess::exists(p_path + ".import")) {
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
Error err = _get_path_and_type(p_path, pat, false);
|
||||
|
||||
if (err == OK) {
|
||||
importer = get_importer_by_name(pat.importer);
|
||||
}
|
||||
} else {
|
||||
importer = get_importer_by_extension(p_path.get_extension().to_lower());
|
||||
importer = get_importer_by_file(p_path);
|
||||
}
|
||||
|
||||
if (importer.is_valid()) {
|
||||
|
|
@ -268,13 +280,13 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const {
|
|||
|
||||
if (FileAccess::exists(p_path + ".import")) {
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
Error err = _get_path_and_type(p_path, pat, false);
|
||||
|
||||
if (err == OK) {
|
||||
importer = get_importer_by_name(pat.importer);
|
||||
}
|
||||
} else {
|
||||
importer = get_importer_by_extension(p_path.get_extension().to_lower());
|
||||
importer = get_importer_by_file(p_path);
|
||||
}
|
||||
|
||||
if (importer.is_valid()) {
|
||||
|
|
@ -300,7 +312,7 @@ bool ResourceFormatImporter::handles_type(const String &p_type) const {
|
|||
|
||||
String ResourceFormatImporter::get_internal_resource_path(const String &p_path) const {
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
Error err = _get_path_and_type(p_path, pat, false);
|
||||
|
||||
if (err != OK) {
|
||||
return String();
|
||||
|
|
@ -354,20 +366,20 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
|
|||
String ResourceFormatImporter::get_import_group_file(const String &p_path) const {
|
||||
bool valid = true;
|
||||
PathAndType pat;
|
||||
_get_path_and_type(p_path, pat, &valid);
|
||||
_get_path_and_type(p_path, pat, false, &valid);
|
||||
return valid ? pat.group_file : String();
|
||||
}
|
||||
|
||||
bool ResourceFormatImporter::is_import_valid(const String &p_path) const {
|
||||
bool valid = true;
|
||||
PathAndType pat;
|
||||
_get_path_and_type(p_path, pat, &valid);
|
||||
_get_path_and_type(p_path, pat, false, &valid);
|
||||
return valid;
|
||||
}
|
||||
|
||||
String ResourceFormatImporter::get_resource_type(const String &p_path) const {
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
Error err = _get_path_and_type(p_path, pat, false);
|
||||
|
||||
if (err != OK) {
|
||||
return "";
|
||||
|
|
@ -378,7 +390,7 @@ String ResourceFormatImporter::get_resource_type(const String &p_path) const {
|
|||
|
||||
ResourceUID::ID ResourceFormatImporter::get_resource_uid(const String &p_path) const {
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
Error err = _get_path_and_type(p_path, pat, false);
|
||||
|
||||
if (err != OK) {
|
||||
return ResourceUID::INVALID_ID;
|
||||
|
|
@ -393,7 +405,7 @@ bool ResourceFormatImporter::has_custom_uid_support() const {
|
|||
|
||||
Error ResourceFormatImporter::get_resource_import_info(const String &p_path, StringName &r_type, ResourceUID::ID &r_uid, String &r_import_group_file) const {
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
Error err = _get_path_and_type(p_path, pat, false);
|
||||
|
||||
if (err == OK) {
|
||||
r_type = pat.type;
|
||||
|
|
@ -410,7 +422,7 @@ Error ResourceFormatImporter::get_resource_import_info(const String &p_path, Str
|
|||
|
||||
Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) const {
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
Error err = _get_path_and_type(p_path, pat, false);
|
||||
|
||||
if (err != OK) {
|
||||
return Variant();
|
||||
|
|
@ -420,7 +432,7 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons
|
|||
}
|
||||
void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) {
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
Error err = _get_path_and_type(p_path, pat, false);
|
||||
|
||||
if (err != OK) {
|
||||
return;
|
||||
|
|
@ -431,7 +443,7 @@ void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet<Stri
|
|||
|
||||
void ResourceFormatImporter::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
Error err = _get_path_and_type(p_path, pat, false);
|
||||
|
||||
if (err != OK) {
|
||||
return;
|
||||
|
|
@ -459,12 +471,12 @@ void ResourceFormatImporter::add_importer(const Ref<ResourceImporter> &p_importe
|
|||
}
|
||||
}
|
||||
|
||||
void ResourceFormatImporter::get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter>> *r_importers) {
|
||||
void ResourceFormatImporter::get_importers_for_file(const String &p_file, List<Ref<ResourceImporter>> *r_importers) {
|
||||
for (int i = 0; i < importers.size(); i++) {
|
||||
List<String> local_exts;
|
||||
importers[i]->get_recognized_extensions(&local_exts);
|
||||
for (const String &F : local_exts) {
|
||||
if (p_extension.to_lower() == F) {
|
||||
if (p_file.right(F.length()).nocasecmp_to(F) == 0) {
|
||||
r_importers->push_back(importers[i]);
|
||||
break;
|
||||
}
|
||||
|
|
@ -478,7 +490,7 @@ void ResourceFormatImporter::get_importers(List<Ref<ResourceImporter>> *r_import
|
|||
}
|
||||
}
|
||||
|
||||
Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const String &p_extension) const {
|
||||
Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_file(const String &p_file) const {
|
||||
Ref<ResourceImporter> importer;
|
||||
float priority = 0;
|
||||
|
||||
|
|
@ -486,9 +498,10 @@ Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const St
|
|||
List<String> local_exts;
|
||||
importers[i]->get_recognized_extensions(&local_exts);
|
||||
for (const String &F : local_exts) {
|
||||
if (p_extension.to_lower() == F && importers[i]->get_priority() > priority) {
|
||||
if (p_file.right(F.length()).nocasecmp_to(F) == 0 && importers[i]->get_priority() > priority) {
|
||||
importer = importers[i];
|
||||
priority = importers[i]->get_priority();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -503,7 +516,7 @@ String ResourceFormatImporter::get_import_base_path(const String &p_for_file) co
|
|||
bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) const {
|
||||
bool valid = true;
|
||||
PathAndType pat;
|
||||
_get_path_and_type(p_path, pat, &valid);
|
||||
_get_path_and_type(p_path, pat, false, &valid);
|
||||
|
||||
if (!valid) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RESOURCE_IMPORTER_H
|
||||
#define RESOURCE_IMPORTER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "core/io/resource_saver.h"
|
||||
|
|
@ -49,7 +48,7 @@ class ResourceFormatImporter : public ResourceFormatLoader {
|
|||
ResourceUID::ID uid = ResourceUID::INVALID_ID;
|
||||
};
|
||||
|
||||
Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = nullptr) const;
|
||||
Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool p_load, bool *r_valid = nullptr) const;
|
||||
|
||||
static ResourceFormatImporter *singleton;
|
||||
|
||||
|
|
@ -90,8 +89,8 @@ public:
|
|||
|
||||
void remove_importer(const Ref<ResourceImporter> &p_importer) { importers.erase(p_importer); }
|
||||
Ref<ResourceImporter> get_importer_by_name(const String &p_name) const;
|
||||
Ref<ResourceImporter> get_importer_by_extension(const String &p_extension) const;
|
||||
void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter>> *r_importers);
|
||||
Ref<ResourceImporter> get_importer_by_file(const String &p_file) const;
|
||||
void get_importers_for_file(const String &p_file, List<Ref<ResourceImporter>> *r_importers);
|
||||
void get_importers(List<Ref<ResourceImporter>> *r_importers);
|
||||
|
||||
bool are_import_settings_valid(const String &p_path) const;
|
||||
|
|
@ -166,5 +165,3 @@ class ResourceFormatImporterSaver : public ResourceFormatSaver {
|
|||
public:
|
||||
virtual Error set_uid(const String &p_path, ResourceUID::ID p_uid) override;
|
||||
};
|
||||
|
||||
#endif // RESOURCE_IMPORTER_H
|
||||
|
|
|
|||
|
|
@ -61,8 +61,6 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_
|
|||
return ret;
|
||||
}
|
||||
|
||||
String extension = p_path.get_extension();
|
||||
|
||||
List<String> extensions;
|
||||
if (p_for_type.is_empty()) {
|
||||
get_recognized_extensions(&extensions);
|
||||
|
|
@ -71,7 +69,8 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_
|
|||
}
|
||||
|
||||
for (const String &E : extensions) {
|
||||
if (E.nocasecmp_to(extension) == 0) {
|
||||
const String ext = !E.begins_with(".") ? "." + E : E;
|
||||
if (p_path.right(ext.length()).nocasecmp_to(ext) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -264,6 +263,14 @@ void ResourceLoader::LoadToken::clear() {
|
|||
thread_load_tasks.erase(local_path);
|
||||
}
|
||||
local_path.clear(); // Mark as already cleared.
|
||||
if (task_to_await) {
|
||||
for (KeyValue<String, ResourceLoader::ThreadLoadTask> &E : thread_load_tasks) {
|
||||
if (E.value.task_id == task_to_await) {
|
||||
task_to_await = 0;
|
||||
break; // Same task is reused by nested loads, do not wait for completion here.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +329,7 @@ Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_origin
|
|||
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
if (ResourceFormatImporter::get_singleton()->get_importer_by_extension(p_path.get_extension()).is_valid()) {
|
||||
if (ResourceFormatImporter::get_singleton()->get_importer_by_file(p_path).is_valid()) {
|
||||
// The format is known to the editor, but the file hasn't been imported
|
||||
// (otherwise, ResourceFormatImporter would have been found as a suitable loader).
|
||||
found = true;
|
||||
|
|
@ -772,6 +779,10 @@ Ref<Resource> ResourceLoader::_load_complete(LoadToken &p_load_token, Error *r_e
|
|||
return _load_complete_inner(p_load_token, r_error, thread_load_lock);
|
||||
}
|
||||
|
||||
void ResourceLoader::set_is_import_thread(bool p_import_thread) {
|
||||
import_thread = p_import_thread;
|
||||
}
|
||||
|
||||
Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Error *r_error, MutexLock<SafeBinaryMutex<BINARY_MUTEX_TAG>> &p_thread_load_lock) {
|
||||
if (r_error) {
|
||||
*r_error = OK;
|
||||
|
|
@ -825,6 +836,12 @@ Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro
|
|||
|
||||
p_thread_load_lock.temp_relock();
|
||||
load_task.awaited = true;
|
||||
// Mark nested loads with the same task id as awaited.
|
||||
for (KeyValue<String, ResourceLoader::ThreadLoadTask> &E : thread_load_tasks) {
|
||||
if (E.value.task_id == load_task.task_id) {
|
||||
E.value.awaited = true;
|
||||
}
|
||||
}
|
||||
|
||||
DEV_ASSERT(load_task.status == THREAD_LOAD_FAILED || load_task.status == THREAD_LOAD_LOADED);
|
||||
} else if (load_task.need_wait) {
|
||||
|
|
@ -886,9 +903,11 @@ Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro
|
|||
MessageQueue::get_main_singleton()->push_callable(callable_mp(rcc.source, &Resource::connect_changed).bind(rcc.callable, rcc.flags));
|
||||
}
|
||||
}
|
||||
core_bind::Semaphore done;
|
||||
MessageQueue::get_main_singleton()->push_callable(callable_mp(&done, &core_bind::Semaphore::post).bind(1));
|
||||
done.wait();
|
||||
if (!import_thread) { // Main thread is blocked by initial resource reimport, do not wait.
|
||||
CoreBind::Semaphore done;
|
||||
MessageQueue::get_main_singleton()->push_callable(callable_mp(&done, &CoreBind::Semaphore::post).bind(1));
|
||||
done.wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1339,10 +1358,8 @@ void ResourceLoader::load_translation_remaps() {
|
|||
}
|
||||
|
||||
Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps");
|
||||
List<Variant> keys;
|
||||
remaps.get_key_list(&keys);
|
||||
for (const Variant &E : keys) {
|
||||
Array langs = remaps[E];
|
||||
for (const KeyValue<Variant, Variant> &kv : remaps) {
|
||||
Array langs = kv.value;
|
||||
Vector<String> lang_remaps;
|
||||
lang_remaps.resize(langs.size());
|
||||
String *lang_remaps_ptrw = lang_remaps.ptrw();
|
||||
|
|
@ -1350,7 +1367,7 @@ void ResourceLoader::load_translation_remaps() {
|
|||
*lang_remaps_ptrw++ = lang;
|
||||
}
|
||||
|
||||
translation_remaps[String(E)] = lang_remaps;
|
||||
translation_remaps[String(kv.key)] = lang_remaps;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1565,6 +1582,7 @@ bool ResourceLoader::create_missing_resources_if_class_unavailable = false;
|
|||
bool ResourceLoader::abort_on_missing_resource = true;
|
||||
bool ResourceLoader::timestamp_on_load = false;
|
||||
|
||||
thread_local bool ResourceLoader::import_thread = false;
|
||||
thread_local int ResourceLoader::load_nesting = 0;
|
||||
thread_local Vector<String> ResourceLoader::load_paths_stack;
|
||||
thread_local HashMap<int, HashMap<String, Ref<Resource>>> ResourceLoader::res_ref_overrides;
|
||||
|
|
|
|||
|
|
@ -28,15 +28,14 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RESOURCE_LOADER_H
|
||||
#define RESOURCE_LOADER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource.h"
|
||||
#include "core/object/gdvirtual.gen.inc"
|
||||
#include "core/object/worker_thread_pool.h"
|
||||
#include "core/os/thread.h"
|
||||
|
||||
namespace core_bind {
|
||||
namespace CoreBind {
|
||||
class ResourceLoader;
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +104,7 @@ typedef void (*ResourceLoadedCallback)(Ref<Resource> p_resource, const String &p
|
|||
|
||||
class ResourceLoader {
|
||||
friend class LoadToken;
|
||||
friend class core_bind::ResourceLoader;
|
||||
friend class CoreBind::ResourceLoader;
|
||||
|
||||
enum {
|
||||
MAX_LOADERS = 64
|
||||
|
|
@ -205,6 +204,7 @@ private:
|
|||
|
||||
static void _run_load_task(void *p_userdata);
|
||||
|
||||
static thread_local bool import_thread;
|
||||
static thread_local int load_nesting;
|
||||
static thread_local HashMap<int, HashMap<String, Ref<Resource>>> res_ref_overrides; // Outermost key is nesting level.
|
||||
static thread_local Vector<String> load_paths_stack;
|
||||
|
|
@ -254,6 +254,8 @@ public:
|
|||
static bool is_imported(const String &p_path);
|
||||
static int get_import_order(const String &p_path);
|
||||
|
||||
static void set_is_import_thread(bool p_import_thread);
|
||||
|
||||
static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; }
|
||||
static bool get_timestamp_on_load() { return timestamp_on_load; }
|
||||
|
||||
|
|
@ -316,5 +318,3 @@ public:
|
|||
static void initialize();
|
||||
static void finalize();
|
||||
};
|
||||
|
||||
#endif // RESOURCE_LOADER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RESOURCE_SAVER_H
|
||||
#define RESOURCE_SAVER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource.h"
|
||||
#include "core/object/gdvirtual.gen.inc"
|
||||
|
|
@ -103,5 +102,3 @@ public:
|
|||
static void add_custom_savers();
|
||||
static void remove_custom_savers();
|
||||
};
|
||||
|
||||
#endif // RESOURCE_SAVER_H
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "core/io/dir_access.h"
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "core/math/random_pcg.h"
|
||||
|
||||
// These constants are off by 1, causing the 'z' and '9' characters never to be used.
|
||||
// This cannot be fixed without breaking compatibility; see GH-83843.
|
||||
|
|
@ -46,7 +47,7 @@ String ResourceUID::get_cache_file() {
|
|||
}
|
||||
|
||||
static constexpr uint8_t uuid_characters[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', '0', '1', '2', '3', '4', '5', '6', '7', '8' };
|
||||
static constexpr uint32_t uuid_characters_element_count = (sizeof(uuid_characters) / sizeof(*uuid_characters));
|
||||
static constexpr uint32_t uuid_characters_element_count = std::size(uuid_characters);
|
||||
static constexpr uint8_t max_uuid_number_length = 13; // Max 0x7FFFFFFFFFFFFFFF (uid://d4n4ub6itg400) size is 13 characters.
|
||||
|
||||
String ResourceUID::id_to_text(ID p_id) const {
|
||||
|
|
@ -121,10 +122,31 @@ ResourceUID::ID ResourceUID::create_id() {
|
|||
}
|
||||
}
|
||||
|
||||
ResourceUID::ID ResourceUID::create_id_for_path(const String &p_path) {
|
||||
ID id = INVALID_ID;
|
||||
RandomPCG rng;
|
||||
|
||||
const String project_name = GLOBAL_GET("application/config/name");
|
||||
rng.seed(project_name.hash64() * p_path.hash64() * FileAccess::get_md5(p_path).hash64());
|
||||
|
||||
while (true) {
|
||||
int64_t num1 = rng.rand();
|
||||
int64_t num2 = ((int64_t)rng.rand()) << 32;
|
||||
id = (num1 | num2) & 0x7FFFFFFFFFFFFFFF;
|
||||
|
||||
MutexLock lock(mutex);
|
||||
if (!unique_ids.has(id)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
bool ResourceUID::has_id(ID p_id) const {
|
||||
MutexLock l(mutex);
|
||||
return unique_ids.has(p_id);
|
||||
}
|
||||
|
||||
void ResourceUID::add_id(ID p_id, const String &p_path) {
|
||||
MutexLock l(mutex);
|
||||
ERR_FAIL_COND(unique_ids.has(p_id));
|
||||
|
|
@ -311,7 +333,7 @@ String ResourceUID::get_path_from_cache(Ref<FileAccess> &p_cache_file, const Str
|
|||
ERR_FAIL_COND_V(rl != len, String());
|
||||
|
||||
if (singleton->id_to_text(id) == p_uid_string) {
|
||||
return String(cs);
|
||||
return String::utf8(cs.get_data());
|
||||
}
|
||||
}
|
||||
return String();
|
||||
|
|
@ -327,6 +349,7 @@ void ResourceUID::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("text_to_id", "text_id"), &ResourceUID::text_to_id);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("create_id"), &ResourceUID::create_id);
|
||||
ClassDB::bind_method(D_METHOD("create_id_for_path", "path"), &ResourceUID::create_id_for_path);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("has_id", "id"), &ResourceUID::has_id);
|
||||
ClassDB::bind_method(D_METHOD("add_id", "id", "path"), &ResourceUID::add_id);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RESOURCE_UID_H
|
||||
#define RESOURCE_UID_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/ref_counted.h"
|
||||
#include "core/string/string_name.h"
|
||||
|
|
@ -71,6 +70,7 @@ public:
|
|||
ID text_to_id(const String &p_text) const;
|
||||
|
||||
ID create_id();
|
||||
ID create_id_for_path(const String &p_path);
|
||||
bool has_id(ID p_id) const;
|
||||
void add_id(ID p_id, const String &p_path);
|
||||
void set_id(ID p_id, const String &p_path);
|
||||
|
|
@ -93,5 +93,3 @@ public:
|
|||
ResourceUID();
|
||||
~ResourceUID();
|
||||
};
|
||||
|
||||
#endif // RESOURCE_UID_H
|
||||
|
|
|
|||
|
|
@ -125,54 +125,90 @@ void StreamPeer::put_8(int8_t p_val) {
|
|||
}
|
||||
|
||||
void StreamPeer::put_u16(uint16_t p_val) {
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
p_val = BSWAP16(p_val);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
p_val = BSWAP16(p_val);
|
||||
}
|
||||
#endif
|
||||
uint8_t buf[2];
|
||||
encode_uint16(p_val, buf);
|
||||
put_data(buf, 2);
|
||||
}
|
||||
|
||||
void StreamPeer::put_16(int16_t p_val) {
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
p_val = BSWAP16(p_val);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
p_val = BSWAP16(p_val);
|
||||
}
|
||||
#endif
|
||||
uint8_t buf[2];
|
||||
encode_uint16(p_val, buf);
|
||||
put_data(buf, 2);
|
||||
}
|
||||
|
||||
void StreamPeer::put_u32(uint32_t p_val) {
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
p_val = BSWAP32(p_val);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
p_val = BSWAP32(p_val);
|
||||
}
|
||||
#endif
|
||||
uint8_t buf[4];
|
||||
encode_uint32(p_val, buf);
|
||||
put_data(buf, 4);
|
||||
}
|
||||
|
||||
void StreamPeer::put_32(int32_t p_val) {
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
p_val = BSWAP32(p_val);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
p_val = BSWAP32(p_val);
|
||||
}
|
||||
#endif
|
||||
uint8_t buf[4];
|
||||
encode_uint32(p_val, buf);
|
||||
put_data(buf, 4);
|
||||
}
|
||||
|
||||
void StreamPeer::put_u64(uint64_t p_val) {
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
p_val = BSWAP64(p_val);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
p_val = BSWAP64(p_val);
|
||||
}
|
||||
#endif
|
||||
uint8_t buf[8];
|
||||
encode_uint64(p_val, buf);
|
||||
put_data(buf, 8);
|
||||
}
|
||||
|
||||
void StreamPeer::put_64(int64_t p_val) {
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
p_val = BSWAP64(p_val);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
p_val = BSWAP64(p_val);
|
||||
}
|
||||
#endif
|
||||
uint8_t buf[8];
|
||||
encode_uint64(p_val, buf);
|
||||
put_data(buf, 8);
|
||||
|
|
@ -183,9 +219,15 @@ void StreamPeer::put_half(float p_val) {
|
|||
|
||||
encode_half(p_val, buf);
|
||||
uint16_t *p16 = (uint16_t *)buf;
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
*p16 = BSWAP16(*p16);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
*p16 = BSWAP16(*p16);
|
||||
}
|
||||
#endif
|
||||
|
||||
put_data(buf, 2);
|
||||
}
|
||||
|
|
@ -194,10 +236,17 @@ void StreamPeer::put_float(float p_val) {
|
|||
uint8_t buf[4];
|
||||
|
||||
encode_float(p_val, buf);
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
uint32_t *p32 = (uint32_t *)buf;
|
||||
*p32 = BSWAP32(*p32);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
uint32_t *p32 = (uint32_t *)buf;
|
||||
*p32 = BSWAP32(*p32);
|
||||
}
|
||||
#endif
|
||||
|
||||
put_data(buf, 4);
|
||||
}
|
||||
|
|
@ -206,10 +255,17 @@ void StreamPeer::put_double(double p_val) {
|
|||
uint8_t buf[8];
|
||||
|
||||
encode_double(p_val, buf);
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
uint64_t *p64 = (uint64_t *)buf;
|
||||
*p64 = BSWAP64(*p64);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
uint64_t *p64 = (uint64_t *)buf;
|
||||
*p64 = BSWAP64(*p64);
|
||||
}
|
||||
#endif
|
||||
|
||||
put_data(buf, 8);
|
||||
}
|
||||
|
|
@ -253,9 +309,15 @@ uint16_t StreamPeer::get_u16() {
|
|||
get_data(buf, 2);
|
||||
|
||||
uint16_t r = decode_uint16(buf);
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
r = BSWAP16(r);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
r = BSWAP16(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
@ -265,9 +327,15 @@ int16_t StreamPeer::get_16() {
|
|||
get_data(buf, 2);
|
||||
|
||||
uint16_t r = decode_uint16(buf);
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
r = BSWAP16(r);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
r = BSWAP16(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
return int16_t(r);
|
||||
}
|
||||
|
|
@ -277,9 +345,15 @@ uint32_t StreamPeer::get_u32() {
|
|||
get_data(buf, 4);
|
||||
|
||||
uint32_t r = decode_uint32(buf);
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
r = BSWAP32(r);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
r = BSWAP32(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
@ -289,9 +363,15 @@ int32_t StreamPeer::get_32() {
|
|||
get_data(buf, 4);
|
||||
|
||||
uint32_t r = decode_uint32(buf);
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
r = BSWAP32(r);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
r = BSWAP32(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
return int32_t(r);
|
||||
}
|
||||
|
|
@ -301,9 +381,15 @@ uint64_t StreamPeer::get_u64() {
|
|||
get_data(buf, 8);
|
||||
|
||||
uint64_t r = decode_uint64(buf);
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
r = BSWAP64(r);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
r = BSWAP64(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
@ -313,9 +399,15 @@ int64_t StreamPeer::get_64() {
|
|||
get_data(buf, 8);
|
||||
|
||||
uint64_t r = decode_uint64(buf);
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
r = BSWAP64(r);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
r = BSWAP64(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
return int64_t(r);
|
||||
}
|
||||
|
|
@ -324,10 +416,17 @@ float StreamPeer::get_half() {
|
|||
uint8_t buf[2];
|
||||
get_data(buf, 2);
|
||||
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
uint16_t *p16 = (uint16_t *)buf;
|
||||
*p16 = BSWAP16(*p16);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
uint16_t *p16 = (uint16_t *)buf;
|
||||
*p16 = BSWAP16(*p16);
|
||||
}
|
||||
#endif
|
||||
|
||||
return decode_half(buf);
|
||||
}
|
||||
|
|
@ -336,10 +435,17 @@ float StreamPeer::get_float() {
|
|||
uint8_t buf[4];
|
||||
get_data(buf, 4);
|
||||
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
uint32_t *p32 = (uint32_t *)buf;
|
||||
*p32 = BSWAP32(*p32);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
uint32_t *p32 = (uint32_t *)buf;
|
||||
*p32 = BSWAP32(*p32);
|
||||
}
|
||||
#endif
|
||||
|
||||
return decode_float(buf);
|
||||
}
|
||||
|
|
@ -348,10 +454,17 @@ double StreamPeer::get_double() {
|
|||
uint8_t buf[8];
|
||||
get_data(buf, 8);
|
||||
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
if (!big_endian) {
|
||||
uint64_t *p64 = (uint64_t *)buf;
|
||||
*p64 = BSWAP64(*p64);
|
||||
}
|
||||
#else
|
||||
if (big_endian) {
|
||||
uint64_t *p64 = (uint64_t *)buf;
|
||||
*p64 = BSWAP64(*p64);
|
||||
}
|
||||
#endif
|
||||
|
||||
return decode_double(buf);
|
||||
}
|
||||
|
|
@ -383,9 +496,7 @@ String StreamPeer::get_utf8_string(int p_bytes) {
|
|||
err = get_data(buf.ptrw(), p_bytes);
|
||||
ERR_FAIL_COND_V(err != OK, String());
|
||||
|
||||
String ret;
|
||||
ret.parse_utf8((const char *)buf.ptr(), buf.size());
|
||||
return ret;
|
||||
return String::utf8((const char *)buf.ptr(), buf.size());
|
||||
}
|
||||
|
||||
Variant StreamPeer::get_var(bool p_allow_objects) {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef STREAM_PEER_H
|
||||
#define STREAM_PEER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/ref_counted.h"
|
||||
|
||||
|
|
@ -50,7 +49,11 @@ protected:
|
|||
Array _get_data(int p_bytes);
|
||||
Array _get_partial_data(int p_bytes);
|
||||
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
bool big_endian = true;
|
||||
#else
|
||||
bool big_endian = false;
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual Error put_data(const uint8_t *p_data, int p_bytes) = 0; ///< put a whole chunk of data, blocking until it sent
|
||||
|
|
@ -152,5 +155,3 @@ public:
|
|||
|
||||
StreamPeerBuffer() {}
|
||||
};
|
||||
|
||||
#endif // STREAM_PEER_H
|
||||
|
|
|
|||
|
|
@ -195,12 +195,12 @@ int StreamPeerGZIP::get_available_bytes() const {
|
|||
Error StreamPeerGZIP::finish() {
|
||||
ERR_FAIL_COND_V(!ctx || !compressing, ERR_UNAVAILABLE);
|
||||
// Ensure we have enough space in temporary buffer.
|
||||
if (buffer.size() < 1024) {
|
||||
buffer.resize(1024); // 1024 should be more than enough.
|
||||
if (buffer.size() < get_available_bytes()) {
|
||||
buffer.resize(get_available_bytes()); // get_available_bytes() is what we can store in RingBuffer.
|
||||
}
|
||||
int consumed = 0;
|
||||
int to_write = 0;
|
||||
Error err = _process(buffer.ptrw(), 1024, nullptr, 0, consumed, to_write, true); // compress
|
||||
Error err = _process(buffer.ptrw(), buffer.size(), nullptr, 0, consumed, to_write, true); // compress
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef STREAM_PEER_GZIP_H
|
||||
#define STREAM_PEER_GZIP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/stream_peer.h"
|
||||
|
||||
|
|
@ -72,5 +71,3 @@ public:
|
|||
StreamPeerGZIP();
|
||||
~StreamPeerGZIP();
|
||||
};
|
||||
|
||||
#endif // STREAM_PEER_GZIP_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef STREAM_PEER_TCP_H
|
||||
#define STREAM_PEER_TCP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/ip.h"
|
||||
#include "core/io/ip_address.h"
|
||||
|
|
@ -92,5 +91,3 @@ public:
|
|||
};
|
||||
|
||||
VARIANT_ENUM_CAST(StreamPeerTCP::Status);
|
||||
|
||||
#endif // STREAM_PEER_TCP_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef STREAM_PEER_TLS_H
|
||||
#define STREAM_PEER_TLS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/crypto/crypto.h"
|
||||
#include "core/io/stream_peer.h"
|
||||
|
|
@ -66,5 +65,3 @@ public:
|
|||
};
|
||||
|
||||
VARIANT_ENUM_CAST(StreamPeerTLS::Status);
|
||||
|
||||
#endif // STREAM_PEER_TLS_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TCP_SERVER_H
|
||||
#define TCP_SERVER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/ip.h"
|
||||
#include "core/io/net_socket.h"
|
||||
|
|
@ -59,5 +58,3 @@ public:
|
|||
TCPServer();
|
||||
~TCPServer();
|
||||
};
|
||||
|
||||
#endif // TCP_SERVER_H
|
||||
|
|
|
|||
|
|
@ -76,14 +76,17 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
|
|||
bool is_plural = false;
|
||||
for (uint32_t j = 0; j < str_len + 1; j++) {
|
||||
if (data[j] == 0x04) {
|
||||
msg_context.parse_utf8((const char *)data.ptr(), j);
|
||||
msg_context.clear();
|
||||
msg_context.append_utf8((const char *)data.ptr(), j);
|
||||
str_start = j + 1;
|
||||
}
|
||||
if (data[j] == 0x00) {
|
||||
if (is_plural) {
|
||||
msg_id_plural.parse_utf8((const char *)(data.ptr() + str_start), j - str_start);
|
||||
msg_id_plural.clear();
|
||||
msg_id_plural.append_utf8((const char *)(data.ptr() + str_start), j - str_start);
|
||||
} else {
|
||||
msg_id.parse_utf8((const char *)(data.ptr() + str_start), j - str_start);
|
||||
msg_id.clear();
|
||||
msg_id.append_utf8((const char *)(data.ptr() + str_start), j - str_start);
|
||||
is_plural = true;
|
||||
}
|
||||
str_start = j + 1;
|
||||
|
|
@ -189,7 +192,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
|
|||
}
|
||||
}
|
||||
msg_context = "";
|
||||
l = l.substr(7, l.length()).strip_edges();
|
||||
l = l.substr(7).strip_edges();
|
||||
status = STATUS_READING_CONTEXT;
|
||||
entered_context = true;
|
||||
}
|
||||
|
|
@ -202,7 +205,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
|
|||
}
|
||||
// We don't record the message in "msgid_plural" itself as tr_n(), TTRN(), RTRN() interfaces provide the plural string already.
|
||||
// We just have to reset variables related to plurals for "msgstr[]" later on.
|
||||
l = l.substr(12, l.length()).strip_edges();
|
||||
l = l.substr(12).strip_edges();
|
||||
plural_index = -1;
|
||||
msgs_plural.clear();
|
||||
msgs_plural.resize(plural_forms);
|
||||
|
|
@ -230,7 +233,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
|
|||
}
|
||||
}
|
||||
|
||||
l = l.substr(5, l.length()).strip_edges();
|
||||
l = l.substr(5).strip_edges();
|
||||
status = STATUS_READING_ID;
|
||||
// If we did not encounter msgctxt, we reset context to empty to reset it.
|
||||
if (!entered_context) {
|
||||
|
|
@ -246,10 +249,10 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
|
|||
if (l.begins_with("msgstr[")) {
|
||||
ERR_FAIL_COND_V_MSG(status != STATUS_READING_PLURAL, Ref<Resource>(), vformat("Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: %s:%d.", path, line));
|
||||
plural_index++; // Increment to add to the next slot in vector msgs_plural.
|
||||
l = l.substr(9, l.length()).strip_edges();
|
||||
l = l.substr(9).strip_edges();
|
||||
} else if (l.begins_with("msgstr")) {
|
||||
ERR_FAIL_COND_V_MSG(status != STATUS_READING_ID, Ref<Resource>(), vformat("Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: %s:%d.", path, line));
|
||||
l = l.substr(6, l.length()).strip_edges();
|
||||
l = l.substr(6).strip_edges();
|
||||
status = STATUS_READING_STRING;
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +266,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
|
|||
|
||||
ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, Ref<Resource>(), vformat("Invalid line '%s' while parsing: %s:%d.", l, path, line));
|
||||
|
||||
l = l.substr(1, l.length());
|
||||
l = l.substr(1);
|
||||
// Find final quote, ignoring escaped ones (\").
|
||||
// The escape_next logic is necessary to properly parse things like \\"
|
||||
// where the backslash is the one being escaped, not the quote.
|
||||
|
|
@ -329,7 +332,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_
|
|||
continue;
|
||||
}
|
||||
String prop = c.substr(0, p).strip_edges();
|
||||
String value = c.substr(p + 1, c.length()).strip_edges();
|
||||
String value = c.substr(p + 1).strip_edges();
|
||||
|
||||
if (prop == "X-Language" || prop == "Language") {
|
||||
translation->set_locale(value);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TRANSLATION_LOADER_PO_H
|
||||
#define TRANSLATION_LOADER_PO_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
|
|
@ -49,5 +48,3 @@ public:
|
|||
|
||||
TranslationLoaderPO() {}
|
||||
};
|
||||
|
||||
#endif // TRANSLATION_LOADER_PO_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef UDP_SERVER_H
|
||||
#define UDP_SERVER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/net_socket.h"
|
||||
#include "core/io/packet_peer_udp.h"
|
||||
|
|
@ -76,5 +75,3 @@ public:
|
|||
UDPServer();
|
||||
~UDPServer();
|
||||
};
|
||||
|
||||
#endif // UDP_SERVER_H
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ void XMLParser::_ignore_definition() {
|
|||
while (*P && *P != '>') {
|
||||
next_char();
|
||||
}
|
||||
node_name.parse_utf8(F, P - F);
|
||||
node_name.clear();
|
||||
node_name.append_utf8(F, P - F);
|
||||
|
||||
if (*P) {
|
||||
next_char();
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef XML_PARSER_H
|
||||
#define XML_PARSER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/ref_counted.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
|
@ -126,5 +125,3 @@ public:
|
|||
};
|
||||
|
||||
VARIANT_ENUM_CAST(XMLParser::NodeType);
|
||||
|
||||
#endif // XML_PARSER_H
|
||||
|
|
|
|||
|
|
@ -76,8 +76,7 @@ void *zipio_open(voidpf opaque, const char *p_fname, int mode) {
|
|||
Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque);
|
||||
ERR_FAIL_NULL_V(fa, nullptr);
|
||||
|
||||
String fname;
|
||||
fname.parse_utf8(p_fname);
|
||||
String fname = String::utf8(p_fname);
|
||||
|
||||
int file_access_mode = 0;
|
||||
if (mode & ZLIB_FILEFUNC_MODE_READ) {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef ZIP_IO_H
|
||||
#define ZIP_IO_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
|
||||
|
|
@ -61,5 +60,3 @@ voidpf zipio_alloc(voidpf opaque, uInt items, uInt size);
|
|||
void zipio_free(voidpf opaque, voidpf address);
|
||||
|
||||
zlib_filefunc_def zipio_create_io(Ref<FileAccess> *p_data);
|
||||
|
||||
#endif // ZIP_IO_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue