summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/config/project_settings.cpp36
-rw-r--r--core/core_bind.cpp24
-rw-r--r--core/core_constants.cpp4
-rw-r--r--core/debugger/engine_debugger.cpp10
-rw-r--r--core/debugger/local_debugger.cpp8
-rw-r--r--core/debugger/remote_debugger.cpp4
-rw-r--r--core/error/error_macros.h183
-rw-r--r--core/extension/extension_api_dump.cpp23
-rw-r--r--core/extension/native_extension_manager.cpp12
-rw-r--r--core/input/input.cpp24
-rw-r--r--core/input/input_event.cpp2
-rw-r--r--core/input/shortcut.cpp84
-rw-r--r--core/input/shortcut.h12
-rw-r--r--core/io/file_access_pack.cpp8
-rw-r--r--core/io/ip.cpp8
-rw-r--r--core/io/resource.cpp4
-rw-r--r--core/io/resource_format_binary.cpp4
-rw-r--r--core/io/resource_loader.cpp4
-rw-r--r--core/math/bvh_cull.inc2
-rw-r--r--core/math/bvh_debug.inc27
-rw-r--r--core/math/bvh_split.inc16
-rw-r--r--core/math/quick_hull.cpp24
-rw-r--r--core/math/static_raycaster.cpp40
-rw-r--r--core/math/static_raycaster.h111
-rw-r--r--core/math/triangle_mesh.cpp4
-rw-r--r--core/multiplayer/multiplayer.h4
-rw-r--r--core/multiplayer/rpc_manager.cpp2
-rw-r--r--core/object/message_queue.cpp12
-rw-r--r--core/object/object.cpp2
-rw-r--r--core/object/script_language.cpp4
-rw-r--r--core/os/os.cpp6
-rw-r--r--core/os/os.h1
-rw-r--r--core/os/thread.cpp6
-rw-r--r--core/os/thread.h9
-rw-r--r--core/string/optimized_translation.cpp10
-rw-r--r--core/string/translation.cpp13
-rw-r--r--core/string/ustring.h16
-rw-r--r--core/templates/rid_owner.h16
-rw-r--r--core/templates/search_array.h67
-rw-r--r--core/templates/vector.h6
-rw-r--r--core/variant/array.cpp36
-rw-r--r--core/variant/variant_call.cpp17
42 files changed, 597 insertions, 308 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 09f9f84728..85e83ff7f2 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -252,15 +252,15 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const {
Set<_VCSort> vclist;
- for (Map<StringName, VariantContainer>::Element *E = props.front(); E; E = E->next()) {
- const VariantContainer *v = &E->get();
+ for (const KeyValue<StringName, VariantContainer> &E : props) {
+ const VariantContainer *v = &E.value;
if (v->hide_from_editor) {
continue;
}
_VCSort vc;
- vc.name = E->key();
+ vc.name = E.key;
vc.order = v->order;
vc.type = v->variant.get_type();
if (vc.name.begins_with("input/") || vc.name.begins_with("import/") || vc.name.begins_with("export/") || vc.name.begins_with("/remap") || vc.name.begins_with("/locale") || vc.name.begins_with("/autoload")) {
@@ -318,14 +318,14 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_f
void ProjectSettings::_convert_to_last_version(int p_from_version) {
if (p_from_version <= 3) {
// Converts the actions from array to dictionary (array of events to dictionary with deadzone + events)
- for (Map<StringName, ProjectSettings::VariantContainer>::Element *E = props.front(); E; E = E->next()) {
- Variant value = E->get().variant;
- if (String(E->key()).begins_with("input/") && value.get_type() == Variant::ARRAY) {
+ for (KeyValue<StringName, ProjectSettings::VariantContainer> &E : props) {
+ Variant value = E.value.variant;
+ if (String(E.key).begins_with("input/") && value.get_type() == Variant::ARRAY) {
Array array = value;
Dictionary action;
action["deadzone"] = Variant(0.5f);
action["events"] = array;
- E->get().variant = action;
+ E.value.variant = action;
}
}
}
@@ -695,8 +695,8 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
int count = 0;
- for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) {
- count += E->get().size();
+ for (const KeyValue<String, List<String>> &E : props) {
+ count += E.value.size();
}
if (p_custom_features != String()) {
@@ -788,7 +788,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
}
file->store_string("\n");
- for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) {
+ for (const Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) {
if (E != props.front()) {
file->store_string("\n");
}
@@ -831,19 +831,19 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
Set<_VCSort> vclist;
if (p_merge_with_current) {
- for (Map<StringName, VariantContainer>::Element *G = props.front(); G; G = G->next()) {
- const VariantContainer *v = &G->get();
+ for (const KeyValue<StringName, VariantContainer> &G : props) {
+ const VariantContainer *v = &G.value;
if (v->hide_from_editor) {
continue;
}
- if (p_custom.has(G->key())) {
+ if (p_custom.has(G.key)) {
continue;
}
_VCSort vc;
- vc.name = G->key(); //*k;
+ vc.name = G.key; //*k;
vc.order = v->order;
vc.type = v->variant.get_type();
vc.flags = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE;
@@ -855,14 +855,14 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
}
}
- for (const Map<String, Variant>::Element *E = p_custom.front(); E; E = E->next()) {
+ for (const KeyValue<String, Variant> &E : p_custom) {
// Lookup global prop to store in the same order
- Map<StringName, VariantContainer>::Element *global_prop = props.find(E->key());
+ Map<StringName, VariantContainer>::Element *global_prop = props.find(E.key);
_VCSort vc;
- vc.name = E->key();
+ vc.name = E.key;
vc.order = global_prop ? global_prop->get().order : 0xFFFFFFF;
- vc.type = E->get().get_type();
+ vc.type = E.value.get_type();
vc.flags = PROPERTY_USAGE_STORAGE;
vclist.insert(vc);
}
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index 1f028702f6..f630adc39e 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -1768,6 +1768,12 @@ void Thread::_start_func(void *ud) {
Ref<Thread> *tud = (Ref<Thread> *)ud;
Ref<Thread> t = *tud;
memdelete(tud);
+
+ Object *target_instance = t->target_callable.get_object();
+ if (!target_instance) {
+ ERR_FAIL_MSG(vformat("Could not call function '%s' on previously freed instance to start thread %s.", t->target_callable.get_method(), t->get_id()));
+ }
+
Callable::CallError ce;
const Variant *arg[1] = { &t->userdata };
int argc = 0;
@@ -1786,15 +1792,17 @@ void Thread::_start_func(void *ud) {
// We must check if we are in case b).
int target_param_count = 0;
int target_default_arg_count = 0;
- Ref<Script> script = t->target_callable.get_object()->get_script();
+ Ref<Script> script = target_instance->get_script();
if (script.is_valid()) {
MethodInfo mi = script->get_method_info(t->target_callable.get_method());
target_param_count = mi.arguments.size();
target_default_arg_count = mi.default_arguments.size();
} else {
- MethodBind *method = ClassDB::get_method(t->target_callable.get_object()->get_class_name(), t->target_callable.get_method());
- target_param_count = method->get_argument_count();
- target_default_arg_count = method->get_default_argument_count();
+ MethodBind *method = ClassDB::get_method(target_instance->get_class_name(), t->target_callable.get_method());
+ if (method) {
+ target_param_count = method->get_argument_count();
+ target_default_arg_count = method->get_default_argument_count();
+ }
}
if (target_param_count >= 1 && target_default_arg_count < target_param_count) {
argc = 1;
@@ -2411,12 +2419,12 @@ Error EngineDebugger::call_capture(void *p_user, const String &p_cmd, const Arra
}
EngineDebugger::~EngineDebugger() {
- for (Map<StringName, Callable>::Element *E = captures.front(); E; E = E->next()) {
- ::EngineDebugger::unregister_message_capture(E->key());
+ for (const KeyValue<StringName, Callable> &E : captures) {
+ ::EngineDebugger::unregister_message_capture(E.key);
}
captures.clear();
- for (Map<StringName, ProfilerCallable>::Element *E = profilers.front(); E; E = E->next()) {
- ::EngineDebugger::unregister_profiler(E->key());
+ for (const KeyValue<StringName, ProfilerCallable> &E : profilers) {
+ ::EngineDebugger::unregister_profiler(E.key);
}
profilers.clear();
}
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 721e5ae622..b2d5a8fdf1 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -613,11 +613,11 @@ void register_global_constants() {
// rpc
BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_DISABLED", Multiplayer::RPC_MODE_DISABLED);
- BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_ANY", Multiplayer::RPC_MODE_ANY);
+ BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_ANY_PEER", Multiplayer::RPC_MODE_ANY_PEER);
BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_AUTH", Multiplayer::RPC_MODE_AUTHORITY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_UNRELIABLE", Multiplayer::TRANSFER_MODE_UNRELIABLE);
- BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_ORDERED", Multiplayer::TRANSFER_MODE_ORDERED);
+ BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_UNRELIABLE_ORDERED", Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_RELIABLE", Multiplayer::TRANSFER_MODE_RELIABLE);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL);
diff --git a/core/debugger/engine_debugger.cpp b/core/debugger/engine_debugger.cpp
index a522b1310f..059025aa8f 100644
--- a/core/debugger/engine_debugger.cpp
+++ b/core/debugger/engine_debugger.cpp
@@ -123,8 +123,8 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks,
physics_time = USEC_TO_SEC(p_physics_ticks);
physics_frame_time = p_physics_frame_time;
// Notify tick to running profilers
- for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
- Profiler &p = E->get();
+ for (KeyValue<StringName, Profiler> &E : profilers) {
+ Profiler &p = E.value;
if (!p.active || !p.tick) {
continue;
}
@@ -179,9 +179,9 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve
void EngineDebugger::deinitialize() {
if (singleton) {
// Stop all profilers
- for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
- if (E->get().active) {
- singleton->profiler_enable(E->key(), false);
+ for (const KeyValue<StringName, Profiler> &E : profilers) {
+ if (E.value.active) {
+ singleton->profiler_enable(E.key, false);
}
}
diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp
index b0b3f11424..f7e56351b0 100644
--- a/core/debugger/local_debugger.cpp
+++ b/core/debugger/local_debugger.cpp
@@ -166,8 +166,8 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
} else if (line.begins_with("set")) {
if (line.get_slice_count(" ") == 1) {
- for (Map<String, String>::Element *E = options.front(); E; E = E->next()) {
- print_line("\t" + E->key() + "=" + E->value());
+ for (const KeyValue<String, String> &E : options) {
+ print_line("\t" + E.key + "=" + E.value);
}
} else {
@@ -249,8 +249,8 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
}
print_line("Breakpoint(s): " + itos(breakpoints.size()));
- for (Map<int, Set<StringName>>::Element *E = breakpoints.front(); E; E = E->next()) {
- print_line("\t" + String(E->value().front()->get()) + ":" + itos(E->key()));
+ for (const KeyValue<int, Set<StringName>> &E : breakpoints) {
+ print_line("\t" + String(E.value.front()->get()) + ":" + itos(E.key));
}
} else {
diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp
index f865dfe102..032c7d55c0 100644
--- a/core/debugger/remote_debugger.cpp
+++ b/core/debugger/remote_debugger.cpp
@@ -179,8 +179,8 @@ public:
if (pt - last_profile_time > 100) {
last_profile_time = pt;
DebuggerMarshalls::NetworkProfilerFrame frame;
- for (Map<ObjectID, NodeInfo>::Element *E = multiplayer_node_data.front(); E; E = E->next()) {
- frame.infos.push_back(E->get());
+ for (const KeyValue<ObjectID, NodeInfo> &E : multiplayer_node_data) {
+ frame.infos.push_back(E.value);
}
multiplayer_node_data.clear();
EngineDebugger::get_singleton()->send_message("network:profile_frame", frame.serialize());
diff --git a/core/error/error_macros.h b/core/error/error_macros.h
index f909a67d55..1bed8d366b 100644
--- a/core/error/error_macros.h
+++ b/core/error/error_macros.h
@@ -89,13 +89,6 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
#define GENERATE_TRAP() __builtin_trap()
#endif
-// Used to strip debug messages in release mode
-#ifdef DEBUG_ENABLED
-#define DEBUG_STR(m_msg) m_msg
-#else
-#define DEBUG_STR(m_msg) ""
-#endif
-
/**
* Error macros.
* WARNING: These macros work in the opposite way to assert().
@@ -135,11 +128,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0.
* If not, prints `m_msg` and the current function returns.
*/
-#define ERR_FAIL_INDEX_MSG(m_index, m_size, m_msg) \
- if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
- _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
- return; \
- } else \
+#define ERR_FAIL_INDEX_MSG(m_index, m_size, m_msg) \
+ if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg); \
+ return; \
+ } else \
((void)0)
/**
@@ -160,11 +153,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0.
* If not, prints `m_msg` and the current function returns `m_retval`.
*/
-#define ERR_FAIL_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
- if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
- _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
- return m_retval; \
- } else \
+#define ERR_FAIL_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
+ if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg); \
+ return m_retval; \
+ } else \
((void)0)
/**
@@ -189,11 +182,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0.
* If not, prints `m_msg` and the application crashes.
*/
-#define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \
- if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
- _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg), true); \
- GENERATE_TRAP(); \
- } else \
+#define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \
+ if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
+ GENERATE_TRAP(); \
+ } else \
((void)0)
// Unsigned integer index out of bounds error macros.
@@ -216,11 +209,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures an unsigned integer index `m_index` is less than `m_size`.
* If not, prints `m_msg` and the current function returns.
*/
-#define ERR_FAIL_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \
- if (unlikely((m_index) >= (m_size))) { \
- _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
- return; \
- } else \
+#define ERR_FAIL_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \
+ if (unlikely((m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg); \
+ return; \
+ } else \
((void)0)
/**
@@ -241,11 +234,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures an unsigned integer index `m_index` is less than `m_size`.
* If not, prints `m_msg` and the current function returns `m_retval`.
*/
-#define ERR_FAIL_UNSIGNED_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
- if (unlikely((m_index) >= (m_size))) { \
- _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
- return m_retval; \
- } else \
+#define ERR_FAIL_UNSIGNED_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
+ if (unlikely((m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg); \
+ return m_retval; \
+ } else \
((void)0)
/**
@@ -270,11 +263,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures an unsigned integer index `m_index` is less than `m_size`.
* If not, prints `m_msg` and the application crashes.
*/
-#define CRASH_BAD_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \
- if (unlikely((m_index) >= (m_size))) { \
- _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg), true); \
- GENERATE_TRAP(); \
- } else \
+#define CRASH_BAD_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \
+ if (unlikely((m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
+ GENERATE_TRAP(); \
+ } else \
((void)0)
// Null reference error macros.
@@ -297,11 +290,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures a pointer `m_param` is not null.
* If it is null, prints `m_msg` and the current function returns.
*/
-#define ERR_FAIL_NULL_MSG(m_param, m_msg) \
- if (unlikely(m_param == nullptr)) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", DEBUG_STR(m_msg)); \
- return; \
- } else \
+#define ERR_FAIL_NULL_MSG(m_param, m_msg) \
+ if (unlikely(m_param == nullptr)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", m_msg); \
+ return; \
+ } else \
((void)0)
/**
@@ -322,11 +315,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures a pointer `m_param` is not null.
* If it is null, prints `m_msg` and the current function returns `m_retval`.
*/
-#define ERR_FAIL_NULL_V_MSG(m_param, m_retval, m_msg) \
- if (unlikely(m_param == nullptr)) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", DEBUG_STR(m_msg)); \
- return m_retval; \
- } else \
+#define ERR_FAIL_NULL_V_MSG(m_param, m_retval, m_msg) \
+ if (unlikely(m_param == nullptr)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", m_msg); \
+ return m_retval; \
+ } else \
((void)0)
/**
@@ -352,11 +345,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* If checking for null use ERR_FAIL_NULL_MSG instead.
* If checking index bounds use ERR_FAIL_INDEX_MSG instead.
*/
-#define ERR_FAIL_COND_MSG(m_cond, m_msg) \
- if (unlikely(m_cond)) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \
- return; \
- } else \
+#define ERR_FAIL_COND_MSG(m_cond, m_msg) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true.", m_msg); \
+ return; \
+ } else \
((void)0)
/**
@@ -382,11 +375,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* If checking for null use ERR_FAIL_NULL_V_MSG instead.
* If checking index bounds use ERR_FAIL_INDEX_V_MSG instead.
*/
-#define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg) \
- if (unlikely(m_cond)) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returning: " _STR(m_retval), DEBUG_STR(m_msg)); \
- return m_retval; \
- } else \
+#define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returning: " _STR(m_retval), m_msg); \
+ return m_retval; \
+ } else \
((void)0)
/**
@@ -407,11 +400,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures `m_cond` is false.
* If `m_cond` is true, prints `m_msg` and the current loop continues.
*/
-#define ERR_CONTINUE_MSG(m_cond, m_msg) \
- if (unlikely(m_cond)) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing.", DEBUG_STR(m_msg)); \
- continue; \
- } else \
+#define ERR_CONTINUE_MSG(m_cond, m_msg) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing.", m_msg); \
+ continue; \
+ } else \
((void)0)
/**
@@ -432,11 +425,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures `m_cond` is false.
* If `m_cond` is true, prints `m_msg` and the current loop breaks.
*/
-#define ERR_BREAK_MSG(m_cond, m_msg) \
- if (unlikely(m_cond)) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking.", DEBUG_STR(m_msg)); \
- break; \
- } else \
+#define ERR_BREAK_MSG(m_cond, m_msg) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking.", m_msg); \
+ break; \
+ } else \
((void)0)
/**
@@ -461,11 +454,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures `m_cond` is false.
* If `m_cond` is true, prints `m_msg` and the application crashes.
*/
-#define CRASH_COND_MSG(m_cond, m_msg) \
- if (unlikely(m_cond)) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \
- GENERATE_TRAP(); \
- } else \
+#define CRASH_COND_MSG(m_cond, m_msg) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", m_msg); \
+ GENERATE_TRAP(); \
+ } else \
((void)0)
// Generic error macros.
@@ -490,11 +483,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*
* Prints `m_msg`, and the current function returns.
*/
-#define ERR_FAIL_MSG(m_msg) \
- if (true) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed.", DEBUG_STR(m_msg)); \
- return; \
- } else \
+#define ERR_FAIL_MSG(m_msg) \
+ if (true) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed.", m_msg); \
+ return; \
+ } else \
((void)0)
/**
@@ -517,11 +510,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*
* Prints `m_msg`, and the current function returns `m_retval`.
*/
-#define ERR_FAIL_V_MSG(m_retval, m_msg) \
- if (true) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed. Returning: " _STR(m_retval), DEBUG_STR(m_msg)); \
- return m_retval; \
- } else \
+#define ERR_FAIL_V_MSG(m_retval, m_msg) \
+ if (true) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed. Returning: " _STR(m_retval), m_msg); \
+ return m_retval; \
+ } else \
((void)0)
/**
@@ -590,14 +583,14 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
/**
* Warns that the current function is deprecated and prints `m_msg`.
*/
-#define WARN_DEPRECATED_MSG(m_msg) \
- if (true) { \
- static SafeFlag warning_shown; \
- if (!warning_shown.is_set()) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", DEBUG_STR(m_msg), ERR_HANDLER_WARNING); \
- warning_shown.set(); \
- } \
- } else \
+#define WARN_DEPRECATED_MSG(m_msg) \
+ if (true) { \
+ static SafeFlag warning_shown; \
+ if (!warning_shown.is_set()) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", m_msg, ERR_HANDLER_WARNING); \
+ warning_shown.set(); \
+ } \
+ } else \
((void)0)
/**
@@ -618,11 +611,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*
* Prints `m_msg`, and then the application crashes.
*/
-#define CRASH_NOW_MSG(m_msg) \
- if (true) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/function failed.", DEBUG_STR(m_msg)); \
- GENERATE_TRAP(); \
- } else \
+#define CRASH_NOW_MSG(m_msg) \
+ if (true) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/function failed.", m_msg); \
+ GENERATE_TRAP(); \
+ } else \
((void)0)
#endif // ERROR_MACROS_H
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index a8547a0090..03b2426370 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -353,11 +353,11 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
api_dump["global_constants"] = constants;
Array enums;
- for (Map<String, List<Pair<String, int>>>::Element *E = enum_list.front(); E; E = E->next()) {
+ for (const KeyValue<String, List<Pair<String, int>>> &E : enum_list) {
Dictionary d1;
- d1["name"] = E->key();
+ d1["name"] = E.key;
Array values;
- for (const Pair<String, int> &F : E->get()) {
+ for (const Pair<String, int> &F : E.value) {
Dictionary d2;
d2["name"] = F.first;
d2["value"] = F.second;
@@ -841,6 +841,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
{
Array native_structures;
+ // AudioStream structures
{
Dictionary d;
d["name"] = "AudioFrame";
@@ -849,6 +850,22 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
native_structures.push_back(d);
}
+ // TextServer structures
+ {
+ Dictionary d;
+ d["name"] = "Glyph";
+ d["format"] = "int start,int end,uint8_t count,uint8_t repeat,uint16_t flags,float x_off,float y_off,float advance,RID font_rid,int font_size,int32_t index";
+
+ native_structures.push_back(d);
+ }
+ {
+ Dictionary d;
+ d["name"] = "CaretInfo";
+ d["format"] = "Rect2 leading_caret,Rect2 trailing_caret,TextServer::Direction leading_direction,TextServer::Direction trailing_direction";
+
+ native_structures.push_back(d);
+ }
+
api_dump["native_structures"] = native_structures;
}
diff --git a/core/extension/native_extension_manager.cpp b/core/extension/native_extension_manager.cpp
index 8b7a9df4f1..4eac5249c9 100644
--- a/core/extension/native_extension_manager.cpp
+++ b/core/extension/native_extension_manager.cpp
@@ -84,8 +84,8 @@ bool NativeExtensionManager::is_extension_loaded(const String &p_path) const {
Vector<String> NativeExtensionManager::get_loaded_extensions() const {
Vector<String> ret;
- for (const Map<String, Ref<NativeExtension>>::Element *E = native_extension_map.front(); E; E = E->next()) {
- ret.push_back(E->key());
+ for (const KeyValue<String, Ref<NativeExtension>> &E : native_extension_map) {
+ ret.push_back(E.key);
}
return ret;
}
@@ -97,16 +97,16 @@ Ref<NativeExtension> NativeExtensionManager::get_extension(const String &p_path)
void NativeExtensionManager::initialize_extensions(NativeExtension::InitializationLevel p_level) {
ERR_FAIL_COND(int32_t(p_level) - 1 != level);
- for (Map<String, Ref<NativeExtension>>::Element *E = native_extension_map.front(); E; E = E->next()) {
- E->get()->initialize_library(p_level);
+ for (KeyValue<String, Ref<NativeExtension>> &E : native_extension_map) {
+ E.value->initialize_library(p_level);
}
level = p_level;
}
void NativeExtensionManager::deinitialize_extensions(NativeExtension::InitializationLevel p_level) {
ERR_FAIL_COND(int32_t(p_level) != level);
- for (Map<String, Ref<NativeExtension>>::Element *E = native_extension_map.front(); E; E = E->next()) {
- E->get()->deinitialize_library(p_level);
+ for (KeyValue<String, Ref<NativeExtension>> &E : native_extension_map) {
+ E.value->deinitialize_library(p_level);
}
level = int32_t(p_level) - 1;
}
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 9195f7d8b5..f9a361c761 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -35,10 +35,6 @@
#include "core/input/input_map.h"
#include "core/os/os.h"
-#ifdef TOOLS_ENABLED
-#include "editor/editor_settings.h"
-#endif
-
static const char *_joy_buttons[JOY_BUTTON_SDL_MAX] = {
"a",
"b",
@@ -162,9 +158,6 @@ void Input::_bind_methods() {
}
void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-#ifdef TOOLS_ENABLED
- const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\"";
-
String pf = p_function;
if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" ||
pf == "is_action_just_pressed" || pf == "is_action_just_released" ||
@@ -179,10 +172,9 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
}
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
- r_options->push_back(name.quote(quote_style));
+ r_options->push_back(name.quote());
}
}
-#endif
}
void Input::SpeedTrack::update(const Vector2 &p_delta_p) {
@@ -863,9 +855,9 @@ void Input::release_pressed_events() {
joy_buttons_pressed.clear();
_joy_axis.clear();
- for (Map<StringName, Input::Action>::Element *E = action_state.front(); E; E = E->next()) {
- if (E->get().pressed) {
- action_release(E->key());
+ for (const KeyValue<StringName, Input::Action> &E : action_state) {
+ if (E.value.pressed) {
+ action_release(E.key);
}
}
}
@@ -1322,8 +1314,8 @@ void Input::add_joy_mapping(String p_mapping, bool p_update_existing) {
if (p_update_existing) {
Vector<String> entry = p_mapping.split(",");
String uid = entry[0];
- for (Map<int, Joypad>::Element *E = joy_names.front(); E; E = E->next()) {
- Joypad &joy = E->get();
+ for (KeyValue<int, Joypad> &E : joy_names) {
+ Joypad &joy = E.value;
if (joy.uid == uid) {
joy.mapping = map_db.size() - 1;
}
@@ -1337,8 +1329,8 @@ void Input::remove_joy_mapping(String p_guid) {
map_db.remove(i);
}
}
- for (Map<int, Joypad>::Element *E = joy_names.front(); E; E = E->next()) {
- Joypad &joy = E->get();
+ for (KeyValue<int, Joypad> &E : joy_names) {
+ Joypad &joy = E.value;
if (joy.uid == p_guid) {
joy.mapping = -1;
}
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index c2a9d30fff..1d2b5f19ee 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -864,6 +864,8 @@ void InputEventMouseMotion::_bind_methods() {
///////////////////////////////////
void InputEventJoypadMotion::set_axis(JoyAxis p_axis) {
+ ERR_FAIL_INDEX(p_axis, JOY_AXIS_MAX);
+
axis = p_axis;
emit_changed();
}
diff --git a/core/input/shortcut.cpp b/core/input/shortcut.cpp
index d0cb08724e..30e35190e4 100644
--- a/core/input/shortcut.cpp
+++ b/core/input/shortcut.cpp
@@ -31,14 +31,26 @@
#include "shortcut.h"
#include "core/os/keyboard.h"
-void Shortcut::set_event(const Ref<InputEvent> &p_event) {
- ERR_FAIL_COND_MSG(Object::cast_to<InputEventShortcut>(*p_event), "Cannot set a shortcut event to an instance of InputEventShortcut.");
- event = p_event;
+void Shortcut::set_events(const Array &p_events) {
+ for (int i = 0; i < p_events.size(); i++) {
+ Ref<InputEventShortcut> ies = p_events[i];
+ ERR_FAIL_COND_MSG(ies.is_valid(), "Cannot set a shortcut event to an instance of InputEventShortcut.");
+ }
+
+ events = p_events;
emit_changed();
}
-Ref<InputEvent> Shortcut::get_event() const {
- return event;
+void Shortcut::set_events_list(const List<Ref<InputEvent>> *p_events) {
+ events.clear();
+
+ for (const Ref<InputEvent> &ie : *p_events) {
+ events.push_back(ie);
+ }
+}
+
+Array Shortcut::get_events() const {
+ return events;
}
bool Shortcut::matches_event(const Ref<InputEvent> &p_event) const {
@@ -48,29 +60,73 @@ bool Shortcut::matches_event(const Ref<InputEvent> &p_event) const {
return true;
}
}
- return event.is_valid() && event->is_match(p_event, true);
+
+ for (int i = 0; i < events.size(); i++) {
+ Ref<InputEvent> ie = events[i];
+ bool valid = ie.is_valid() && ie->is_match(p_event);
+
+ // Stop on first valid event - don't need to check further.
+ if (valid) {
+ return true;
+ }
+ }
+
+ return false;
}
String Shortcut::get_as_text() const {
- if (event.is_valid()) {
- return event->as_text();
- } else {
- return "None";
+ for (int i = 0; i < events.size(); i++) {
+ Ref<InputEvent> ie = events[i];
+ // Return first shortcut which is valid
+ if (ie.is_valid()) {
+ return ie->as_text();
+ }
}
+
+ return "None";
}
bool Shortcut::has_valid_event() const {
- return event.is_valid();
+ // Tests if there is ANY input event which is valid.
+ for (int i = 0; i < events.size(); i++) {
+ Ref<InputEvent> ie = events[i];
+ if (ie.is_valid()) {
+ return true;
+ }
+ }
+
+ return false;
}
void Shortcut::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_event", "event"), &Shortcut::set_event);
- ClassDB::bind_method(D_METHOD("get_event"), &Shortcut::get_event);
+ ClassDB::bind_method(D_METHOD("set_events", "events"), &Shortcut::set_events);
+ ClassDB::bind_method(D_METHOD("get_events"), &Shortcut::get_events);
ClassDB::bind_method(D_METHOD("has_valid_event"), &Shortcut::has_valid_event);
ClassDB::bind_method(D_METHOD("matches_event", "event"), &Shortcut::matches_event);
ClassDB::bind_method(D_METHOD("get_as_text"), &Shortcut::get_as_text);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), "set_event", "get_event");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "events", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")), "set_events", "get_events");
+}
+
+bool Shortcut::is_event_array_equal(const Array &p_event_array1, const Array &p_event_array2) {
+ if (p_event_array1.size() != p_event_array2.size()) {
+ return false;
+ }
+
+ bool is_same = true;
+ for (int i = 0; i < p_event_array1.size(); i++) {
+ Ref<InputEvent> ie_1 = p_event_array1[i];
+ Ref<InputEvent> ie_2 = p_event_array2[i];
+
+ is_same = ie_1->is_match(ie_2);
+
+ // Break on the first that doesn't match - don't need to check further.
+ if (!is_same) {
+ break;
+ }
+ }
+
+ return is_same;
}
diff --git a/core/input/shortcut.h b/core/input/shortcut.h
index 249dd1971f..a989b10626 100644
--- a/core/input/shortcut.h
+++ b/core/input/shortcut.h
@@ -37,18 +37,22 @@
class Shortcut : public Resource {
GDCLASS(Shortcut, Resource);
- Ref<InputEvent> event;
+ Array events;
protected:
static void _bind_methods();
public:
- void set_event(const Ref<InputEvent> &p_shortcut);
- Ref<InputEvent> get_event() const;
+ void set_events(const Array &p_events);
+ Array get_events() const;
+
+ void set_events_list(const List<Ref<InputEvent>> *p_events);
+
bool matches_event(const Ref<InputEvent> &p_event) const;
bool has_valid_event() const;
String get_as_text() const;
-};
+ static bool is_event_array_equal(const Array &p_event_array1, const Array &p_event_array2);
+};
#endif // SHORTCUT_H
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index 7b43daf9c0..b2832b2a75 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -110,8 +110,8 @@ PackedData::PackedData() {
}
void PackedData::_free_packed_dirs(PackedDir *p_dir) {
- for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next()) {
- _free_packed_dirs(E->get());
+ for (const KeyValue<String, PackedDir *> &E : p_dir->subdirs) {
+ _free_packed_dirs(E.value);
}
memdelete(p_dir);
}
@@ -395,8 +395,8 @@ Error DirAccessPack::list_dir_begin() {
list_dirs.clear();
list_files.clear();
- for (Map<String, PackedData::PackedDir *>::Element *E = current->subdirs.front(); E; E = E->next()) {
- list_dirs.push_back(E->key());
+ for (const KeyValue<String, PackedData::PackedDir *> &E : current->subdirs) {
+ list_dirs.push_back(E.key);
}
for (Set<String>::Element *E = current->files.front(); E; E = E->next()) {
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index e3102508a3..68b4e4b354 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -288,8 +288,8 @@ Array IP::_get_local_interfaces() const {
Array results;
Map<String, Interface_Info> interfaces;
get_local_interfaces(&interfaces);
- for (Map<String, Interface_Info>::Element *E = interfaces.front(); E; E = E->next()) {
- Interface_Info &c = E->get();
+ for (KeyValue<String, Interface_Info> &E : interfaces) {
+ Interface_Info &c = E.value;
Dictionary rc;
rc["name"] = c.name;
rc["friendly"] = c.name_friendly;
@@ -310,8 +310,8 @@ Array IP::_get_local_interfaces() const {
void IP::get_local_addresses(List<IPAddress> *r_addresses) const {
Map<String, Interface_Info> interfaces;
get_local_interfaces(&interfaces);
- for (Map<String, Interface_Info>::Element *E = interfaces.front(); E; E = E->next()) {
- for (const IPAddress &F : E->get().ip_addresses) {
+ for (const KeyValue<String, Interface_Info> &E : interfaces) {
+ for (const IPAddress &F : E.value.ip_addresses) {
r_addresses->push_front(F);
}
}
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 87b4d7195d..1cefa52d69 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -540,9 +540,9 @@ void ResourceCache::dump(const char *p_file, bool p_short) {
}
}
- for (Map<String, int>::Element *E = type_count.front(); E; E = E->next()) {
+ for (const KeyValue<String, int> &E : type_count) {
if (f) {
- f->store_line(E->key() + " count: " + itos(E->get()));
+ f->store_line(E.key + " count: " + itos(E.value));
}
}
if (f) {
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 84fd6496a7..cbb033f6c6 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -1960,8 +1960,8 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
Vector<RES> save_order;
save_order.resize(external_resources.size());
- for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
- save_order.write[E->get()] = E->key();
+ for (const KeyValue<RES, int> &E : external_resources) {
+ save_order.write[E.value] = E.key;
}
for (int i = 0; i < save_order.size(); i++) {
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 3026236f07..2198761c2a 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -156,8 +156,8 @@ void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *
Error ResourceFormatLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
Dictionary deps_dict;
- for (Map<String, String>::Element *E = p_map.front(); E; E = E->next()) {
- deps_dict[E->key()] = E->value();
+ for (KeyValue<String, String> E : p_map) {
+ deps_dict[E.key] = E.value;
}
int64_t err;
diff --git a/core/math/bvh_cull.inc b/core/math/bvh_cull.inc
index cba8ea6cb3..d7edc8a884 100644
--- a/core/math/bvh_cull.inc
+++ b/core/math/bvh_cull.inc
@@ -14,7 +14,7 @@ struct CullParams {
uint32_t pairable_type;
// optional components for different tests
- Vector3 point;
+ Point point;
BVHABB_CLASS abb;
typename BVHABB_CLASS::ConvexHull hull;
typename BVHABB_CLASS::Segment segment;
diff --git a/core/math/bvh_debug.inc b/core/math/bvh_debug.inc
index a97304334c..55db794ee3 100644
--- a/core/math/bvh_debug.inc
+++ b/core/math/bvh_debug.inc
@@ -6,24 +6,21 @@ void _debug_recursive_print_tree(int p_tree_id) const {
}
String _debug_aabb_to_string(const BVHABB_CLASS &aabb) const {
- String sz = "(";
- sz += itos(aabb.min.x);
- sz += " ~ ";
- sz += itos(-aabb.neg_max.x);
- sz += ") (";
+ Point size = aabb.calculate_size();
- sz += itos(aabb.min.y);
- sz += " ~ ";
- sz += itos(-aabb.neg_max.y);
- sz += ") (";
+ String sz;
+ float vol = 0.0;
- sz += itos(aabb.min.z);
- sz += " ~ ";
- sz += itos(-aabb.neg_max.z);
- sz += ") ";
+ for (int i = 0; i < Point::AXES_COUNT; ++i) {
+ sz += "(";
+ sz += itos(aabb.min[i]);
+ sz += " ~ ";
+ sz += itos(-aabb.neg_max[i]);
+ sz += ") ";
+
+ vol += size[i];
+ }
- Vector3 size = aabb.calculate_size();
- float vol = size.x * size.y * size.z;
sz += "vol " + itos(vol);
return sz;
diff --git a/core/math/bvh_split.inc b/core/math/bvh_split.inc
index 3fcc4c7b10..6f54d06ce7 100644
--- a/core/math/bvh_split.inc
+++ b/core/math/bvh_split.inc
@@ -28,11 +28,15 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u
Point centre = full_bound.calculate_centre();
Point size = full_bound.calculate_size();
- int order[3];
+ int order[Point::AXIS_COUNT];
order[0] = size.min_axis();
- order[2] = size.max_axis();
- order[1] = 3 - (order[0] + order[2]);
+ order[Point::AXIS_COUNT - 1] = size.max_axis();
+
+ static_assert(Point::AXIS_COUNT <= 3);
+ if (Point::AXIS_COUNT == 3) {
+ order[1] = 3 - (order[0] + order[2]);
+ }
// simplest case, split on the longest axis
int split_axis = order[0];
@@ -54,7 +58,7 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u
// detect when split on longest axis failed
int min_threshold = MAX_ITEMS / 4;
- int min_group_size[3];
+ int min_group_size[Point::AXIS_COUNT];
min_group_size[0] = MIN(num_a, num_b);
if (min_group_size[0] < min_threshold) {
// slow but sure .. first move everything back into a
@@ -64,7 +68,7 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u
num_b = 0;
// now calculate the best split
- for (int axis = 1; axis < 3; axis++) {
+ for (int axis = 1; axis < Point::AXIS_COUNT; axis++) {
split_axis = order[axis];
int count = 0;
@@ -82,7 +86,7 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u
// best axis
int best_axis = 0;
int best_min = min_group_size[0];
- for (int axis = 1; axis < 3; axis++) {
+ for (int axis = 1; axis < Point::AXIS_COUNT; axis++) {
if (min_group_size[axis] > best_min) {
best_min = min_group_size[axis];
best_axis = axis;
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index 0960fe19a6..d438a9a377 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -265,8 +265,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_
//create new faces from horizon edges
List<List<Face>::Element *> new_faces; //new faces
- for (Map<Edge, FaceConnect>::Element *E = lit_edges.front(); E; E = E->next()) {
- FaceConnect &fc = E->get();
+ for (KeyValue<Edge, FaceConnect> &E : lit_edges) {
+ FaceConnect &fc = E.value;
if (fc.left && fc.right) {
continue; //edge is uninteresting, not on horizon
}
@@ -275,8 +275,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_
Face face;
face.vertices[0] = f.points_over[next];
- face.vertices[1] = E->key().vertices[0];
- face.vertices[2] = E->key().vertices[1];
+ face.vertices[1] = E.key.vertices[0];
+ face.vertices[2] = E.key.vertices[1];
Plane p(p_points[face.vertices[0]], p_points[face.vertices[1]], p_points[face.vertices[2]]);
@@ -418,13 +418,13 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_
}
// remove all edge connections to this face
- for (Map<Edge, RetFaceConnect>::Element *G = ret_edges.front(); G; G = G->next()) {
- if (G->get().left == O) {
- G->get().left = nullptr;
+ for (KeyValue<Edge, RetFaceConnect> &G : ret_edges) {
+ if (G.value.left == O) {
+ G.value.left = nullptr;
}
- if (G->get().right == O) {
- G->get().right = nullptr;
+ if (G.value.right == O) {
+ G.value.right = nullptr;
}
}
@@ -444,10 +444,10 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_
}
r_mesh.edges.resize(ret_edges.size());
idx = 0;
- for (Map<Edge, RetFaceConnect>::Element *E = ret_edges.front(); E; E = E->next()) {
+ for (const KeyValue<Edge, RetFaceConnect> &E : ret_edges) {
Geometry3D::MeshData::Edge e;
- e.a = E->key().vertices[0];
- e.b = E->key().vertices[1];
+ e.a = E.key.vertices[0];
+ e.b = E.key.vertices[1];
r_mesh.edges.write[idx++] = e;
}
diff --git a/core/math/static_raycaster.cpp b/core/math/static_raycaster.cpp
new file mode 100644
index 0000000000..da05d49428
--- /dev/null
+++ b/core/math/static_raycaster.cpp
@@ -0,0 +1,40 @@
+/*************************************************************************/
+/* static_raycaster.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "static_raycaster.h"
+
+StaticRaycaster *(*StaticRaycaster::create_function)() = nullptr;
+
+Ref<StaticRaycaster> StaticRaycaster::create() {
+ if (create_function) {
+ return Ref<StaticRaycaster>(create_function());
+ }
+ return Ref<StaticRaycaster>();
+}
diff --git a/core/math/static_raycaster.h b/core/math/static_raycaster.h
new file mode 100644
index 0000000000..3759c788a7
--- /dev/null
+++ b/core/math/static_raycaster.h
@@ -0,0 +1,111 @@
+/*************************************************************************/
+/* static_raycaster.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef STATIC_RAYCASTER_H
+#define STATIC_RAYCASTER_H
+
+#include "core/object/ref_counted.h"
+
+#if !defined(__aligned)
+
+#if defined(_WIN32) && defined(_MSC_VER)
+#define __aligned(...) __declspec(align(__VA_ARGS__))
+#else
+#define __aligned(...) __attribute__((aligned(__VA_ARGS__)))
+#endif
+
+#endif
+
+class StaticRaycaster : public RefCounted {
+ GDCLASS(StaticRaycaster, RefCounted)
+protected:
+ static StaticRaycaster *(*create_function)();
+
+public:
+ // compatible with embree3 rays
+ struct __aligned(16) Ray {
+ const static unsigned int INVALID_GEOMETRY_ID = ((unsigned int)-1); // from rtcore_common.h
+
+ /*! Default construction does nothing. */
+ _FORCE_INLINE_ Ray() :
+ geomID(INVALID_GEOMETRY_ID) {}
+
+ /*! Constructs a ray from origin, direction, and ray segment. Near
+ * has to be smaller than far. */
+ _FORCE_INLINE_ Ray(const Vector3 &org,
+ const Vector3 &dir,
+ float tnear = 0.0f,
+ float tfar = INFINITY) :
+ org(org),
+ tnear(tnear),
+ dir(dir),
+ time(0.0f),
+ tfar(tfar),
+ mask(-1),
+ u(0.0),
+ v(0.0),
+ primID(INVALID_GEOMETRY_ID),
+ geomID(INVALID_GEOMETRY_ID),
+ instID(INVALID_GEOMETRY_ID) {}
+
+ /*! Tests if we hit something. */
+ _FORCE_INLINE_ explicit operator bool() const { return geomID != INVALID_GEOMETRY_ID; }
+
+ public:
+ Vector3 org; //!< Ray origin + tnear
+ float tnear; //!< Start of ray segment
+ Vector3 dir; //!< Ray direction + tfar
+ float time; //!< Time of this ray for motion blur.
+ float tfar; //!< End of ray segment
+ unsigned int mask; //!< used to mask out objects during traversal
+ unsigned int id; //!< ray ID
+ unsigned int flags; //!< ray flags
+
+ Vector3 normal; //!< Not normalized geometry normal
+ float u; //!< Barycentric u coordinate of hit
+ float v; //!< Barycentric v coordinate of hit
+ unsigned int primID; //!< primitive ID
+ unsigned int geomID; //!< geometry ID
+ unsigned int instID; //!< instance ID
+ };
+
+ virtual bool intersect(Ray &p_ray) = 0;
+ virtual void intersect(Vector<Ray> &r_rays) = 0;
+
+ virtual void add_mesh(const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices, unsigned int p_id) = 0;
+ virtual void commit() = 0;
+
+ virtual void set_mesh_filter(const Set<int> &p_mesh_ids) = 0;
+ virtual void clear_mesh_filter() = 0;
+
+ static Ref<StaticRaycaster> create();
+};
+
+#endif // STATIC_RAYCASTER_H
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index 16d9652ef2..2f3da0b6a8 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -157,8 +157,8 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces) {
vertices.resize(db.size());
Vector3 *vw = vertices.ptrw();
- for (Map<Vector3, int>::Element *E = db.front(); E; E = E->next()) {
- vw[E->get()] = E->key();
+ for (const KeyValue<Vector3, int> &E : db) {
+ vw[E.value] = E.key;
}
}
diff --git a/core/multiplayer/multiplayer.h b/core/multiplayer/multiplayer.h
index 00c81d3c9a..31b7bf0043 100644
--- a/core/multiplayer/multiplayer.h
+++ b/core/multiplayer/multiplayer.h
@@ -39,13 +39,13 @@ namespace Multiplayer {
enum TransferMode {
TRANSFER_MODE_UNRELIABLE,
- TRANSFER_MODE_ORDERED,
+ TRANSFER_MODE_UNRELIABLE_ORDERED,
TRANSFER_MODE_RELIABLE
};
enum RPCMode {
RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default)
- RPC_MODE_ANY, // Any peer can call this RPC
+ RPC_MODE_ANY_PEER, // Any peer can call this RPC
RPC_MODE_AUTHORITY, // / Only the node's multiplayer authority (server by default) can call this RPC
};
diff --git a/core/multiplayer/rpc_manager.cpp b/core/multiplayer/rpc_manager.cpp
index 915571375e..20ab7a25bb 100644
--- a/core/multiplayer/rpc_manager.cpp
+++ b/core/multiplayer/rpc_manager.cpp
@@ -99,7 +99,7 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, Multiplayer::RPCMode mode, int
case Multiplayer::RPC_MODE_DISABLED: {
return false;
} break;
- case Multiplayer::RPC_MODE_ANY: {
+ case Multiplayer::RPC_MODE_ANY_PEER: {
return true;
} break;
case Multiplayer::RPC_MODE_AUTHORITY: {
diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp
index 4751c69f1e..736e940846 100644
--- a/core/object/message_queue.cpp
+++ b/core/object/message_queue.cpp
@@ -227,16 +227,16 @@ void MessageQueue::statistics() {
print_line("TOTAL BYTES: " + itos(buffer_end));
print_line("NULL count: " + itos(null_count));
- for (Map<StringName, int>::Element *E = set_count.front(); E; E = E->next()) {
- print_line("SET " + E->key() + ": " + itos(E->get()));
+ for (const KeyValue<StringName, int> &E : set_count) {
+ print_line("SET " + E.key + ": " + itos(E.value));
}
- for (Map<Callable, int>::Element *E = call_count.front(); E; E = E->next()) {
- print_line("CALL " + E->key() + ": " + itos(E->get()));
+ for (const KeyValue<Callable, int> &E : call_count) {
+ print_line("CALL " + E.key + ": " + itos(E.value));
}
- for (Map<int, int>::Element *E = notify_count.front(); E; E = E->next()) {
- print_line("NOTIFY " + itos(E->key()) + ": " + itos(E->get()));
+ for (const KeyValue<int, int> &E : notify_count) {
+ print_line("NOTIFY " + itos(E.key) + ": " + itos(E.value));
}
}
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 3335942fb3..b5797a4633 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -1409,7 +1409,7 @@ void Object::_disconnect(const StringName &p_signal, const Callable &p_callable,
if (!p_force) {
slot->reference_count--; // by default is zero, if it was not referenced it will go below it
- if (slot->reference_count >= 0) {
+ if (slot->reference_count > 0) {
return;
}
}
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index 0fb8c7350c..b0ce46ca2b 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -93,8 +93,8 @@ Dictionary Script::_get_script_constant_map() {
Dictionary ret;
Map<StringName, Variant> map;
get_constants(&map);
- for (Map<StringName, Variant>::Element *E = map.front(); E; E = E->next()) {
- ret[E->key()] = E->value();
+ for (const KeyValue<StringName, Variant> &E : map) {
+ ret[E.key] = E.value;
}
return ret;
}
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 7505f3ff34..12f85858c3 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -36,7 +36,6 @@
#include "core/io/file_access.h"
#include "core/os/midi_driver.h"
#include "core/version_generated.gen.h"
-#include "servers/audio_server.h"
#include <stdarg.h>
@@ -282,6 +281,11 @@ String OS::get_bundle_resource_dir() const {
return ".";
}
+// Path to macOS .app bundle embedded icon
+String OS::get_bundle_icon_path() const {
+ return String();
+}
+
// OS specific path for user://
String OS::get_user_data_dir() const {
return ".";
diff --git a/core/os/os.h b/core/os/os.h
index c027428477..29d33ce4f0 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -252,6 +252,7 @@ public:
virtual String get_config_path() const;
virtual String get_cache_path() const;
virtual String get_bundle_resource_dir() const;
+ virtual String get_bundle_icon_path() const;
virtual String get_user_data_dir() const;
virtual String get_resource_dir() const;
diff --git a/core/os/thread.cpp b/core/os/thread.cpp
index 92e43963d2..27aefc98de 100644
--- a/core/os/thread.cpp
+++ b/core/os/thread.cpp
@@ -28,9 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-// Define PLATFORM_CUSTOM_THREAD_H in platform_config.h
-// Overriding the platform implementation is required in some proprietary platforms
-#ifndef PLATFORM_CUSTOM_THREAD_H
+#ifndef PLATFORM_THREAD_OVERRIDE // See details in thread.h
#include "thread.h"
@@ -130,4 +128,4 @@ Thread::~Thread() {
}
#endif
-#endif // PLATFORM_CUSTOM_THREAD_H
+#endif // PLATFORM_THREAD_OVERRIDE
diff --git a/core/os/thread.h b/core/os/thread.h
index 3a0938c7f7..59cb58ac57 100644
--- a/core/os/thread.h
+++ b/core/os/thread.h
@@ -28,10 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-// Define PLATFORM_CUSTOM_THREAD_H in platform_config.h
+// Define PLATFORM_THREAD_OVERRIDE in your platform's `platform_config.h`
+// to use a custom Thread implementation defined in `platform/[your_platform]/platform_thread.h`
// Overriding the platform implementation is required in some proprietary platforms
-#ifdef PLATFORM_CUSTOM_THREAD_H
-#include PLATFORM_CUSTOM_THREAD_H
+#ifdef PLATFORM_THREAD_OVERRIDE
+#include "platform_thread.h"
#else
#ifndef THREAD_H
#define THREAD_H
@@ -121,4 +122,4 @@ public:
};
#endif // THREAD_H
-#endif // PLATFORM_CUSTOM_THREAD_H
+#endif // PLATFORM_THREAD_OVERRIDE
diff --git a/core/string/optimized_translation.cpp b/core/string/optimized_translation.cpp
index 5863bd1c46..839b7a9c01 100644
--- a/core/string/optimized_translation.cpp
+++ b/core/string/optimized_translation.cpp
@@ -162,11 +162,11 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) {
btw[btindex++] = t.size();
btw[btindex++] = hfunc_table[i];
- for (Map<uint32_t, int>::Element *E = t.front(); E; E = E->next()) {
- btw[btindex++] = E->key();
- btw[btindex++] = compressed[E->get()].offset;
- btw[btindex++] = compressed[E->get()].compressed.size();
- btw[btindex++] = compressed[E->get()].orig_len;
+ for (const KeyValue<uint32_t, int> &E : t) {
+ btw[btindex++] = E.key;
+ btw[btindex++] = compressed[E.value].offset;
+ btw[btindex++] = compressed[E.value].compressed.size();
+ btw[btindex++] = compressed[E.value].orig_len;
}
}
diff --git a/core/string/translation.cpp b/core/string/translation.cpp
index af27219a60..cf61467d08 100644
--- a/core/string/translation.cpp
+++ b/core/string/translation.cpp
@@ -35,7 +35,6 @@
#include "core/os/os.h"
#ifdef TOOLS_ENABLED
-#include "editor/editor_settings.h"
#include "main/main.h"
#endif
@@ -823,8 +822,8 @@ static const char *locale_renames[][2] = {
Dictionary Translation::_get_messages() const {
Dictionary d;
- for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) {
- d[E->key()] = E->value();
+ for (const KeyValue<StringName, StringName> &E : translation_map) {
+ d[E.key] = E.value;
}
return d;
}
@@ -833,8 +832,8 @@ Vector<String> Translation::_get_message_list() const {
Vector<String> msgs;
msgs.resize(translation_map.size());
int idx = 0;
- for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) {
- msgs.set(idx, E->key());
+ for (const KeyValue<StringName, StringName> &E : translation_map) {
+ msgs.set(idx, E.key);
idx += 1;
}
@@ -914,8 +913,8 @@ void Translation::erase_message(const StringName &p_src_text, const StringName &
}
void Translation::get_message_list(List<StringName> *r_messages) const {
- for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) {
- r_messages->push_back(E->key());
+ for (const KeyValue<StringName, StringName> &E : translation_map) {
+ r_messages->push_back(E.key);
}
}
diff --git a/core/string/ustring.h b/core/string/ustring.h
index 24da6b82af..1d80ccf58d 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -51,11 +51,15 @@ class CharProxy {
CowData<T> &_cowdata;
static const T _null = 0;
- _FORCE_INLINE_ CharProxy(const int &p_index, CowData<T> &cowdata) :
+ _FORCE_INLINE_ CharProxy(const int &p_index, CowData<T> &p_cowdata) :
_index(p_index),
- _cowdata(cowdata) {}
+ _cowdata(p_cowdata) {}
public:
+ _FORCE_INLINE_ CharProxy(const CharProxy<T> &p_other) :
+ _index(p_other._index),
+ _cowdata(p_other._cowdata) {}
+
_FORCE_INLINE_ operator T() const {
if (unlikely(_index == _cowdata.size())) {
return _null;
@@ -68,12 +72,12 @@ public:
return _cowdata.ptr() + _index;
}
- _FORCE_INLINE_ void operator=(const T &other) const {
- _cowdata.set(_index, other);
+ _FORCE_INLINE_ void operator=(const T &p_other) const {
+ _cowdata.set(_index, p_other);
}
- _FORCE_INLINE_ void operator=(const CharProxy<T> &other) const {
- _cowdata.set(_index, other.operator T());
+ _FORCE_INLINE_ void operator=(const CharProxy<T> &p_other) const {
+ _cowdata.set(_index, p_other.operator T());
}
};
diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h
index e947d2211c..71d41eacc4 100644
--- a/core/templates/rid_owner.h
+++ b/core/templates/rid_owner.h
@@ -151,7 +151,7 @@ public:
return _allocate_rid();
}
- _FORCE_INLINE_ T *getornull(const RID &p_rid, bool p_initialize = false) {
+ _FORCE_INLINE_ T *get_or_null(const RID &p_rid, bool p_initialize = false) {
if (p_rid == RID()) {
return nullptr;
}
@@ -210,12 +210,12 @@ public:
return ptr;
}
void initialize_rid(RID p_rid) {
- T *mem = getornull(p_rid, true);
+ T *mem = get_or_null(p_rid, true);
ERR_FAIL_COND(!mem);
memnew_placement(mem, T);
}
void initialize_rid(RID p_rid, const T &p_value) {
- T *mem = getornull(p_rid, true);
+ T *mem = get_or_null(p_rid, true);
ERR_FAIL_COND(!mem);
memnew_placement(mem, T(p_value));
}
@@ -399,8 +399,8 @@ public:
alloc.initialize_rid(p_rid, p_ptr);
}
- _FORCE_INLINE_ T *getornull(const RID &p_rid) {
- T **ptr = alloc.getornull(p_rid);
+ _FORCE_INLINE_ T *get_or_null(const RID &p_rid) {
+ T **ptr = alloc.get_or_null(p_rid);
if (unlikely(!ptr)) {
return nullptr;
}
@@ -408,7 +408,7 @@ public:
}
_FORCE_INLINE_ void replace(const RID &p_rid, T *p_new_ptr) {
- T **ptr = alloc.getornull(p_rid);
+ T **ptr = alloc.get_or_null(p_rid);
ERR_FAIL_COND(!ptr);
*ptr = p_new_ptr;
}
@@ -469,8 +469,8 @@ public:
alloc.initialize_rid(p_rid, p_ptr);
}
- _FORCE_INLINE_ T *getornull(const RID &p_rid) {
- return alloc.getornull(p_rid);
+ _FORCE_INLINE_ T *get_or_null(const RID &p_rid) {
+ return alloc.get_or_null(p_rid);
}
_FORCE_INLINE_ bool owns(const RID &p_rid) {
diff --git a/core/templates/search_array.h b/core/templates/search_array.h
new file mode 100644
index 0000000000..8efc32df82
--- /dev/null
+++ b/core/templates/search_array.h
@@ -0,0 +1,67 @@
+/*************************************************************************/
+/* search_array.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SEARCH_ARRAY_H
+#define SEARCH_ARRAY_H
+
+#include <core/templates/sort_array.h>
+
+template <class T, class Comparator = _DefaultComparator<T>>
+class SearchArray {
+public:
+ Comparator compare;
+
+ inline int bisect(const T *p_array, int p_len, const T &p_value, bool p_before) const {
+ int lo = 0;
+ int hi = p_len;
+ if (p_before) {
+ while (lo < hi) {
+ const int mid = (lo + hi) / 2;
+ if (compare(p_array[mid], p_value)) {
+ lo = mid + 1;
+ } else {
+ hi = mid;
+ }
+ }
+ } else {
+ while (lo < hi) {
+ const int mid = (lo + hi) / 2;
+ if (compare(p_value, p_array[mid])) {
+ hi = mid;
+ } else {
+ lo = mid + 1;
+ }
+ }
+ }
+ return lo;
+ }
+};
+
+#endif // SEARCH_ARRAY_H
diff --git a/core/templates/vector.h b/core/templates/vector.h
index 2600604eb7..4b008a45a4 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -40,6 +40,7 @@
#include "core/error/error_macros.h"
#include "core/os/memory.h"
#include "core/templates/cowdata.h"
+#include "core/templates/search_array.h"
#include "core/templates/sort_array.h"
template <class T>
@@ -112,6 +113,11 @@ public:
sort_custom<_DefaultComparator<T>>();
}
+ int bsearch(const T &p_value, bool p_before) {
+ SearchArray<T> search;
+ return search.bisect(ptrw(), size(), p_value, p_before);
+ }
+
Vector<T> duplicate() {
return *this;
}
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index 8373cbd4e8..b4d6dffc6f 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -34,6 +34,7 @@
#include "core/object/class_db.h"
#include "core/object/script_language.h"
#include "core/templates/hashfuncs.h"
+#include "core/templates/search_array.h"
#include "core/templates/vector.h"
#include "core/variant/callable.h"
#include "core/variant/variant.h"
@@ -484,44 +485,19 @@ void Array::shuffle() {
}
}
-template <typename Less>
-_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) {
- int lo = 0;
- int hi = p_array.size();
- if (p_before) {
- while (lo < hi) {
- const int mid = (lo + hi) / 2;
- if (p_less(p_array.get(mid), p_value)) {
- lo = mid + 1;
- } else {
- hi = mid;
- }
- }
- } else {
- while (lo < hi) {
- const int mid = (lo + hi) / 2;
- if (p_less(p_value, p_array.get(mid))) {
- hi = mid;
- } else {
- lo = mid + 1;
- }
- }
- }
- return lo;
-}
-
int Array::bsearch(const Variant &p_value, bool p_before) {
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "binary search"), -1);
- return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
+ SearchArray<Variant, _ArrayVariantSort> avs;
+ return avs.bisect(_p->array.ptrw(), _p->array.size(), p_value, p_before);
}
int Array::bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before) {
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1);
- _ArrayVariantSortCustom less;
- less.func = p_callable;
+ SearchArray<Variant, _ArrayVariantSortCustom> avs;
+ avs.compare.func = p_callable;
- return bisect(_p->array, p_value, p_before, less);
+ return avs.bisect(_p->array.ptrw(), _p->array.size(), p_value, p_before);
}
void Array::reverse() {
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 32d6778a2b..6284caae2d 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1241,8 +1241,8 @@ void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_c
for (List<StringName>::Element *E = cd.value_ordered.front(); E; E = E->next()) {
p_constants->push_back(E->get());
#else
- for (Map<StringName, int>::Element *E = cd.value.front(); E; E = E->next()) {
- p_constants->push_back(E->key());
+ for (const KeyValue<StringName, int> &E : cd.value) {
+ p_constants->push_back(E.key);
#endif
}
@@ -1250,8 +1250,8 @@ void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_c
for (List<StringName>::Element *E = cd.variant_value_ordered.front(); E; E = E->next()) {
p_constants->push_back(E->get());
#else
- for (Map<StringName, Variant>::Element *E = cd.variant_value.front(); E; E = E->next()) {
- p_constants->push_back(E->key());
+ for (const KeyValue<StringName, Variant> &E : cd.variant_value) {
+ p_constants->push_back(E.key);
#endif
}
}
@@ -1845,6 +1845,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedByteArray, reverse, sarray(), varray());
bind_method(PackedByteArray, subarray, sarray("from", "to"), varray());
bind_method(PackedByteArray, sort, sarray(), varray());
+ bind_method(PackedByteArray, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedByteArray, duplicate, sarray(), varray());
bind_function(PackedByteArray, get_string_from_ascii, _VariantCall::func_PackedByteArray_get_string_from_ascii, sarray(), varray());
@@ -1906,6 +1907,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedInt32Array, subarray, sarray("from", "to"), varray());
bind_method(PackedInt32Array, to_byte_array, sarray(), varray());
bind_method(PackedInt32Array, sort, sarray(), varray());
+ bind_method(PackedInt32Array, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedInt32Array, duplicate, sarray(), varray());
/* Int64 Array */
@@ -1925,6 +1927,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedInt64Array, subarray, sarray("from", "to"), varray());
bind_method(PackedInt64Array, to_byte_array, sarray(), varray());
bind_method(PackedInt64Array, sort, sarray(), varray());
+ bind_method(PackedInt64Array, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedInt64Array, duplicate, sarray(), varray());
/* Float32 Array */
@@ -1944,6 +1947,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedFloat32Array, subarray, sarray("from", "to"), varray());
bind_method(PackedFloat32Array, to_byte_array, sarray(), varray());
bind_method(PackedFloat32Array, sort, sarray(), varray());
+ bind_method(PackedFloat32Array, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedFloat32Array, duplicate, sarray(), varray());
/* Float64 Array */
@@ -1963,6 +1967,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedFloat64Array, subarray, sarray("from", "to"), varray());
bind_method(PackedFloat64Array, to_byte_array, sarray(), varray());
bind_method(PackedFloat64Array, sort, sarray(), varray());
+ bind_method(PackedFloat64Array, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedFloat64Array, duplicate, sarray(), varray());
/* String Array */
@@ -1982,6 +1987,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedStringArray, subarray, sarray("from", "to"), varray());
bind_method(PackedStringArray, to_byte_array, sarray(), varray());
bind_method(PackedStringArray, sort, sarray(), varray());
+ bind_method(PackedStringArray, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedStringArray, duplicate, sarray(), varray());
/* Vector2 Array */
@@ -2001,6 +2007,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedVector2Array, subarray, sarray("from", "to"), varray());
bind_method(PackedVector2Array, to_byte_array, sarray(), varray());
bind_method(PackedVector2Array, sort, sarray(), varray());
+ bind_method(PackedVector2Array, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedVector2Array, duplicate, sarray(), varray());
/* Vector3 Array */
@@ -2020,6 +2027,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedVector3Array, subarray, sarray("from", "to"), varray());
bind_method(PackedVector3Array, to_byte_array, sarray(), varray());
bind_method(PackedVector3Array, sort, sarray(), varray());
+ bind_method(PackedVector3Array, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedVector3Array, duplicate, sarray(), varray());
/* Color Array */
@@ -2039,6 +2047,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedColorArray, subarray, sarray("from", "to"), varray());
bind_method(PackedColorArray, to_byte_array, sarray(), varray());
bind_method(PackedColorArray, sort, sarray(), varray());
+ bind_method(PackedColorArray, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedColorArray, duplicate, sarray(), varray());
/* Register constants */