crash fix

This commit is contained in:
Jorijn van der Graaf 2025-11-26 01:58:01 +01:00
commit 444d5640c8

View file

@ -102,6 +102,7 @@ namespace Crafter {
std::replace(pos->second.begin(), pos->second.end(), listener, static_cast<EventListener<T>*>(nullptr)); std::replace(pos->second.begin(), pos->second.end(), listener, static_cast<EventListener<T>*>(nullptr));
} }
#ifdef CRAFTER_TIMING #ifdef CRAFTER_TIMING
// Log timing data in a clear manner // Log timing data in a clear manner
void LogTiming() const { void LogTiming() const {
@ -146,6 +147,16 @@ namespace Crafter {
} }
} }
#endif #endif
protected:
void removeEmptyListeners() {
for (auto it = listeners.begin(); it != listeners.end(); ) {
if (it->second.empty()) {
it = listeners.erase(it); // Erase and move to the next element
} else {
++it; // Move to the next element
}
}
}
}; };
// Specialized Event<void> with different Invoke signature // Specialized Event<void> with different Invoke signature
@ -155,28 +166,25 @@ namespace Crafter {
using EventBase<void>::EventBase; using EventBase<void>::EventBase;
void Invoke() { void Invoke() {
#ifdef CRAFTER_TIMING #ifdef CRAFTER_TIMING
// Clear previous timing data
this->listenerTimes.clear(); this->listenerTimes.clear();
#endif
this->listeners.erase(std::remove(this->listeners.begin(), this->listeners.end(), static_cast<EventListener<void>>(nullptr)), this->listeners.end()); for (auto& listenerSlice : this->listeners) {
for (const auto& listenerSlice : this->listeners) { listenerSlice.second.erase(std::remove(listenerSlice.second.begin(), listenerSlice.second.end(), static_cast<EventListener<void>*>(nullptr)), listenerSlice.second.end());
for (const auto& listener : listenerSlice.second) { for (const auto& listener : listenerSlice.second) {
#ifdef CRAFTER_TIMING
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
#endif
listener->function(); listener->function();
#ifdef CRAFTER_TIMING
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start); auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
this->listenerTimes[listener] = duration; this->listenerTimes[listener] = duration;
#endif
} }
} }
#else removeEmptyListeners();
this->listeners.erase(std::remove(this->listeners.begin(), this->listeners.end(), static_cast<EventListener<void>>(nullptr)), this->listeners.end());
for (const auto& listenerSlice : this->listeners) {
for (const auto& listener : listenerSlice.second) {
listener->function();
}
}
#endif
} }
}; };
@ -187,28 +195,25 @@ namespace Crafter {
using EventBase<T>::EventBase; using EventBase<T>::EventBase;
void Invoke(T data) { void Invoke(T data) {
#ifdef CRAFTER_TIMING #ifdef CRAFTER_TIMING
// Clear previous timing data
this->listenerTimes.clear(); this->listenerTimes.clear();
#endif
this->listeners.erase(std::remove(this->listeners.begin(), this->listeners.end(), static_cast<EventListener<T>>(nullptr)), this->listeners.end()); for (auto& listenerSlice : this->listeners) {
for (const auto& listenerSlice : this->listeners) { listenerSlice.second.erase(std::remove(listenerSlice.second.begin(), listenerSlice.second.end(), static_cast<EventListener<T>*>(nullptr)), listenerSlice.second.end());
for (const auto& listener : listenerSlice.second) { for (const auto& listener : listenerSlice.second) {
#ifdef CRAFTER_TIMING
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
#endif
listener->function(data); listener->function(data);
#ifdef CRAFTER_TIMING
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start); auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
this->listenerTimes[listener] = duration; this->listenerTimes[listener] = duration;
#endif
} }
} }
#else EventBase<T>::removeEmptyListeners();
this->listeners.erase(std::remove(this->listeners.begin(), this->listeners.end(), static_cast<EventListener<T>>(nullptr)), this->listeners.end());
for (const auto& listenerSlice : this->listeners) {
for (const auto& listener : listenerSlice.second) {
listener->function(data);
}
}
#endif
} }
}; };