summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/bind/core_bind.cpp1
-rw-r--r--core/bind/core_bind.h3
-rw-r--r--core/engine.cpp2
-rw-r--r--core/engine.h4
-rw-r--r--core/global_config.cpp80
-rw-r--r--core/global_config.h5
-rw-r--r--core/io/compression.cpp34
-rw-r--r--core/io/compression.h8
-rw-r--r--core/io/packet_peer.cpp2
-rw-r--r--core/io/resource_format_binary.cpp73
-rw-r--r--core/math/audio_frame.h10
-rw-r--r--core/math/vector3.h6
-rw-r--r--core/message_queue.cpp2
-rw-r--r--core/object.cpp26
-rw-r--r--core/object.h9
-rw-r--r--core/os/os.cpp2
-rw-r--r--core/register_core_types.cpp2
-rw-r--r--core/safe_refcount.cpp189
-rw-r--r--core/safe_refcount.h8
-rw-r--r--core/script_debugger_remote.cpp4
-rw-r--r--core/script_language.cpp5
-rw-r--r--core/script_language.h5
-rw-r--r--core/self_list.h19
-rw-r--r--core/variant_call.cpp2
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;