2023-11-13 19:36:25 +01:00
|
|
|
#include "event.hpp"
|
2024-10-12 04:24:58 +02:00
|
|
|
|
2023-11-13 19:36:25 +01:00
|
|
|
#include "thread/Process.hpp"
|
2024-10-12 04:24:58 +02:00
|
|
|
#include <algorithm>
|
2023-11-13 19:36:25 +01:00
|
|
|
|
|
|
|
|
orbis::KNote::~KNote() {
|
2024-10-12 04:24:58 +02:00
|
|
|
while (!emitters.empty()) {
|
|
|
|
|
emitters.back()->unsubscribe(this);
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-13 19:36:25 +01:00
|
|
|
if (linked == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (event.filter == kEvFiltProc) {
|
|
|
|
|
auto proc = static_cast<Process *>(linked);
|
|
|
|
|
|
|
|
|
|
std::lock_guard lock(proc->event.mutex);
|
|
|
|
|
proc->event.notes.erase(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-13 21:02:23 +01:00
|
|
|
|
2024-10-12 04:24:58 +02:00
|
|
|
void orbis::EventEmitter::emit(sshort filter, uint fflags, intptr_t data) {
|
2023-11-13 21:02:23 +01:00
|
|
|
std::lock_guard lock(mutex);
|
|
|
|
|
|
|
|
|
|
for (auto note : notes) {
|
|
|
|
|
if (note->event.filter != filter) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2024-01-13 18:57:02 +01:00
|
|
|
if (fflags != 0) {
|
|
|
|
|
if ((note->event.fflags & fflags) == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
note->event.fflags = fflags;
|
2023-11-13 21:02:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-12 04:24:58 +02:00
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|