diff --git a/interfaces/Crafter.Event.cppm b/interfaces/Crafter.Event.cppm index 35edc24..6bdce6a 100644 --- a/interfaces/Crafter.Event.cppm +++ b/interfaces/Crafter.Event.cppm @@ -102,6 +102,7 @@ namespace Crafter { std::replace(pos->second.begin(), pos->second.end(), listener, static_cast*>(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 with different Invoke signature @@ -155,28 +166,25 @@ namespace Crafter { using EventBase::EventBase; void Invoke() { -#ifdef CRAFTER_TIMING - // Clear previous timing data + #ifdef CRAFTER_TIMING this->listenerTimes.clear(); + #endif - this->listeners.erase(std::remove(this->listeners.begin(), this->listeners.end(), static_cast>(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*>(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(end - start); this->listenerTimes[listener] = duration; + #endif } } -#else - this->listeners.erase(std::remove(this->listeners.begin(), this->listeners.end(), static_cast>(nullptr)), this->listeners.end()); - for (const auto& listenerSlice : this->listeners) { - for (const auto& listener : listenerSlice.second) { - listener->function(); - } - } -#endif + removeEmptyListeners(); } }; @@ -187,28 +195,25 @@ namespace Crafter { using EventBase::EventBase; void Invoke(T data) { -#ifdef CRAFTER_TIMING - // Clear previous timing data + #ifdef CRAFTER_TIMING this->listenerTimes.clear(); + #endif - this->listeners.erase(std::remove(this->listeners.begin(), this->listeners.end(), static_cast>(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*>(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(end - start); this->listenerTimes[listener] = duration; + #endif } } -#else - this->listeners.erase(std::remove(this->listeners.begin(), this->listeners.end(), static_cast>(nullptr)), this->listeners.end()); - for (const auto& listenerSlice : this->listeners) { - for (const auto& listener : listenerSlice.second) { - listener->function(data); - } - } -#endif + EventBase::removeEmptyListeners(); } };