Avoid sorting CallableCustomMethodPointers by their actual address values
This commit is contained in:
parent
668cf3c66f
commit
5cc961627d
|
@ -38,13 +38,10 @@ bool CallableCustomMethodPointerBase::compare_equal(const CallableCustom *p_a, c
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < a->comp_size; i++) {
|
// Avoid sorting by memory address proximity, which leads to unpredictable performance over time
|
||||||
if (a->comp_ptr[i] != b->comp_ptr[i]) {
|
// due to the reuse of old addresses for newer objects. Use byte-wise comparison to leverage the
|
||||||
return false;
|
// backwards encoding of little-endian systems as a way to decouple spatiality and time.
|
||||||
}
|
return memcmp(a->comp_ptr, b->comp_ptr, a->comp_size * 4) == 0;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CallableCustomMethodPointerBase::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
|
bool CallableCustomMethodPointerBase::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
|
||||||
|
@ -55,15 +52,8 @@ bool CallableCustomMethodPointerBase::compare_less(const CallableCustom *p_a, co
|
||||||
return a->comp_size < b->comp_size;
|
return a->comp_size < b->comp_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < a->comp_size; i++) {
|
// See note in compare_equal().
|
||||||
if (a->comp_ptr[i] == b->comp_ptr[i]) {
|
return memcmp(a->comp_ptr, b->comp_ptr, a->comp_size * 4) < 0;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a->comp_ptr[i] < b->comp_ptr[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CallableCustom::CompareEqualFunc CallableCustomMethodPointerBase::get_compare_equal_func() const {
|
CallableCustom::CompareEqualFunc CallableCustomMethodPointerBase::get_compare_equal_func() const {
|
||||||
|
|
|
@ -399,6 +399,29 @@ TEST_CASE("[Object] Signals") {
|
||||||
SIGNAL_CHECK("my_custom_signal", empty_signal_args);
|
SIGNAL_CHECK("my_custom_signal", empty_signal_args);
|
||||||
SIGNAL_UNWATCH(&object, "my_custom_signal");
|
SIGNAL_UNWATCH(&object, "my_custom_signal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBCASE("Connecting and then disconnecting many signals should not leave anything behind") {
|
||||||
|
List<Object::Connection> signal_connections;
|
||||||
|
Object targets[100];
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
ERR_PRINT_OFF;
|
||||||
|
for (Object &target : targets) {
|
||||||
|
object.connect("my_custom_signal", callable_mp(&target, &Object::notify_property_list_changed));
|
||||||
|
}
|
||||||
|
ERR_PRINT_ON;
|
||||||
|
signal_connections.clear();
|
||||||
|
object.get_all_signal_connections(&signal_connections);
|
||||||
|
CHECK(signal_connections.size() == 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Object &target : targets) {
|
||||||
|
object.disconnect("my_custom_signal", callable_mp(&target, &Object::notify_property_list_changed));
|
||||||
|
}
|
||||||
|
signal_connections.clear();
|
||||||
|
object.get_all_signal_connections(&signal_connections);
|
||||||
|
CHECK(signal_connections.size() == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace TestObject
|
} // namespace TestObject
|
||||||
|
|
Loading…
Reference in New Issue