crash fix for real this time

This commit is contained in:
Jorijn van der Graaf 2025-11-26 02:52:25 +01:00
commit 99a854d5d1

View file

@ -63,6 +63,7 @@ namespace Crafter {
std::map<const EventListener<T>*, std::chrono::nanoseconds> listenerTimes; std::map<const EventListener<T>*, std::chrono::nanoseconds> listenerTimes;
#endif #endif
protected: protected:
bool deleted = false;
std::map<int, std::vector<EventListener<T>*>> listeners; std::map<int, std::vector<EventListener<T>*>> listeners;
public: public:
@ -78,7 +79,8 @@ namespace Crafter {
} }
EventBase(EventBase&) = delete; EventBase(EventBase&) = delete;
EventBase& operator=(EventBase&) = delete; EventBase& operator=(EventBase&) = delete;
virtual ~EventBase() { ~EventBase() {
deleted = true;
for (const auto& listenerSlice : listeners) { for (const auto& listenerSlice : listeners) {
for (const auto& listener : listenerSlice.second) { for (const auto& listener : listenerSlice.second) {
if(listener) { if(listener) {
@ -170,14 +172,23 @@ namespace Crafter {
this->listenerTimes.clear(); this->listenerTimes.clear();
#endif #endif
for (auto& listenerSlice : this->listeners) { std::vector<std::int_fast32_t> keys;
listenerSlice.second.erase(std::remove(listenerSlice.second.begin(), listenerSlice.second.end(), static_cast<EventListener<void>*>(nullptr)), listenerSlice.second.end()); for (const auto& pair : this->listeners) {
auto sliceCopy = listenerSlice.second; keys.push_back(pair.first);
}
for (std::int_fast32_t key : keys) {
auto it = this->listeners.find(key);
if (it != this->listeners.end()) {
it->second.erase(std::remove(it->second.begin(), it->second.end(), static_cast<EventListener<void>*>(nullptr)), it->second.end());
auto sliceCopy = it->second;
for (const auto& listener : sliceCopy) { for (const auto& listener : sliceCopy) {
#ifdef CRAFTER_TIMING #ifdef CRAFTER_TIMING
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
#endif #endif
listener->function(); listener->function();
if(deleted) {
return;
}
#ifdef CRAFTER_TIMING #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);
@ -185,6 +196,7 @@ namespace Crafter {
#endif #endif
} }
} }
}
removeEmptyListeners(); removeEmptyListeners();
} }
}; };
@ -200,14 +212,23 @@ namespace Crafter {
this->listenerTimes.clear(); this->listenerTimes.clear();
#endif #endif
for (auto& listenerSlice : this->listeners) { std::vector<std::int_fast32_t> keys;
listenerSlice.second.erase(std::remove(listenerSlice.second.begin(), listenerSlice.second.end(), static_cast<EventListener<T>*>(nullptr)), listenerSlice.second.end()); for (const auto& pair : this->listeners) {
auto sliceCopy = listenerSlice.second; keys.push_back(pair.first);
}
for (std::int_fast32_t key : keys) {
auto it = this->listeners.find(key);
if (it != this->listeners.end()) {
it->second.erase(std::remove(it->second.begin(), it->second.end(), static_cast<EventListener<T>*>(nullptr)), it->second.end());
auto sliceCopy = it->second;
for (const auto& listener : sliceCopy) { for (const auto& listener : sliceCopy) {
#ifdef CRAFTER_TIMING #ifdef CRAFTER_TIMING
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
#endif #endif
listener->function(data); listener->function(data);
if(this->deleted) {
return;
}
#ifdef CRAFTER_TIMING #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);
@ -215,6 +236,7 @@ namespace Crafter {
#endif #endif
} }
} }
}
EventBase<T>::removeEmptyListeners(); EventBase<T>::removeEmptyListeners();
} }
}; };