diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/bind/core_bind.cpp | 1 | ||||
-rw-r--r-- | core/bind/core_bind.h | 3 | ||||
-rw-r--r-- | core/engine.cpp | 2 | ||||
-rw-r--r-- | core/engine.h | 4 | ||||
-rw-r--r-- | core/global_config.cpp | 80 | ||||
-rw-r--r-- | core/global_config.h | 5 | ||||
-rw-r--r-- | core/io/compression.cpp | 34 | ||||
-rw-r--r-- | core/io/compression.h | 8 | ||||
-rw-r--r-- | core/io/packet_peer.cpp | 2 | ||||
-rw-r--r-- | core/io/resource_format_binary.cpp | 73 | ||||
-rw-r--r-- | core/math/audio_frame.h | 10 | ||||
-rw-r--r-- | core/math/vector3.h | 6 | ||||
-rw-r--r-- | core/message_queue.cpp | 2 | ||||
-rw-r--r-- | core/object.cpp | 26 | ||||
-rw-r--r-- | core/object.h | 9 | ||||
-rw-r--r-- | core/os/os.cpp | 2 | ||||
-rw-r--r-- | core/register_core_types.cpp | 2 | ||||
-rw-r--r-- | core/safe_refcount.cpp | 189 | ||||
-rw-r--r-- | core/safe_refcount.h | 8 | ||||
-rw-r--r-- | core/script_debugger_remote.cpp | 4 | ||||
-rw-r--r-- | core/script_language.cpp | 5 | ||||
-rw-r--r-- | core/script_language.h | 5 | ||||
-rw-r--r-- | core/self_list.h | 19 | ||||
-rw-r--r-- | core/variant_call.cpp | 2 |
24 files changed, 392 insertions, 109 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index e863078a48..a5ec9c1afc 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -1780,6 +1780,7 @@ void _File::_bind_methods() { BIND_CONSTANT(COMPRESSION_FASTLZ); BIND_CONSTANT(COMPRESSION_DEFLATE); BIND_CONSTANT(COMPRESSION_ZSTD); + BIND_CONSTANT(COMPRESSION_GZIP); } _File::_File() { diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index f72f665d9e..ec4fd3f476 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -372,7 +372,8 @@ public: enum CompressionMode { COMPRESSION_FASTLZ = Compression::MODE_FASTLZ, COMPRESSION_DEFLATE = Compression::MODE_DEFLATE, - COMPRESSION_ZSTD = Compression::MODE_ZSTD + COMPRESSION_ZSTD = Compression::MODE_ZSTD, + COMPRESSION_GZIP = Compression::MODE_GZIP }; Error open_encrypted(const String &p_path, int p_mode_flags, const Vector<uint8_t> &p_key); diff --git a/core/engine.cpp b/core/engine.cpp index 42850325b4..c16a2903d3 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -119,4 +119,6 @@ Engine::Engine() { _fixed_frames = 0; _idle_frames = 0; _in_fixed = false; + _frame_ticks = 0; + _frame_step = 0; } diff --git a/core/engine.h b/core/engine.h index 80b11c095d..16dfb77593 100644 --- a/core/engine.h +++ b/core/engine.h @@ -42,6 +42,8 @@ class Engine { String _custom_level; uint64_t frames_drawn; uint32_t _frame_delay; + uint64_t _frame_ticks; + float _frame_step; int ips; float _fps; @@ -72,6 +74,8 @@ public: uint64_t get_fixed_frames() const { return _fixed_frames; } uint64_t get_idle_frames() const { return _idle_frames; } bool is_in_fixed_frame() const { return _in_fixed; } + uint64_t get_idle_frame_ticks() const { return _frame_ticks; } + float get_idle_frame_step() const { return _frame_step; } void set_time_scale(float p_scale); float get_time_scale() const; diff --git a/core/global_config.cpp b/core/global_config.cpp index caae73ee2e..95f4ec5e22 100644 --- a/core/global_config.cpp +++ b/core/global_config.cpp @@ -130,33 +130,8 @@ bool GlobalConfig::_set(const StringName &p_name, const Variant &p_value) { if (!props[p_name].overrided) props[p_name].variant = p_value; - if (props[p_name].order >= NO_ORDER_BASE && registering_order) { - props[p_name].order = last_order++; - } } else { - props[p_name] = VariantContainer(p_value, last_order++ + (registering_order ? 0 : NO_ORDER_BASE)); - } - } - - if (!disable_platform_override) { - - String s = String(p_name); - int sl = s.find("/"); - int p = s.find("."); - if (p != -1 && sl != -1 && p < sl) { - - Vector<String> ps = s.substr(0, sl).split("."); - String prop = s.substr(sl, s.length() - sl); - for (int i = 1; i < ps.size(); i++) { - - if (ps[i] == OS::get_singleton()->get_name()) { - - String fullprop = ps[0] + prop; - - set(fullprop, p_value); - props[fullprop].overrided = true; - } - } + props[p_name] = VariantContainer(p_value, last_order++); } } @@ -372,8 +347,6 @@ Error GlobalConfig::_load_settings_binary(const String p_path) { ERR_FAIL_V(ERR_FILE_CORRUPT;) } - set_registering_order(false); - uint32_t count = f->get_32(); for (uint32_t i = 0; i < count; i++) { @@ -397,8 +370,6 @@ Error GlobalConfig::_load_settings_binary(const String p_path) { set(key, value); } - set_registering_order(true); - return OK; } Error GlobalConfig::_load_settings(const String p_path) { @@ -468,6 +439,14 @@ void GlobalConfig::set_order(const String &p_name, int p_order) { props[p_name].order = p_order; } +void GlobalConfig::set_builtin_order(const String &p_name) { + + ERR_FAIL_COND(!props.has(p_name)); + if (props[p_name].order >= NO_BUILTIN_ORDER_BASE) { + props[p_name].order = last_builtin_order++; + } +} + void GlobalConfig::clear(const String &p_name) { ERR_FAIL_COND(!props.has(p_name)); @@ -715,13 +694,16 @@ Error GlobalConfig::save_custom(const String &p_path, const CustomMap &p_custom, Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default) { + Variant ret; if (GlobalConfig::get_singleton()->has(p_var)) { - GlobalConfig::get_singleton()->set_initial_value(p_var, p_default); - return GlobalConfig::get_singleton()->get(p_var); + ret = GlobalConfig::get_singleton()->get(p_var); + } else { + GlobalConfig::get_singleton()->set(p_var, p_default); + ret = p_default; } - GlobalConfig::get_singleton()->set(p_var, p_default); GlobalConfig::get_singleton()->set_initial_value(p_var, p_default); - return p_default; + GlobalConfig::get_singleton()->set_builtin_order(p_var); + return ret; } void GlobalConfig::add_singleton(const Singleton &p_singleton) { @@ -843,7 +825,8 @@ void GlobalConfig::_bind_methods() { GlobalConfig::GlobalConfig() { singleton = this; - last_order = 0; + last_order = NO_BUILTIN_ORDER_BASE; + last_builtin_order = 0; disable_platform_override = false; registering_order = true; @@ -851,12 +834,12 @@ GlobalConfig::GlobalConfig() { Ref<InputEventKey> key; Ref<InputEventJoypadButton> joyb; - GLOBAL_DEF("application/name", ""); - GLOBAL_DEF("application/main_scene", ""); - custom_prop_info["application/main_scene"] = PropertyInfo(Variant::STRING, "application/main_scene", PROPERTY_HINT_FILE, "tscn,scn,xscn,xml,res"); - GLOBAL_DEF("application/disable_stdout", false); - GLOBAL_DEF("application/disable_stderr", false); - GLOBAL_DEF("application/use_shared_user_dir", true); + GLOBAL_DEF("application/config/name", ""); + GLOBAL_DEF("application/run/main_scene", ""); + custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "tscn,scn,res"); + GLOBAL_DEF("application/run/disable_stdout", false); + GLOBAL_DEF("application/run/disable_stderr", false); + GLOBAL_DEF("application/config/use_shared_user_dir", true); key.instance(); key->set_scancode(KEY_RETURN); @@ -964,16 +947,19 @@ GlobalConfig::GlobalConfig() { //GLOBAL_DEF("display/handheld/orientation", "landscape"); - custom_prop_info["display/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor"); + custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor"); custom_prop_info["rendering/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); - GLOBAL_DEF("debug/profiler/max_functions", 16384); + GLOBAL_DEF("debug/settings/profiler/max_functions", 16384); - GLOBAL_DEF("compression/zstd/compression_level", 3); - custom_prop_info["compression/zstd/compression_level"] = PropertyInfo(Variant::INT, "compression/zstd/compression_level", PROPERTY_HINT_RANGE, "1,22,1"); - GLOBAL_DEF("compression/zlib/compression_level", Z_DEFAULT_COMPRESSION); - custom_prop_info["compression/zlib/compression_level"] = PropertyInfo(Variant::INT, "compression/zlib/compression_level", PROPERTY_HINT_RANGE, "-1,9,1"); + //assigning here, because using GLOBAL_GET on every block for compressing can be slow + Compression::zstd_level = GLOBAL_DEF("compression/formats/zstd/compression_level", 3); + custom_prop_info["compression/formats/zstd/compression_level"] = PropertyInfo(Variant::INT, "compression/formats/zstd/compression_level", PROPERTY_HINT_RANGE, "1,22,1"); + Compression::zlib_level = GLOBAL_DEF("compression/formats/zlib/compression_level", Z_DEFAULT_COMPRESSION); + custom_prop_info["compression/formats/zlib/compression_level"] = PropertyInfo(Variant::INT, "compression/formats/zlib/compression_level", PROPERTY_HINT_RANGE, "-1,9,1"); + Compression::gzip_level = GLOBAL_DEF("compression/formats/gzip/compression_level", Z_DEFAULT_COMPRESSION); + custom_prop_info["compression/formats/gzip/compression_level"] = PropertyInfo(Variant::INT, "compression/formats/gzip/compression_level", PROPERTY_HINT_RANGE, "-1,9,1"); using_datapack = false; } diff --git a/core/global_config.h b/core/global_config.h index d0f64dc23c..30c77bbc27 100644 --- a/core/global_config.h +++ b/core/global_config.h @@ -56,7 +56,8 @@ public: protected: enum { - NO_ORDER_BASE = 1 << 18 + //properties that are not for built in values begin from this value, so builtin ones are displayed first + NO_BUILTIN_ORDER_BASE = 1 << 16 }; struct VariantContainer { @@ -83,6 +84,7 @@ protected: bool registering_order; int last_order; + int last_builtin_order; Map<StringName, VariantContainer> props; String resource_path; Map<StringName, PropertyInfo> custom_prop_info; @@ -130,6 +132,7 @@ public: void clear(const String &p_name); int get_order(const String &p_name) const; void set_order(const String &p_name, int p_order); + void set_builtin_order(const String &p_name); Error setup(const String &p_path, const String &p_main_pack); diff --git a/core/io/compression.cpp b/core/io/compression.cpp index f806c4da6d..b0f5448b6c 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -52,23 +52,22 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, } } break; - case MODE_DEFLATE: { + case MODE_DEFLATE: + case MODE_GZIP: { + + int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; z_stream strm; strm.zalloc = zipio_alloc; strm.zfree = zipio_free; strm.opaque = Z_NULL; - int level = GLOBAL_GET("compression/zlib/compression_level"); - int err = deflateInit(&strm, level); + int level = p_mode == MODE_DEFLATE ? zlib_level : gzip_level; + int err = deflateInit2(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return -1; strm.avail_in = p_src_size; int aout = deflateBound(&strm, p_src_size); - /*if (aout>p_src_size) { - deflateEnd(&strm); - return -1; - }*/ strm.avail_out = aout; strm.next_in = (Bytef *)p_src; strm.next_out = p_dst; @@ -81,8 +80,7 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, case MODE_ZSTD: { int max_dst_size = get_max_compressed_buffer_size(p_src_size, MODE_ZSTD); - int level = GLOBAL_GET("compression/zstd/compression_level"); - return ZSTD_compress(p_dst, max_dst_size, p_src, p_src_size, level); + return ZSTD_compress(p_dst, max_dst_size, p_src, p_src_size, zstd_level); } break; } @@ -100,13 +98,16 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) { return ss; } break; - case MODE_DEFLATE: { + case MODE_DEFLATE: + case MODE_GZIP: { + + int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; z_stream strm; strm.zalloc = zipio_alloc; strm.zfree = zipio_free; strm.opaque = Z_NULL; - int err = deflateInit(&strm, Z_DEFAULT_COMPRESSION); + int err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return -1; int aout = deflateBound(&strm, p_src_size); @@ -138,7 +139,10 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p } return ret_size; } break; - case MODE_DEFLATE: { + case MODE_DEFLATE: + case MODE_GZIP: { + + int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; z_stream strm; strm.zalloc = zipio_alloc; @@ -146,7 +150,7 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; - int err = inflateInit(&strm); + int err = inflateInit2(&strm, window_bits); ERR_FAIL_COND_V(err != Z_OK, -1); strm.avail_in = p_src_size; @@ -168,3 +172,7 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p ERR_FAIL_V(-1); } + +int Compression::zlib_level = Z_DEFAULT_COMPRESSION; +int Compression::gzip_level = Z_DEFAULT_COMPRESSION; +int Compression::zstd_level = 3; diff --git a/core/io/compression.h b/core/io/compression.h index 742f0f4d68..5eb7806d7b 100644 --- a/core/io/compression.h +++ b/core/io/compression.h @@ -33,11 +33,17 @@ #include "typedefs.h" class Compression { + public: + static int zlib_level; + static int gzip_level; + static int zstd_level; + enum Mode { MODE_FASTLZ, MODE_DEFLATE, - MODE_ZSTD + MODE_ZSTD, + MODE_GZIP }; static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD); diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index ac68d5240c..93682e6b8a 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -254,7 +254,7 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) { PacketPeerStream::PacketPeerStream() { - int rbsize = GLOBAL_GET("network/packets/packet_stream_peer_max_buffer_po2"); + int rbsize = GLOBAL_GET("network/limits/packet_peer_stream/max_buffer_po2"); ring_buffer.resize(rbsize); temp_buffer.resize(1 << rbsize); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index b474c2e078..728cd5d4ff 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "resource_format_binary.h" #include "global_config.h" +#include "image.h" #include "io/file_access_compressed.h" #include "io/marshalls.h" #include "os/dir_access.h" @@ -54,7 +55,6 @@ enum { VARIANT_TRANSFORM = 17, VARIANT_MATRIX32 = 18, VARIANT_COLOR = 20, - //VARIANT_IMAGE = 21, - no longer variant type VARIANT_NODE_PATH = 22, VARIANT_RID = 23, VARIANT_OBJECT = 24, @@ -70,7 +70,13 @@ enum { VARIANT_VECTOR2_ARRAY = 37, VARIANT_INT64 = 40, VARIANT_DOUBLE = 41, - +#ifndef DISABLE_DEPRECATED + VARIANT_IMAGE = 21, // - no longer variant type + IMAGE_ENCODING_EMPTY = 0, + IMAGE_ENCODING_RAW = 1, + IMAGE_ENCODING_LOSSLESS = 2, + IMAGE_ENCODING_LOSSY = 3, +#endif OBJECT_EMPTY = 0, OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_INTERNAL_RESOURCE = 2, @@ -541,7 +547,69 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { w = PoolVector<Color>::Write(); r_v = array; } break; +#ifndef DISABLE_DEPRECATED + case VARIANT_IMAGE: { + uint32_t encoding = f->get_32(); + if (encoding == IMAGE_ENCODING_EMPTY) { + r_v = Ref<Image>(); + break; + } else if (encoding == IMAGE_ENCODING_RAW) { + uint32_t width = f->get_32(); + uint32_t height = f->get_32(); + uint32_t mipmaps = f->get_32(); + uint32_t format = f->get_32(); + const uint32_t format_version_shift = 24; + const uint32_t format_version_mask = format_version_shift - 1; + + uint32_t format_version = format >> format_version_shift; + + const uint32_t current_version = 0; + if (format_version > current_version) { + + ERR_PRINT("Format version for encoded binary image is too new"); + return ERR_PARSE_ERROR; + } + + Image::Format fmt = Image::Format(format & format_version_mask); //if format changes, we can add a compatibility bit on top + + uint32_t datalen = f->get_32(); + + PoolVector<uint8_t> imgdata; + imgdata.resize(datalen); + PoolVector<uint8_t>::Write w = imgdata.write(); + f->get_buffer(w.ptr(), datalen); + _advance_padding(datalen); + w = PoolVector<uint8_t>::Write(); + + Ref<Image> image; + image.instance(); + image->create(width, height, mipmaps, fmt, imgdata); + r_v = image; + + } else { + //compressed + PoolVector<uint8_t> data; + data.resize(f->get_32()); + PoolVector<uint8_t>::Write w = data.write(); + f->get_buffer(w.ptr(), data.size()); + w = PoolVector<uint8_t>::Write(); + + Ref<Image> image; + if (encoding == IMAGE_ENCODING_LOSSY && Image::lossy_unpacker) { + + image = Image::lossy_unpacker(data); + } else if (encoding == IMAGE_ENCODING_LOSSLESS && Image::lossless_unpacker) { + + image = Image::lossless_unpacker(data); + } + _advance_padding(data.size()); + + r_v = image; + } + + } break; +#endif default: { ERR_FAIL_V(ERR_FILE_CORRUPT); } break; @@ -1644,7 +1712,6 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant get_string_index(np.get_property()); } break; - default: {} } } diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h index 5ccc9d9e5e..d54f622197 100644 --- a/core/math/audio_frame.h +++ b/core/math/audio_frame.h @@ -102,6 +102,16 @@ struct AudioFrame { r = ::undenormalise(r); } + _FORCE_INLINE_ AudioFrame linear_interpolate(const AudioFrame &p_b, float p_t) const { + + AudioFrame res = *this; + + res.l += (p_t * (p_b.l - l)); + res.r += (p_t * (p_b.r - r)); + + return res; + } + _ALWAYS_INLINE_ AudioFrame(float p_l, float p_r) { l = p_l; r = p_r; diff --git a/core/math/vector3.h b/core/math/vector3.h index 7dfcedd0da..6a7974681e 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -100,6 +100,7 @@ struct Vector3 { _FORCE_INLINE_ Vector3 abs() const; _FORCE_INLINE_ Vector3 floor() const; + _FORCE_INLINE_ Vector3 sign() const; _FORCE_INLINE_ Vector3 ceil() const; _FORCE_INLINE_ real_t distance_to(const Vector3 &p_b) const; @@ -187,6 +188,11 @@ Vector3 Vector3::abs() const { return Vector3(Math::abs(x), Math::abs(y), Math::abs(z)); } +Vector3 Vector3::sign() const { + + return Vector3(SGN(x), SGN(y), SGN(z)); +} + Vector3 Vector3::floor() const { return Vector3(Math::floor(x), Math::floor(y), Math::floor(z)); diff --git a/core/message_queue.cpp b/core/message_queue.cpp index d7d31b6c1e..1c980a56e3 100644 --- a/core/message_queue.cpp +++ b/core/message_queue.cpp @@ -382,7 +382,7 @@ MessageQueue::MessageQueue() { buffer_end = 0; buffer_max_used = 0; - buffer_size = GLOBAL_DEF("memory/buffers/message_queue_max_size_kb", DEFAULT_QUEUE_SIZE_KB); + buffer_size = GLOBAL_DEF("memory/limits/message_queue/max_size_kb", DEFAULT_QUEUE_SIZE_KB); buffer_size *= 1024; buffer = memnew_arr(uint8_t, buffer_size); } diff --git a/core/object.cpp b/core/object.cpp index 3416cd8c5a..9184fb9cd0 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1655,7 +1655,7 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("get_script:Script"), &Object::get_script); ClassDB::bind_method(D_METHOD("set_meta", "name", "value"), &Object::set_meta); - ClassDB::bind_method(D_METHOD("get_meta", "name", "value"), &Object::get_meta); + ClassDB::bind_method(D_METHOD("get_meta:Variant", "name", "value"), &Object::get_meta); ClassDB::bind_method(D_METHOD("has_meta", "name"), &Object::has_meta); ClassDB::bind_method(D_METHOD("get_meta_list"), &Object::_get_meta_list_bind); @@ -1817,6 +1817,23 @@ uint32_t Object::get_edited_version() const { } #endif +void *Object::get_script_instance_binding(int p_script_language_index) { +#ifdef DEBUG_ENABLED + ERR_FAIL_INDEX_V(p_script_language_index, MAX_SCRIPT_INSTANCE_BINDINGS, NULL); +#endif + + //it's up to the script language to make this thread safe, if the function is called twice due to threads being out of syncro + //just return the same pointer. + //if you want to put a big lock in the entire function and keep allocated pointers in a map or something, feel free to do it + //as it should not really affect performance much (won't be called too often), as in far most caes the condition below will be false afterwards + + if (!_script_instance_bindings[p_script_language_index]) { + _script_instance_bindings[p_script_language_index] = ScriptServer::get_language(p_script_language_index)->alloc_instance_binding_data(this); + } + + return _script_instance_bindings[p_script_language_index]; +} + Object::Object() { _class_ptr = NULL; @@ -1826,6 +1843,7 @@ Object::Object() { _instance_ID = ObjectDB::add_instance(this); _can_translate = true; _is_queued_for_deletion = false; + memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS); script_instance = NULL; #ifdef TOOLS_ENABLED @@ -1877,6 +1895,12 @@ Object::~Object() { ObjectDB::remove_instance(this); _instance_ID = 0; _predelete_ok = 2; + + for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { + if (_script_instance_bindings[i]) { + ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]); + } + } } bool predelete_handler(Object *p_object) { diff --git a/core/object.h b/core/object.h index f87705c48b..556f3f1586 100644 --- a/core/object.h +++ b/core/object.h @@ -381,6 +381,10 @@ public: }; private: + enum { + MAX_SCRIPT_INSTANCE_BINDINGS = 8 + }; + #ifdef DEBUG_ENABLED friend class _ObjectDebugLock; #endif @@ -447,6 +451,8 @@ private: void _set_bind(const String &p_set, const Variant &p_value); Variant _get_bind(const String &p_name) const; + void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS]; + void property_list_changed_notify(); protected: @@ -683,6 +689,9 @@ public: bool editor_is_section_unfolded(const String &p_section); #endif + //used by script languages to store binding data + void *get_script_instance_binding(int p_script_language_index); + void clear_internal_resource_paths(); Object(); diff --git a/core/os/os.cpp b/core/os/os.cpp index 8bee725813..48463722cf 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -269,7 +269,7 @@ String OS::get_system_dir(SystemDir p_dir) const { } String OS::get_safe_application_name() const { - String an = GlobalConfig::get_singleton()->get("application/name"); + String an = GlobalConfig::get_singleton()->get("application/config/name"); Vector<String> invalid_char = String("\\ / : * ? \" < > |").split(" "); for (int i = 0; i < invalid_char.size(); i++) { an = an.replace(invalid_char[i], "-"); diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index b089ba9129..d6a521a86f 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -172,7 +172,7 @@ void register_core_types() { void register_core_settings() { //since in register core types, globals may not e present - GLOBAL_DEF("network/packets/packet_stream_peer_max_buffer_po2", (16)); + GLOBAL_DEF("network/limits/packet_peer_stream/max_buffer_po2", (16)); } void register_core_singletons() { diff --git a/core/safe_refcount.cpp b/core/safe_refcount.cpp index e4a5a994e6..1bd16f9e4f 100644 --- a/core/safe_refcount.cpp +++ b/core/safe_refcount.cpp @@ -33,7 +33,10 @@ #ifdef NO_THREADS -uint32_t atomic_conditional_increment(register uint32_t *pw) { +/* Bogus implementation unaware of multiprocessing */ + +template <class T> +static _ALWAYS_INLINE_ T _atomic_conditional_increment_impl(register T *pw) { if (*pw == 0) return 0; @@ -43,74 +46,202 @@ uint32_t atomic_conditional_increment(register uint32_t *pw) { return *pw; } -uint32_t atomic_increment(register uint32_t *pw) { +template <class T> +static _ALWAYS_INLINE_ T _atomic_decrement_impl(register T *pw) { + + (*pw)--; + + return *pw; +} + +template <class T> +static _ALWAYS_INLINE_T _atomic_increment_impl(register T *pw) { (*pw)++; return *pw; } -uint32_t atomic_decrement(register uint32_t *pw) { +template <class T> +static _ALWAYS_INLINE_ T _atomic_sub_impl(register T *pw, register T val) { - (*pw)--; + (*pw) -= val; return *pw; } -#else +template <class T> +static _ALWAYS_INLINE_T _atomic_add_impl(register T *pw, register T val) { -#ifdef _MSC_VER + (*pw) += val; -// don't pollute my namespace! -#include <windows.h> -uint32_t atomic_conditional_increment(register uint32_t *pw) { + return *pw; +} + +#elif defined(__GNUC__) + +/* Implementation for GCC & Clang */ + +// GCC guarantees atomic intrinsics for sizes of 1, 2, 4 and 8 bytes. +// Clang states it supports GCC atomic builtins. - /* try to increment until it actually works */ - // taken from boost +template <class T> +static _ALWAYS_INLINE_ T _atomic_conditional_increment_impl(register T *pw) { while (true) { - uint32_t tmp = static_cast<uint32_t const volatile &>(*pw); + T tmp = static_cast<T const volatile &>(*pw); if (tmp == 0) return 0; // if zero, can't add to it anymore - if (InterlockedCompareExchange((LONG volatile *)pw, tmp + 1, tmp) == tmp) + if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp) return tmp + 1; } } -uint32_t atomic_decrement(register uint32_t *pw) { +template <class T> +static _ALWAYS_INLINE_ T _atomic_decrement_impl(register T *pw) { + + return __sync_sub_and_fetch(pw, 1); +} + +template <class T> +static _ALWAYS_INLINE_ T _atomic_increment_impl(register T *pw) { + + return __sync_add_and_fetch(pw, 1); +} + +template <class T> +static _ALWAYS_INLINE_ T _atomic_sub_impl(register T *pw, register T val) { + + return __sync_sub_and_fetch(pw, val); +} + +template <class T> +static _ALWAYS_INLINE_ T _atomic_add_impl(register T *pw, register T val) { + + return __sync_add_and_fetch(pw, val); +} + +#elif defined(_MSC_VER) + +/* Implementation for MSVC-Windows */ + +// don't pollute my namespace! +#include <windows.h> + +#define ATOMIC_CONDITIONAL_INCREMENT_BODY(m_pw, m_win_type, m_win_cmpxchg, m_cpp_type) \ + /* try to increment until it actually works */ \ + /* taken from boost */ \ + while (true) { \ + m_cpp_type tmp = static_cast<m_cpp_type const volatile &>(*(m_pw)); \ + if (tmp == 0) \ + return 0; /* if zero, can't add to it anymore */ \ + if (m_win_cmpxchg((m_win_type volatile *)(m_pw), tmp + 1, tmp) == tmp) \ + return tmp + 1; \ + } + +static _ALWAYS_INLINE_ uint32_t _atomic_conditional_increment_impl(register uint32_t *pw) { + + ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONG, InterlockedCompareExchange, uint32_t) +} + +static _ALWAYS_INLINE_ uint32_t _atomic_decrement_impl(register uint32_t *pw) { + return InterlockedDecrement((LONG volatile *)pw); } -uint32_t atomic_increment(register uint32_t *pw) { +static _ALWAYS_INLINE_ uint32_t _atomic_increment_impl(register uint32_t *pw) { + return InterlockedIncrement((LONG volatile *)pw); } -#elif defined(__GNUC__) -uint32_t atomic_conditional_increment(register uint32_t *pw) { +static _ALWAYS_INLINE_ uint32_t _atomic_sub_impl(register uint32_t *pw, register uint32_t val) { - while (true) { - uint32_t tmp = static_cast<uint32_t const volatile &>(*pw); - if (tmp == 0) - return 0; // if zero, can't add to it anymore - if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp) - return tmp + 1; - } +#if _WIN32_WINNT >= 0x0601 // Windows 7+ + return InterlockedExchangeSubtract(pw, val) - val; +#else + return InterlockedExchangeAdd((LONG volatile *)pw, -(int32_t)val) - val; +#endif } -uint32_t atomic_decrement(register uint32_t *pw) { +static _ALWAYS_INLINE_ uint32_t _atomic_add_impl(register uint32_t *pw, register uint32_t val) { - return __sync_sub_and_fetch(pw, 1); + return InterlockedAdd((LONG volatile *)pw, val); } -uint32_t atomic_increment(register uint32_t *pw) { +static _ALWAYS_INLINE_ uint64_t _atomic_conditional_increment_impl(register uint64_t *pw) { - return __sync_add_and_fetch(pw, 1); + ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONGLONG, InterlockedCompareExchange64, uint64_t) +} + +static _ALWAYS_INLINE_ uint64_t _atomic_decrement_impl(register uint64_t *pw) { + + return InterlockedDecrement64((LONGLONG volatile *)pw); +} + +static _ALWAYS_INLINE_ uint64_t _atomic_increment_impl(register uint64_t *pw) { + + return InterlockedIncrement64((LONGLONG volatile *)pw); +} + +static _ALWAYS_INLINE_ uint64_t _atomic_sub_impl(register uint64_t *pw, register uint64_t val) { + +#if _WIN32_WINNT >= 0x0601 // Windows 7+ + return InterlockedExchangeSubtract64(pw, val) - val; +#else + return InterlockedExchangeAdd64((LONGLONG volatile *)pw, -(int64_t)val) - val; +#endif +} + +static _ALWAYS_INLINE_ uint64_t _atomic_add_impl(register uint64_t *pw, register uint64_t val) { + + return InterlockedAdd64((LONGLONG volatile *)pw, val); } #else + //no threads supported? #error Must provide atomic functions for this platform or compiler! #endif -#endif +// The actual advertised functions; they'll call the right implementation + +uint32_t atomic_conditional_increment(register uint32_t *counter) { + return _atomic_conditional_increment_impl(counter); +} + +uint32_t atomic_decrement(register uint32_t *pw) { + return _atomic_decrement_impl(pw); +} + +uint32_t atomic_increment(register uint32_t *pw) { + return _atomic_increment_impl(pw); +} + +uint32_t atomic_sub(register uint32_t *pw, register uint32_t val) { + return _atomic_sub_impl(pw, val); +} + +uint32_t atomic_add(register uint32_t *pw, register uint32_t val) { + return _atomic_add_impl(pw, val); +} + +uint64_t atomic_conditional_increment(register uint64_t *counter) { + return _atomic_conditional_increment_impl(counter); +} + +uint64_t atomic_decrement(register uint64_t *pw) { + return _atomic_decrement_impl(pw); +} + +uint64_t atomic_increment(register uint64_t *pw) { + return _atomic_increment_impl(pw); +} + +uint64_t atomic_sub(register uint64_t *pw, register uint64_t val) { + return _atomic_sub_impl(pw, val); +} + +uint64_t atomic_add(register uint64_t *pw, register uint64_t val) { + return _atomic_add_impl(pw, val); +} diff --git a/core/safe_refcount.h b/core/safe_refcount.h index d30f563b56..a2d2b5e127 100644 --- a/core/safe_refcount.h +++ b/core/safe_refcount.h @@ -39,6 +39,14 @@ uint32_t atomic_conditional_increment(register uint32_t *counter); uint32_t atomic_decrement(register uint32_t *pw); uint32_t atomic_increment(register uint32_t *pw); +uint32_t atomic_sub(register uint32_t *pw, register uint32_t val); +uint32_t atomic_add(register uint32_t *pw, register uint32_t val); + +uint64_t atomic_conditional_increment(register uint64_t *counter); +uint64_t atomic_decrement(register uint64_t *pw); +uint64_t atomic_increment(register uint64_t *pw); +uint64_t atomic_sub(register uint64_t *pw, register uint64_t val); +uint64_t atomic_add(register uint64_t *pw, register uint64_t val); struct SafeRefCount { diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index f230a4bc95..7fc151d83f 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -957,7 +957,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() { poll_every = 0; request_scene_tree = NULL; live_edit_funcs = NULL; - max_cps = GLOBAL_DEF("network/debug/max_remote_stdout_chars_per_second", 2048); + max_cps = GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second"); char_count = 0; msec_count = 0; last_msec = 0; @@ -967,7 +967,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() { eh.userdata = this; add_error_handler(&eh); - profile_info.resize(CLAMP(int(GlobalConfig::get_singleton()->get("debug/profiler/max_functions")), 128, 65535)); + profile_info.resize(CLAMP(int(GlobalConfig::get_singleton()->get("debug/settings/profiler/max_functions")), 128, 65535)); profile_info_ptrs.resize(profile_info.size()); profiling = false; max_frame_functions = 16; diff --git a/core/script_language.cpp b/core/script_language.cpp index 72f0acec3b..4a7fdc9d64 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -66,11 +66,6 @@ bool ScriptServer::is_scripting_enabled() { return scripting_enabled; } -int ScriptServer::get_language_count() { - - return _language_count; -} - ScriptLanguage *ScriptServer::get_language(int p_idx) { ERR_FAIL_INDEX_V(p_idx, _language_count, NULL); diff --git a/core/script_language.h b/core/script_language.h index 6e39593a89..a81300233f 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -57,7 +57,7 @@ public: static void set_scripting_enabled(bool p_enabled); static bool is_scripting_enabled(); - static int get_language_count(); + _FORCE_INLINE_ static int get_language_count() { return _language_count; } static ScriptLanguage *get_language(int p_idx); static void register_language(ScriptLanguage *p_language); static void unregister_language(ScriptLanguage *p_language); @@ -274,6 +274,9 @@ public: virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) = 0; virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) = 0; + virtual void *alloc_instance_binding_data(Object *p_object) { return NULL; } //optional, not used by all languages + virtual void free_instance_binding_data(void *p_data) {} //optional, not used by all languages + virtual void frame(); virtual ~ScriptLanguage(){}; diff --git a/core/self_list.h b/core/self_list.h index 9edf735f7b..e229d5bf8e 100644 --- a/core/self_list.h +++ b/core/self_list.h @@ -51,6 +51,25 @@ public: _first->_prev = p_elem; _first = p_elem; } + void add_last(SelfList<T> *p_elem) { + + ERR_FAIL_COND(p_elem->_root); + + if (!_first) { + add(p_elem); + return; + } + + SelfList<T> *e = _first; + + while (e->next()) { + e = e->next(); + } + + e->_next = p_elem; + p_elem->_prev = e->_next; + p_elem->_root = this; + } void remove(SelfList<T> *p_elem) { diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 6936a362e1..4a806aec6c 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -516,7 +516,7 @@ struct _VariantCall { PoolByteArray compressed; Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]); - compressed.resize(Compression::get_max_compressed_buffer_size(ba->size())); + compressed.resize(Compression::get_max_compressed_buffer_size(ba->size(), mode)); int result = Compression::compress(compressed.write().ptr(), ba->read().ptr(), ba->size(), mode); result = result >= 0 ? result : 0; |