summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/func_ref.cpp13
-rw-r--r--core/func_ref.h1
-rw-r--r--core/image.cpp10
-rw-r--r--core/image.h4
-rw-r--r--core/io/file_access_compressed.cpp3
-rw-r--r--core/io/resource_loader.cpp3
-rw-r--r--core/io/resource_saver.cpp3
-rw-r--r--core/math/math_funcs.h12
-rw-r--r--core/object.h7
-rw-r--r--core/pool_allocator.cpp4
-rw-r--r--core/script_debugger_remote.cpp57
-rw-r--r--core/script_debugger_remote.h6
-rw-r--r--core/translation.cpp64
13 files changed, 135 insertions, 52 deletions
diff --git a/core/func_ref.cpp b/core/func_ref.cpp
index 3d03137d09..66ef27f6b9 100644
--- a/core/func_ref.cpp
+++ b/core/func_ref.cpp
@@ -46,6 +46,17 @@ Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::Call
return obj->call(function, p_args, p_argcount, r_error);
}
+Variant FuncRef::call_funcv(const Array &p_args) {
+
+ ERR_FAIL_COND_V(id == 0, Variant());
+
+ Object *obj = ObjectDB::get_instance(id);
+
+ ERR_FAIL_COND_V(!obj, Variant());
+
+ return obj->callv(function, p_args);
+}
+
void FuncRef::set_instance(Object *p_obj) {
ERR_FAIL_NULL(p_obj);
@@ -77,6 +88,8 @@ void FuncRef::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_func", &FuncRef::call_func, mi, defargs);
}
+ ClassDB::bind_method(D_METHOD("call_funcv", "arg_array"), &FuncRef::call_funcv);
+
ClassDB::bind_method(D_METHOD("set_instance", "instance"), &FuncRef::set_instance);
ClassDB::bind_method(D_METHOD("set_function", "name"), &FuncRef::set_function);
ClassDB::bind_method(D_METHOD("is_valid"), &FuncRef::is_valid);
diff --git a/core/func_ref.h b/core/func_ref.h
index a143b58bf0..af0bf63203 100644
--- a/core/func_ref.h
+++ b/core/func_ref.h
@@ -44,6 +44,7 @@ protected:
public:
Variant call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant call_funcv(const Array &p_args);
void set_instance(Object *p_obj);
void set_function(const StringName &p_func);
bool is_valid() const;
diff --git a/core/image.cpp b/core/image.cpp
index 10778eced6..5ce744f709 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -83,6 +83,7 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
};
SavePNGFunc Image::save_png_func = NULL;
+SaveEXRFunc Image::save_exr_func = NULL;
void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel) {
@@ -1917,6 +1918,14 @@ Error Image::save_png(const String &p_path) const {
return save_png_func(p_path, Ref<Image>((Image *)this));
}
+Error Image::save_exr(const String &p_path, bool p_grayscale) const {
+
+ if (save_exr_func == NULL)
+ return ERR_UNAVAILABLE;
+
+ return save_exr_func(p_path, Ref<Image>((Image *)this), p_grayscale);
+}
+
int Image::get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps) {
int mm;
@@ -2746,6 +2755,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
+ ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false));
ClassDB::bind_method(D_METHOD("detect_alpha"), &Image::detect_alpha);
ClassDB::bind_method(D_METHOD("is_invisible"), &Image::is_invisible);
diff --git a/core/image.h b/core/image.h
index cc796789cd..d17571399d 100644
--- a/core/image.h
+++ b/core/image.h
@@ -49,11 +49,14 @@ class Image;
typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
+typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
+
class Image : public Resource {
GDCLASS(Image, Resource);
public:
static SavePNGFunc save_png_func;
+ static SaveEXRFunc save_exr_func;
enum {
MAX_WIDTH = 16384, // force a limit somehow
@@ -258,6 +261,7 @@ public:
Error load(const String &p_path);
Error save_png(const String &p_path) const;
+ Error save_exr(const String &p_path, bool p_grayscale) const;
/**
* create an empty image
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index 6c4310a572..102cd9cf6c 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -208,7 +208,8 @@ void FileAccessCompressed::seek(size_t p_position) {
if (p_position == read_total) {
at_end = true;
} else {
-
+ at_end = false;
+ read_eof = false;
int block_idx = p_position / block_size;
if (block_idx != read_block) {
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index a29b9d1ddb..35af58ad07 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -940,8 +940,7 @@ bool ResourceLoader::add_custom_resource_format_loader(String script_path) {
ERR_EXPLAIN("Cannot instance script as custom resource loader, expected 'ResourceFormatLoader' inheritance, got: " + String(ibt));
ERR_FAIL_COND_V(obj == NULL, false);
- ResourceFormatLoader *crl = NULL;
- crl = Object::cast_to<ResourceFormatLoader>(obj);
+ ResourceFormatLoader *crl = Object::cast_to<ResourceFormatLoader>(obj);
crl->set_script(s.get_ref_ptr());
ResourceLoader::add_resource_format_loader(crl);
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index e2c1c3402a..369cd93442 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -222,8 +222,7 @@ bool ResourceSaver::add_custom_resource_format_saver(String script_path) {
ERR_EXPLAIN("Cannot instance script as custom resource saver, expected 'ResourceFormatSaver' inheritance, got: " + String(ibt));
ERR_FAIL_COND_V(obj == NULL, false);
- ResourceFormatSaver *crl = NULL;
- crl = Object::cast_to<ResourceFormatSaver>(obj);
+ ResourceFormatSaver *crl = Object::cast_to<ResourceFormatSaver>(obj);
crl->set_script(s.get_ref_ptr());
ResourceSaver::add_resource_format_saver(crl);
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index a712356ddc..af845ca01e 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -255,16 +255,16 @@ public:
static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) {
- int64_t rng = max - min;
- return (rng != 0) ? min + ((((value - min) % rng) + rng) % rng) : min;
+ int64_t range = max - min;
+ return range == 0 ? min : min + ((((value - min) % range) + range) % range);
}
static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) {
- double rng = max - min;
- return (!is_equal_approx(rng, 0.0)) ? value - (rng * Math::floor((value - min) / rng)) : min;
+ double range = max - min;
+ return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range));
}
static _ALWAYS_INLINE_ float wrapf(float value, float min, float max) {
- float rng = max - min;
- return (!is_equal_approx(rng, 0.0f)) ? value - (rng * Math::floor((value - min) / rng)) : min;
+ float range = max - min;
+ return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range));
}
// double only, as these functions are mainly used by the editor and not performance-critical,
diff --git a/core/object.h b/core/object.h
index dce1cc74ae..15c3ab94c5 100644
--- a/core/object.h
+++ b/core/object.h
@@ -794,8 +794,13 @@ public:
static int get_object_count();
_FORCE_INLINE_ static bool instance_validate(Object *p_ptr) {
+ rw_lock->read_lock();
- return instance_checks.has(p_ptr);
+ bool exists = instance_checks.has(p_ptr);
+
+ rw_lock->read_unlock();
+
+ return exists;
}
};
diff --git a/core/pool_allocator.cpp b/core/pool_allocator.cpp
index 9b342ef913..48a30f6702 100644
--- a/core/pool_allocator.cpp
+++ b/core/pool_allocator.cpp
@@ -539,6 +539,10 @@ void PoolAllocator::unlock(ID p_mem) {
return;
mt_lock();
Entry *e = get_entry(p_mem);
+ if (!e) {
+ mt_unlock();
+ ERR_FAIL_COND(!e);
+ }
if (e->lock == 0) {
mt_unlock();
ERR_PRINT("e->lock == 0");
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index e7ff7a3aef..5f01e043c4 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -357,10 +357,11 @@ void ScriptDebuggerRemote::_get_output() {
locking = false;
}
- if (n_errors_dropped > 0) {
+ if (n_errors_dropped == 1) {
+ // Only print one message about dropping per second
OutputError oe;
oe.error = "TOO_MANY_ERRORS";
- oe.error_descr = "Too many errors! " + String::num_int64(n_errors_dropped) + " errors were dropped.";
+ oe.error_descr = "Too many errors! Ignoring errors for up to 1 second.";
oe.warning = false;
uint64_t time = OS::get_singleton()->get_ticks_msec();
oe.hr = time / 3600000;
@@ -368,7 +369,20 @@ void ScriptDebuggerRemote::_get_output() {
oe.sec = (time / 1000) % 60;
oe.msec = time % 1000;
errors.push_back(oe);
- n_errors_dropped = 0;
+ }
+
+ if (n_warnings_dropped == 1) {
+ // Only print one message about dropping per second
+ OutputError oe;
+ oe.error = "TOO_MANY_WARNINGS";
+ oe.error_descr = "Too many warnings! Ignoring warnings for up to 1 second.";
+ oe.warning = true;
+ uint64_t time = OS::get_singleton()->get_ticks_msec();
+ oe.hr = time / 3600000;
+ oe.min = (time / 60000) % 60;
+ oe.sec = (time / 1000) % 60;
+ oe.msec = time % 1000;
+ errors.push_back(oe);
}
while (errors.size()) {
@@ -934,6 +948,19 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file
oe.msec = time % 1000;
Array cstack;
+ uint64_t ticks = OS::get_singleton()->get_ticks_usec() / 1000;
+ msec_count += ticks - last_msec;
+ last_msec = ticks;
+
+ if (msec_count > 1000) {
+ msec_count = 0;
+
+ err_count = 0;
+ n_errors_dropped = 0;
+ warn_count = 0;
+ n_warnings_dropped = 0;
+ }
+
cstack.resize(p_stack_info.size() * 3);
for (int i = 0; i < p_stack_info.size(); i++) {
cstack[i * 3 + 0] = p_stack_info[i].file;
@@ -942,15 +969,28 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file
}
oe.callstack = cstack;
+ if (oe.warning) {
+ warn_count++;
+ } else {
+ err_count++;
+ }
mutex->lock();
if (!locking && tcp_client->is_connected_to_host()) {
- if (errors.size() >= max_errors_per_frame) {
- n_errors_dropped++;
+ if (oe.warning) {
+ if (warn_count > max_warnings_per_second) {
+ n_warnings_dropped++;
+ } else {
+ errors.push_back(oe);
+ }
} else {
- errors.push_back(oe);
+ if (err_count > max_errors_per_second) {
+ n_errors_dropped++;
+ } else {
+ errors.push_back(oe);
+ }
}
}
@@ -1070,10 +1110,13 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() :
mutex(Mutex::create()),
max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")),
n_messages_dropped(0),
- max_errors_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_frame")),
+ max_errors_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_second")),
+ max_warnings_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_warnings_per_second")),
n_errors_dropped(0),
max_cps(GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second")),
char_count(0),
+ err_count(0),
+ warn_count(0),
last_msec(0),
msec_count(0),
locking(false),
diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h
index 1fc9d7c7f1..a5bfd7a32d 100644
--- a/core/script_debugger_remote.h
+++ b/core/script_debugger_remote.h
@@ -91,11 +91,15 @@ class ScriptDebuggerRemote : public ScriptDebugger {
int max_messages_per_frame;
int n_messages_dropped;
List<OutputError> errors;
- int max_errors_per_frame;
+ int max_errors_per_second;
+ int max_warnings_per_second;
int n_errors_dropped;
+ int n_warnings_dropped;
int max_cps;
int char_count;
+ int err_count;
+ int warn_count;
uint64_t last_msec;
uint64_t msec_count;
diff --git a/core/translation.cpp b/core/translation.cpp
index 0b55badc61..a3ff971f45 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -1044,6 +1044,13 @@ StringName TranslationServer::translate(const StringName &p_message) const {
if (!enabled)
return p_message;
+ // Locale can be of the form 'll_CC', i.e. language code and regional code,
+ // e.g. 'en_US', 'en_GB', etc. It might also be simply 'll', e.g. 'en'.
+ // To find the relevant translation, we look for those with locale starting
+ // with the language code, and then if any is an exact match for the long
+ // form. If not found, we fall back to a near match (another locale with
+ // same language code).
+
StringName res;
bool near_match = false;
const CharType *lptr = &locale[0];
@@ -1053,13 +1060,11 @@ StringName TranslationServer::translate(const StringName &p_message) const {
const Ref<Translation> &t = E->get();
String l = t->get_locale();
if (lptr[0] != l[0] || lptr[1] != l[1])
- continue; // locale not match
-
- //near match
- bool match = (l != locale);
+ continue; // Language code does not match.
- if (near_match && !match)
- continue; //only near-match once
+ bool exact_match = (l == locale);
+ if (!exact_match && near_match)
+ continue; // Only near-match once, but keep looking for exact matches.
StringName r = t->get_message(p_message);
@@ -1068,43 +1073,38 @@ StringName TranslationServer::translate(const StringName &p_message) const {
res = r;
- if (match)
+ if (exact_match)
break;
else
near_match = true;
}
- if (!res) {
- //try again with fallback
- if (fallback.length() >= 2) {
-
- const CharType *fptr = &fallback[0];
- near_match = false;
- for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) {
+ if (!res && fallback.length() >= 2) {
+ // Try again with the fallback locale.
+ const CharType *fptr = &fallback[0];
+ near_match = false;
+ for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) {
- const Ref<Translation> &t = E->get();
- String l = t->get_locale();
- if (fptr[0] != l[0] || fptr[1] != l[1])
- continue; // locale not match
+ const Ref<Translation> &t = E->get();
+ String l = t->get_locale();
+ if (fptr[0] != l[0] || fptr[1] != l[1])
+ continue; // Language code does not match.
- //near match
- bool match = (l != fallback);
+ bool exact_match = (l == fallback);
+ if (!exact_match && near_match)
+ continue; // Only near-match once, but keep looking for exact matches.
- if (near_match && !match)
- continue; //only near-match once
+ StringName r = t->get_message(p_message);
- StringName r = t->get_message(p_message);
+ if (!r)
+ continue;
- if (!r)
- continue;
+ res = r;
- res = r;
-
- if (match)
- break;
- else
- near_match = true;
- }
+ if (exact_match)
+ break;
+ else
+ near_match = true;
}
}