#include "event.hpp" #include "thread/Process.hpp" #include orbis::KNote::~KNote() { while (!emitters.empty()) { emitters.back()->unsubscribe(this); } if (linked == nullptr) { return; } if (event.filter == kEvFiltProc) { auto proc = static_cast(linked); std::lock_guard lock(proc->event.mutex); proc->event.notes.erase(this); } } void orbis::EventEmitter::emit(sshort filter, uint fflags, intptr_t data) { std::lock_guard lock(mutex); for (auto note : notes) { if (note->event.filter != filter) { continue; } if (fflags != 0) { if ((note->event.fflags & fflags) == 0) { continue; } note->event.fflags = fflags; } std::lock_guard lock(note->mutex); if (note->triggered) { continue; } note->triggered = true; note->event.data = data; note->queue->cv.notify_all(note->queue->mtx); } } void orbis::EventEmitter::subscribe(KNote *note) { std::lock_guard lock(mutex); notes.insert(note); note->emitters.emplace_back(this); } void orbis::EventEmitter::unsubscribe(KNote *note) { std::lock_guard lock(mutex); notes.erase(note); auto it = std::ranges::find(note->emitters, this); if (it == note->emitters.end()) { return; } std::size_t index = it - note->emitters.begin(); auto lastEmitter = note->emitters.size() - 1; if (index != lastEmitter) { std::swap(note->emitters[index], note->emitters[lastEmitter]); } note->emitters.pop_back(); }