diff --git a/interfaces/Crafter.Event.cppm b/interfaces/Crafter.Event.cppm index 9c526b1..d1997fc 100644 --- a/interfaces/Crafter.Event.cppm +++ b/interfaces/Crafter.Event.cppm @@ -63,6 +63,7 @@ namespace Crafter { std::map*, std::chrono::nanoseconds> listenerTimes; #endif protected: + bool deleted = false; std::map*>> listeners; public: @@ -78,7 +79,8 @@ namespace Crafter { } EventBase(EventBase&) = delete; EventBase& operator=(EventBase&) = delete; - virtual ~EventBase() { + ~EventBase() { + deleted = true; for (const auto& listenerSlice : listeners) { for (const auto& listener : listenerSlice.second) { if(listener) { @@ -170,19 +172,29 @@ namespace Crafter { this->listenerTimes.clear(); #endif - for (auto& listenerSlice : this->listeners) { - listenerSlice.second.erase(std::remove(listenerSlice.second.begin(), listenerSlice.second.end(), static_cast*>(nullptr)), listenerSlice.second.end()); - auto sliceCopy = listenerSlice.second; - for (const auto& listener : sliceCopy) { - #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(end - start); - this->listenerTimes[listener] = duration; - #endif + std::vector keys; + for (const auto& pair : this->listeners) { + 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*>(nullptr)), it->second.end()); + auto sliceCopy = it->second; + for (const auto& listener : sliceCopy) { + #ifdef CRAFTER_TIMING + auto start = std::chrono::high_resolution_clock::now(); + #endif + listener->function(); + if(deleted) { + return; + } + #ifdef CRAFTER_TIMING + auto end = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end - start); + this->listenerTimes[listener] = duration; + #endif + } } } removeEmptyListeners(); @@ -200,19 +212,29 @@ namespace Crafter { this->listenerTimes.clear(); #endif - for (auto& listenerSlice : this->listeners) { - listenerSlice.second.erase(std::remove(listenerSlice.second.begin(), listenerSlice.second.end(), static_cast*>(nullptr)), listenerSlice.second.end()); - auto sliceCopy = listenerSlice.second; - for (const auto& listener : sliceCopy) { - #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(end - start); - this->listenerTimes[listener] = duration; - #endif + std::vector keys; + for (const auto& pair : this->listeners) { + 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*>(nullptr)), it->second.end()); + auto sliceCopy = it->second; + for (const auto& listener : sliceCopy) { + #ifdef CRAFTER_TIMING + auto start = std::chrono::high_resolution_clock::now(); + #endif + listener->function(data); + if(this->deleted) { + return; + } + #ifdef CRAFTER_TIMING + auto end = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end - start); + this->listenerTimes[listener] = duration; + #endif + } } } EventBase::removeEmptyListeners();