summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authormyaaaaaaaaa <103326468+myaaaaaaaaa@users.noreply.github.com>2023-01-30 11:46:56 -0500
committermyaaaaaaaaa <103326468+myaaaaaaaaa@users.noreply.github.com>2023-02-25 18:44:09 -0500
commit1ec5381c1612bd739e31aa2bd04ed287b5fe2aba (patch)
treeba7b09e2f9aa61931590a9cd36405f11a418dc6a /core
parent17a85973559fae0cd2c33d13c4b53f16cf7419ba (diff)
downloadredot-engine-1ec5381c1612bd739e31aa2bd04ed287b5fe2aba.tar.gz
Store Object signals in a HashMap rather than a VMap
Diffstat (limited to 'core')
-rw-r--r--core/object/object.cpp41
-rw-r--r--core/object/object.h3
-rw-r--r--core/templates/hashfuncs.h6
3 files changed, 28 insertions, 22 deletions
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 57aa1339ec..9382674c4e 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -38,6 +38,7 @@
#include "core/os/os.h"
#include "core/string/print_string.h"
#include "core/string/translation.h"
+#include "core/templates/local_vector.h"
#include "core/variant/typed_array.h"
#ifdef DEBUG_ENABLED
@@ -1014,20 +1015,23 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int
List<_ObjectSignalDisconnectData> disconnect_data;
- //copy on write will ensure that disconnecting the signal or even deleting the object will not affect the signal calling.
- //this happens automatically and will not change the performance of calling.
- //awesome, isn't it?
- VMap<Callable, SignalData::Slot> slot_map = s->slot_map;
-
- int ssize = slot_map.size();
+ // Ensure that disconnecting the signal or even deleting the object
+ // will not affect the signal calling.
+ LocalVector<Connection> slot_conns;
+ slot_conns.resize(s->slot_map.size());
+ {
+ uint32_t idx = 0;
+ for (const KeyValue<Callable, SignalData::Slot> &slot_kv : s->slot_map) {
+ slot_conns[idx++] = slot_kv.value.conn;
+ }
+ DEV_ASSERT(idx == s->slot_map.size());
+ }
OBJ_DEBUG_LOCK
Error err = OK;
- for (int i = 0; i < ssize; i++) {
- const Connection &c = slot_map.getv(i).conn;
-
+ for (const Connection &c : slot_conns) {
Object *target = c.callable.get_object();
if (!target) {
// Target might have been deleted during signal callback, this is expected and OK.
@@ -1190,8 +1194,8 @@ void Object::get_all_signal_connections(List<Connection> *p_connections) const {
for (const KeyValue<StringName, SignalData> &E : signal_map) {
const SignalData *s = &E.value;
- for (int i = 0; i < s->slot_map.size(); i++) {
- p_connections->push_back(s->slot_map.getv(i).conn);
+ for (const KeyValue<Callable, SignalData::Slot> &slot_kv : s->slot_map) {
+ p_connections->push_back(slot_kv.value.conn);
}
}
}
@@ -1202,8 +1206,8 @@ void Object::get_signal_connection_list(const StringName &p_signal, List<Connect
return; //nothing
}
- for (int i = 0; i < s->slot_map.size(); i++) {
- p_connections->push_back(s->slot_map.getv(i).conn);
+ for (const KeyValue<Callable, SignalData::Slot> &slot_kv : s->slot_map) {
+ p_connections->push_back(slot_kv.value.conn);
}
}
@@ -1213,8 +1217,8 @@ int Object::get_persistent_signal_connection_count() const {
for (const KeyValue<StringName, SignalData> &E : signal_map) {
const SignalData *s = &E.value;
- for (int i = 0; i < s->slot_map.size(); i++) {
- if (s->slot_map.getv(i).conn.flags & CONNECT_PERSIST) {
+ for (const KeyValue<Callable, SignalData::Slot> &slot_kv : s->slot_map) {
+ if (slot_kv.value.conn.flags & CONNECT_PERSIST) {
count += 1;
}
}
@@ -1789,11 +1793,8 @@ Object::~Object() {
SignalData *s = &E.value;
//brute force disconnect for performance
- int slot_count = s->slot_map.size();
- const VMap<Callable, SignalData::Slot>::Pair *slot_list = s->slot_map.get_array();
-
- for (int i = 0; i < slot_count; i++) {
- slot_list[i].value.conn.callable.get_object()->connections.erase(slot_list[i].value.cE);
+ for (const KeyValue<Callable, SignalData::Slot> &slot_kv : s->slot_map) {
+ slot_kv.value.conn.callable.get_object()->connections.erase(slot_kv.value.cE);
}
signal_map.erase(E.key);
diff --git a/core/object/object.h b/core/object/object.h
index 5ec69a371b..013bccb372 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -41,7 +41,6 @@
#include "core/templates/list.h"
#include "core/templates/rb_map.h"
#include "core/templates/safe_refcount.h"
-#include "core/templates/vmap.h"
#include "core/variant/callable_bind.h"
#include "core/variant/variant.h"
@@ -590,7 +589,7 @@ private:
};
MethodInfo user;
- VMap<Callable, Slot> slot_map;
+ HashMap<Callable, Slot, HashableHasher<Callable>> slot_map;
};
HashMap<StringName, SignalData> signal_map;
diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h
index 95e6bad2f2..2a212f3dcb 100644
--- a/core/templates/hashfuncs.h
+++ b/core/templates/hashfuncs.h
@@ -386,6 +386,12 @@ struct HashMapHasherDefault {
}
};
+// TODO: Fold this into HashMapHasherDefault once C++20 concepts are allowed
+template <class T>
+struct HashableHasher {
+ static _FORCE_INLINE_ uint32_t hash(const T &hashable) { return hashable.hash(); }
+};
+
template <typename T>
struct HashMapComparatorDefault {
static bool compare(const T &p_lhs, const T &p_rhs) {