diff options
Diffstat (limited to 'src/video/video_driver.hpp')
-rw-r--r-- | src/video/video_driver.hpp | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/src/video/video_driver.hpp b/src/video/video_driver.hpp index 4964e01cb..db522a761 100644 --- a/src/video/video_driver.hpp +++ b/src/video/video_driver.hpp @@ -22,6 +22,7 @@ #include <mutex> #include <thread> #include <vector> +#include <functional> extern std::string _ini_videodriver; extern std::vector<Dimension> _resolutions; @@ -36,7 +37,7 @@ class VideoDriver : public Driver { const uint DEFAULT_WINDOW_HEIGHT = 480u; ///< Default window height. public: - VideoDriver() : fast_forward_key_pressed(false), fast_forward_via_key(false), is_game_threaded(true), change_blitter(nullptr) {} + VideoDriver() : fast_forward_key_pressed(false), fast_forward_via_key(false), is_game_threaded(true) {} /** * Mark a particular area dirty. @@ -178,12 +179,16 @@ public: } /** - * Queue a request to change the blitter. This is not executed immediately, - * but instead on the next draw-tick. + * Queue a function to be called on the main thread with game state + * lock held and video buffer locked. Queued functions will be + * executed on the next draw tick. + * @param func Function to call. */ - void ChangeBlitter(const char *new_blitter) + void QueueOnMainThread(std::function<void()> &&func) { - this->change_blitter = new_blitter; + std::lock_guard<std::mutex> lock(this->cmd_queue_mutex); + + this->cmd_queue.emplace_back(std::forward<std::function<void()>>(func)); } void GameLoopPause(); @@ -328,11 +333,29 @@ protected: static void GameThreadThunk(VideoDriver *drv); private: + std::mutex cmd_queue_mutex; + std::vector<std::function<void()>> cmd_queue; + + /** Execute all queued commands. */ + void DrainCommandQueue() + { + std::vector<std::function<void()>> cmds{}; + + { + /* Exchange queue with an empty one to limit the time we + * hold the mutex. This also ensures that queued functions can + * add new functions to the queue without everything blocking. */ + std::lock_guard<std::mutex> lock(this->cmd_queue_mutex); + cmds.swap(this->cmd_queue); + } + + for (auto &f : cmds) { + f(); + } + } + void GameLoop(); void GameThread(); - void RealChangeBlitter(const char *repl_blitter); - - const char *change_blitter; ///< Request to change the blitter. nullptr if no pending request. }; #endif /* VIDEO_VIDEO_DRIVER_HPP */ |