#pragma once #include #include #include #include #include #include #include #include #include #include namespace extra2d { using TimerHdl = uint32; constexpr TimerHdl INVALID_HDL = 0; /** * @brief 定时器目标接口 * * 实现此接口的对象可以接收 update 回调 */ class TimerTarget { public: virtual ~TimerTarget() = default; virtual void update(float dt) = 0; }; /** * @brief 定时器基类 */ class Timer : public RefCounted { public: virtual ~Timer() = default; virtual void update(float dt) = 0; virtual void trigger() = 0; bool isPaused() const { return paused_; } bool isDone() const { return done_; } TimerHdl hdl() const { return hdl_; } void pause() { paused_ = true; } void resume() { paused_ = false; } void cancel() { done_ = true; } protected: Timer() = default; float elapsed_ = -1.0f; float interval_ = 0.0f; float delay_ = 0.0f; uint32 repeat_ = 0; uint32 timesExecuted_ = 0; bool useDelay_ = false; bool runForever_ = false; bool paused_ = false; bool done_ = false; TimerHdl hdl_ = INVALID_HDL; friend class Scheduler; }; /** * @brief 调度器 * * 基于 TBB 实现的线程安全调度器,支持定时器和 update 回调 */ class Scheduler { public: using Cb = Fn; using VoidCb = Fn; static Scheduler& inst(); TimerHdl scheduleUpdate(TimerTarget* target, int pri = 0); void unscheduleUpdate(TimerTarget* target); TimerHdl schedule(Cb cb, float interval, uint32 repeat = 0, float delay = 0.0f); TimerHdl scheduleOnce(VoidCb cb, float delay); TimerHdl scheduleForever(Cb cb, float interval); void unschedule(TimerHdl hdl); void unscheduleAll(); void pause(TimerHdl hdl); void resume(TimerHdl hdl); void setTimeScale(float scale) { timeScale_ = scale; } float timeScale() const { return timeScale_; } void update(float dt); void updateParallel(float dt); bool isScheduled(TimerHdl hdl) const; size_t count() const; private: Scheduler() = default; struct UpdateEntry { TimerTarget* target; int pri; bool paused; bool markedForDel; bool operator<(const UpdateEntry& o) const { return pri > o.pri; } }; std::vector updates_; tbb::concurrent_hash_map updateIndex_; tbb::concurrent_hash_map> timers_; tbb::concurrent_priority_queue updateQueue_; std::atomic nextHdl_{1}; std::atomic timeScale_{1.0f}; std::atomic locked_{false}; TimerHdl genHdl(); }; #define SCHED extra2d::Scheduler::inst() } // namespace extra2d