#pragma once class CPUThread; class PPUThread; typedef void(PauseResumeCB)(bool is_paused); class CallbackManager { std::mutex m_mutex; std::vector> m_cb_list; std::vector> m_async_list; CPUThread* m_cb_thread; struct PauseResumeCBS { std::function cb; u64 tag; }; u64 next_tag; // not initialized, only increased std::vector m_pause_cb_list; public: void Register(const std::function& func); // register callback (called in Check() method) void Async(const std::function& func); // register callback for callback thread (called immediately) bool Check(CPUThread& CPU, s32& result); // call one callback registered by Register() method void Init(); void Clear(); u64 AddPauseCallback(const std::function& func); // register callback for pausing/resuming emulation events void RemovePauseCallback(const u64 tag); // unregister callback (uses the result of AddPauseCallback() function) void RunPauseCallbacks(const bool is_paused); }; class PauseCallbackRegisterer { CallbackManager& cb_manager; u64 cb_tag; public: PauseCallbackRegisterer(CallbackManager& cb_manager, const std::function& func) : cb_manager(cb_manager) , cb_tag(cb_manager.AddPauseCallback(func)) { } PauseCallbackRegisterer() = delete; PauseCallbackRegisterer(const PauseCallbackRegisterer& right) = delete; PauseCallbackRegisterer(PauseCallbackRegisterer&& right) = delete; ~PauseCallbackRegisterer() { cb_manager.RemovePauseCallback(cb_tag); } PauseCallbackRegisterer& operator =(const PauseCallbackRegisterer& right) = delete; PauseCallbackRegisterer& operator =(PauseCallbackRegisterer&& right) = delete; };