Files
klubhaus-doorbell/libraries/FastLED/src/fl/engine_events.cpp
2026-02-12 00:45:31 -08:00

132 lines
3.9 KiB
C++

#include "fl/engine_events.h"
#include "fl/namespace.h"
#include "fl/int.h"
namespace fl {
EngineEvents::Listener::Listener() {}
EngineEvents::Listener::~Listener() {
#if FASTLED_HAS_ENGINE_EVENTS
EngineEvents *ptr = EngineEvents::getInstance();
const bool has_listener = ptr && ptr->_hasListener(this);
if (has_listener) {
// Warning, the listener should be removed by the subclass. If we are
// here then the subclass did not remove the listener and we are now in
// a partial state of destruction and the results may be undefined for
// multithreaded applications. However, for single threaded (the only
// option as of 2024, October) this will be ok.
ptr->_removeListener(this);
}
#endif
}
#if FASTLED_HAS_ENGINE_EVENTS
EngineEvents *EngineEvents::getInstance() {
return &Singleton<EngineEvents>::instance();
}
#endif
#if FASTLED_HAS_ENGINE_EVENTS
void EngineEvents::_onPlatformPreLoop() {
for (auto &item : mListeners) {
auto listener = item.listener;
listener->onPlatformPreLoop();
}
for (auto &item : mListeners) {
auto listener = item.listener;
listener->onPlatformPreLoop2();
}
}
bool EngineEvents::_hasListener(Listener *listener) {
auto predicate = [listener](const Pair &pair) {
return pair.listener == listener;
};
return mListeners.find_if(predicate) != mListeners.end();
}
void EngineEvents::_addListener(Listener *listener, int priority) {
if (_hasListener(listener)) {
return;
}
for (auto it = mListeners.begin(); it != mListeners.end(); ++it) {
if (it->priority < priority) {
// this is now the highest priority in this spot.
EngineEvents::Pair pair = EngineEvents::Pair(listener, priority);
mListeners.insert(it, pair);
return;
}
}
EngineEvents::Pair pair = EngineEvents::Pair(listener, priority);
mListeners.push_back(pair);
}
void EngineEvents::_removeListener(Listener *listener) {
auto predicate = [listener](const Pair &pair) {
return pair.listener == listener;
};
auto it = mListeners.find_if(predicate);
if (it != mListeners.end()) {
mListeners.erase(it);
}
}
void EngineEvents::_onBeginFrame() {
// Make the copy of the listener list to avoid issues with listeners being
// added or removed during the loop.
ListenerList copy = mListeners;
for (auto &item : copy) {
auto listener = item.listener;
listener->onBeginFrame();
}
}
void EngineEvents::_onEndShowLeds() {
// Make the copy of the listener list to avoid issues with listeners being
// added or removed during the loop.
ListenerList copy = mListeners;
for (auto &item : copy) {
auto listener = item.listener;
listener->onEndShowLeds();
}
}
void EngineEvents::_onEndFrame() {
// Make the copy of the listener list to avoid issues with listeners being
// added or removed during the loop.
ListenerList copy = mListeners;
for (auto &item : copy) {
auto listener = item.listener;
listener->onEndFrame();
}
}
void EngineEvents::_onStripAdded(CLEDController *strip, fl::u32 num_leds) {
// Make the copy of the listener list to avoid issues with listeners being
// added or removed during the loop.
ListenerList copy = mListeners;
for (auto &item : copy) {
auto listener = item.listener;
listener->onStripAdded(strip, num_leds);
}
}
void EngineEvents::_onCanvasUiSet(CLEDController *strip,
const ScreenMap &screenmap) {
// Make the copy of the listener list to avoid issues with listeners being
// added or removed during the loop.
ListenerList copy = mListeners;
for (auto &item : copy) {
auto listener = item.listener;
listener->onCanvasUiSet(strip, screenmap);
}
}
#endif // FASTLED_HAS_ENGINE_EVENTS
} // namespace fl