Duckstation/src/core/timing_event.h

75 lines
2 KiB
C++

#pragma once
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include "types.h"
class System;
class TimingEvent;
// Event callback type. Second parameter is the number of cycles the event was executed "late".
using TimingEventCallback = std::function<void(TickCount ticks, TickCount ticks_late)>;
class TimingEvent
{
friend System;
public:
TimingEvent(System* system, std::string name, TickCount period, TickCount interval, TimingEventCallback callback);
~TimingEvent();
System* GetSystem() const { return m_system; }
const std::string& GetName() const { return m_name; }
bool IsActive() const { return m_active; }
// Returns the number of ticks between each event.
TickCount GetPeriod() const { return m_period; }
TickCount GetInterval() const { return m_interval; }
TickCount GetDowncount() const { return m_downcount; }
// Includes pending time.
TickCount GetTicksSinceLastExecution() const;
TickCount GetTicksUntilNextExecution() const;
void Schedule(TickCount ticks);
void SetIntervalAndSchedule(TickCount ticks);
void SetPeriodAndSchedule(TickCount ticks);
void Reset();
// Services the event with the current accmulated time. If force is set, when not enough time is pending to
// simulate a single cycle, the callback will still be invoked, otherwise it won't be.
void InvokeEarly(bool force = false);
// Deactivates the event, preventing it from firing again.
// Do not call within a callback, return Deactivate instead.
void Activate();
void Deactivate();
ALWAYS_INLINE void SetState(bool active)
{
if (active)
Activate();
else
Deactivate();
}
// Directly alters the interval of the event.
void SetInterval(TickCount interval) { m_interval = interval; }
void SetPeriod(TickCount period) { m_period = period; }
private:
TickCount m_downcount;
TickCount m_time_since_last_run;
TickCount m_period;
TickCount m_interval;
TimingEventCallback m_callback;
System* m_system;
std::string m_name;
bool m_active;
};