Codechange: Generalise the delayed blitter change to a generic video driver command queue.

This commit is contained in:
Michael Lutz
2021-05-01 19:39:03 +02:00
parent 2cf5df2a50
commit 91b8ce073f
3 changed files with 55 additions and 34 deletions

View File

@@ -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 */