rpcsx/orbis-kernel/include/orbis/note.hpp
2024-11-24 20:50:28 +03:00

113 lines
3.3 KiB
C++

#pragma once
#include "KernelAllocator.hpp"
#include "orbis-config.hpp"
#include "orbis/utils/Rc.hpp"
#include "utils/SharedMutex.hpp"
#include <limits>
#include <set>
namespace orbis {
struct File;
static constexpr auto kEvFiltRead = -1;
static constexpr auto kEvFiltWrite = -2;
static constexpr auto kEvFiltAio = -3;
static constexpr auto kEvFiltVnode = -4;
static constexpr auto kEvFiltProc = -5;
static constexpr auto kEvFiltSignal = -6;
static constexpr auto kEvFiltTimer = -7;
static constexpr auto kEvFiltFs = -9;
static constexpr auto kEvFiltLio = -10;
static constexpr auto kEvFiltUser = -11;
static constexpr auto kEvFiltPolling = -12;
static constexpr auto kEvFiltDisplay = -13;
static constexpr auto kEvFiltGraphicsCore = -14;
static constexpr auto kEvFiltHrTimer = -15;
static constexpr auto kEvFiltUvdTrap = -16;
static constexpr auto kEvFiltVceTrap = -17;
static constexpr auto kEvFiltSdmaTrap = -18;
static constexpr auto kEvFiltRegEv = -19;
static constexpr auto kEvFiltGpuException = -20;
static constexpr auto kEvFiltGpuSystemException = -21;
static constexpr auto kEvFiltGpuDbgGcEv = -22;
static constexpr auto kEvFiltSysCount = 22;
// actions
static constexpr auto kEvAdd = 0x0001;
static constexpr auto kEvDelete = 0x0002;
static constexpr auto kEvEnable = 0x0004;
static constexpr auto kEvDisable = 0x0008;
// flags
static constexpr auto kEvOneshot = 0x0010;
static constexpr auto kEvClear = 0x0020;
static constexpr auto kEvReceipt = 0x0040;
static constexpr auto kEvDispatch = 0x0080;
static constexpr auto kEvSysFlags = 0xf000;
static constexpr auto kEvFlag1 = 0x2000;
static constexpr auto kEvEof = 0x8000;
static constexpr auto kEvError = 0x4000;
// kEvFiltUser
static constexpr auto kNoteFFNop = 0x00000000;
static constexpr auto kNoteFFAnd = 0x40000000;
static constexpr auto kNoteFFOr = 0x80000000;
static constexpr auto kNoteFFCopy = 0xc0000000;
static constexpr auto kNoteFFCtrlMask = 0xc0000000;
static constexpr auto kNoteFFlagsMask = 0x00ffffff;
static constexpr auto kNoteTrigger = 0x01000000;
// kEvFiltProc
static constexpr auto kNoteExit = 0x80000000;
static constexpr auto kNoteFork = 0x40000000;
static constexpr auto kNoteExec = 0x20000000;
struct KEvent {
uintptr_t ident;
sshort filter;
ushort flags;
uint fflags;
intptr_t data;
ptr<void> udata;
};
struct EventEmitter;
struct KQueue;
struct KNote {
shared_mutex mutex;
KQueue *queue;
Ref<File> file;
KEvent event{};
bool enabled = true;
bool triggered = false;
void *linked = nullptr; // TODO: use Ref<>
kvector<Ref<EventEmitter>> emitters;
~KNote();
};
struct EventEmitter : orbis::RcBase {
shared_mutex mutex;
std::set<KNote *, std::less<>, kallocator<KNote *>> notes;
void emit(sshort filter, uint fflags = 0, intptr_t data = 0,
uintptr_t ident = std::numeric_limits<uintptr_t>::max());
void emit(sshort filter, void *userData,
std::optional<intptr_t> (*filterFn)(void *userData, KNote *note));
template <typename T>
void emit(sshort filter, T &&fn)
requires requires(KNote *note) {
{ fn(note) } -> std::same_as<std::optional<intptr_t>>;
}
{
emit(filter, &fn, [](void *userData, KNote *note) {
return (*static_cast<std::remove_cvref_t<T> *>(userData))(note);
});
}
void subscribe(KNote *note);
void unsubscribe(KNote *note);
};
} // namespace orbis