duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

timing_event.h (2603B)


      1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
      3 
      4 #pragma once
      5 
      6 #include "types.h"
      7 
      8 #include <string_view>
      9 
     10 class StateWrapper;
     11 
     12 // Event callback type. Second parameter is the number of cycles the event was executed "late".
     13 using TimingEventCallback = void (*)(void* param, TickCount ticks, TickCount ticks_late);
     14 
     15 class TimingEvent
     16 {
     17 public:
     18   TimingEvent(const std::string_view name, TickCount period, TickCount interval, TimingEventCallback callback,
     19               void* callback_param);
     20   ~TimingEvent();
     21 
     22   ALWAYS_INLINE const std::string_view GetName() const { return m_name; }
     23   ALWAYS_INLINE bool IsActive() const { return m_active; }
     24 
     25   // Returns the number of ticks between each event.
     26   ALWAYS_INLINE TickCount GetPeriod() const { return m_period; }
     27   ALWAYS_INLINE TickCount GetInterval() const { return m_interval; }
     28 
     29   // Includes pending time.
     30   TickCount GetTicksSinceLastExecution() const;
     31   TickCount GetTicksUntilNextExecution() const;
     32 
     33   // Adds ticks to current execution.
     34   void Delay(TickCount ticks);
     35 
     36   void Schedule(TickCount ticks);
     37   void SetIntervalAndSchedule(TickCount ticks);
     38   void SetPeriodAndSchedule(TickCount ticks);
     39 
     40   // Services the event with the current accmulated time. If force is set, when not enough time is pending to
     41   // simulate a single cycle, the callback will still be invoked, otherwise it won't be.
     42   void InvokeEarly(bool force = false);
     43 
     44   // Deactivates the event, preventing it from firing again.
     45   // Do not call within a callback, return Deactivate instead.
     46   void Activate();
     47   void Deactivate();
     48 
     49   ALWAYS_INLINE void SetState(bool active)
     50   {
     51     if (active)
     52       Activate();
     53     else
     54       Deactivate();
     55   }
     56 
     57   // Directly alters the interval of the event.
     58   void SetInterval(TickCount interval) { m_interval = interval; }
     59   void SetPeriod(TickCount period) { m_period = period; }
     60 
     61   TimingEvent* prev = nullptr;
     62   TimingEvent* next = nullptr;
     63 
     64   TimingEventCallback m_callback;
     65   void* m_callback_param;
     66 
     67   GlobalTicks m_next_run_time = 0;
     68   GlobalTicks m_last_run_time = 0;
     69 
     70   TickCount m_period;
     71   TickCount m_interval;
     72   bool m_active = false;
     73 
     74   std::string_view m_name;
     75 };
     76 
     77 namespace TimingEvents {
     78 
     79 GlobalTicks GetGlobalTickCounter();
     80 GlobalTicks GetEventRunTickCounter();
     81 
     82 void Initialize();
     83 void Reset();
     84 void Shutdown();
     85 
     86 bool DoState(StateWrapper& sw);
     87 
     88 bool IsRunningEvents();
     89 void CancelRunningEvent();
     90 void RunEvents();
     91 void CommitLeftoverTicks();
     92 
     93 void UpdateCPUDowncount();
     94 
     95 TimingEvent** GetHeadEventPtr();
     96 
     97 } // namespace TimingEvents