#pragma once #include #include #include #include namespace n64 { struct Mem; struct Registers; } enum EventType { NONE, PI_BUS_WRITE_COMPLETE, PI_DMA_COMPLETE, SI_DMA, IMPOSSIBLE }; struct Event { u64 time; EventType type; friend bool operator<(const Event& rhs, const Event& lhs) { return rhs.time < lhs.time; } friend bool operator>(const Event& rhs, const Event& lhs) { return rhs.time > lhs.time; } friend bool operator>=(const Event& rhs, const Event& lhs) { return rhs.time >= lhs.time; } }; struct IterableEvents { std::priority_queue, std::greater<>> events; public: explicit IterableEvents() = default; [[nodiscard]] auto top() const { return events.top(); } auto pop() { events.pop(); } [[nodiscard]] auto begin() const { return (Event*)(&events.top()); } [[nodiscard]] auto end() const { return begin() + events.size(); } auto push(Event e) { events.push(e); } }; struct Scheduler { Scheduler() { EnqueueAbsolute(std::numeric_limits::max(), IMPOSSIBLE); } void EnqueueRelative(u64, EventType); void EnqueueAbsolute(u64, EventType); u64 Remove(EventType); void Tick(u64 t, n64::Mem&); IterableEvents events; u64 ticks = 0; u8 index = 0; }; extern Scheduler scheduler;