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));
}
#ifdef CRAFTER_TIMING
// Log timing data in a clear manner
void LogTiming() const {
@ -146,6 +147,16 @@ namespace Crafter {
}
}
#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
@ -156,28 +167,25 @@ namespace Crafter {
void Invoke() {
#ifdef CRAFTER_TIMING
// Clear previous timing data
this->listenerTimes.clear();
#endif
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 (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) {
#ifdef CRAFTER_TIMING
auto start = std::chrono::high_resolution_clock::now();
#endif
listener->function();
#ifdef CRAFTER_TIMING
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
this->listenerTimes[listener] = duration;
}
}
#else
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
}
}
removeEmptyListeners();
}
};
// Generic Event<T> with Invoke signature
@ -188,28 +196,25 @@ namespace Crafter {
void Invoke(T data) {
#ifdef CRAFTER_TIMING
// Clear previous timing data
this->listenerTimes.clear();
#endif
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 (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) {
#ifdef CRAFTER_TIMING
auto start = std::chrono::high_resolution_clock::now();
#endif
listener->function(data);
#ifdef CRAFTER_TIMING
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
this->listenerTimes[listener] = duration;
}
}
#else
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
}
}
EventBase<T>::removeEmptyListeners();
}
};
// Common implementations for EventListener<T>