#include "STDInclude.hpp" namespace Components { bool Scheduler::ReadyPassed = false; Utils::Signal Scheduler::ReadySignal; Utils::Signal Scheduler::ShutdownSignal; Utils::Signal Scheduler::FrameSignal; Utils::Signal Scheduler::FrameOnceSignal; std::vector Scheduler::DelayedSlots; void Scheduler::Once(Utils::Slot callback) { Scheduler::FrameOnceSignal.connect(callback); } void Scheduler::OnShutdown(Utils::Slot callback) { Scheduler::ShutdownSignal.connect(callback); } void Scheduler::OnFrame(Utils::Slot callback) { Scheduler::FrameSignal.connect(callback); } void Scheduler::OnReady(Utils::Slot callback) { if (Scheduler::ReadyPassed) Scheduler::Once(callback); else Scheduler::ReadySignal.connect(callback); } void Scheduler::ReadyHandler() { if (!FastFiles::Ready()) { Scheduler::Once(Scheduler::ReadyHandler); } else { Scheduler::ReadyPassed = true; Scheduler::ReadySignal(); Scheduler::ReadySignal.clear(); } } void Scheduler::FrameHandler() { Scheduler::ReadyHandler(); Scheduler::DelaySignal(); Scheduler::FrameSignal(); Utils::Signal copy(Scheduler::FrameOnceSignal); Scheduler::FrameOnceSignal.clear(); copy(); } void Scheduler::OnDelay(Utils::Slot callback, std::chrono::nanoseconds delay) { Scheduler::DelayedSlot slot; slot.callback = callback; slot.delay = delay; Scheduler::DelayedSlots.push_back(slot); } void Scheduler::DelaySignal() { Utils::Signal signal; for (auto i = Scheduler::DelayedSlots.begin(); i != Scheduler::DelayedSlots.end();) { if (i->interval.elapsed(i->delay)) { signal.connect(i->callback); i = Scheduler::DelayedSlots.erase(i); continue; } ++i; } signal(); } void Scheduler::ShutdownStub(int num) { Scheduler::ShutdownSignal(); Utils::Hook::Call(0x46B370)(num); } Scheduler::Scheduler() { Scheduler::ReadyPassed = false; Scheduler::Once(Scheduler::ReadyHandler); Utils::Hook(0x4D697A, Scheduler::ShutdownStub, HOOK_CALL).install()->quick(); } Scheduler::~Scheduler() { Scheduler::ReadySignal.clear(); Scheduler::ShutdownSignal.clear(); Scheduler::FrameSignal.clear(); Scheduler::FrameOnceSignal.clear(); Scheduler::DelayedSlots.clear(); Scheduler::ReadyPassed = false; } }