From a27a5794a4696297a06b5a735bd3f8e37d57bd41 Mon Sep 17 00:00:00 2001 From: Robert Chisholm Date: Sun, 26 Mar 2023 13:39:38 +0100 Subject: [PATCH] Pressing 'o' whilst sim is paused, allows the simulation to be stepped. This does nothing if the simulation isn't ready, e.g. if it hasn't completed a new step since the sim last paused. Closes #124 --- src/flamegpu/visualiser/FLAMEGPU_Visualisation.cpp | 2 ++ src/flamegpu/visualiser/Visualiser.cpp | 10 ++++++++++ src/flamegpu/visualiser/Visualiser.h | 14 +++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/flamegpu/visualiser/FLAMEGPU_Visualisation.cpp b/src/flamegpu/visualiser/FLAMEGPU_Visualisation.cpp index 3009552..a0d37f3 100644 --- a/src/flamegpu/visualiser/FLAMEGPU_Visualisation.cpp +++ b/src/flamegpu/visualiser/FLAMEGPU_Visualisation.cpp @@ -68,7 +68,9 @@ bool FLAMEGPU_Visualisation::isReady() const { void FLAMEGPU_Visualisation::lockMutex() { + auto lock_t = new std::lock_guard(vis->getRenderBufferMutexPre()); lock = new LockHolder(vis->getRenderBufferMutex()); + delete lock_t; } void FLAMEGPU_Visualisation::releaseMutex() { if (lock) { diff --git a/src/flamegpu/visualiser/Visualiser.cpp b/src/flamegpu/visualiser/Visualiser.cpp index de472e3..69e457b 100644 --- a/src/flamegpu/visualiser/Visualiser.cpp +++ b/src/flamegpu/visualiser/Visualiser.cpp @@ -902,6 +902,16 @@ void Visualiser::handleKeypress(SDL_Keycode keycode, int /*x*/, int /*y*/) { stepsPerSecond = 0.0; } break; + case SDLK_o: + // If paused step the simulation, else do nothing + if (this->pause_guard) { + delete pause_guard; + pause_guard = nullptr; + const auto pause_guard_t = new std::lock_guard(render_buffer_mutex_pre); + pause_guard = new std::lock_guard(render_buffer_mutex); + delete pause_guard_t; + } + break; case SDLK_l: renderLines = !renderLines; break; diff --git a/src/flamegpu/visualiser/Visualiser.h b/src/flamegpu/visualiser/Visualiser.h index 5b4602e..0fc40d2 100644 --- a/src/flamegpu/visualiser/Visualiser.h +++ b/src/flamegpu/visualiser/Visualiser.h @@ -241,7 +241,13 @@ class Visualiser : public ViewportExt { * This must be locked before calling updateAgentStateBuffer() * @see updateAgentStateBuffer(const std::string &, const std::string &, const unsigned int, float *, float *, float *, float *) */ - std::mutex &getRenderBufferMutex() { return render_buffer_mutex; } + std::mutex& getRenderBufferMutex() { return render_buffer_mutex; } + /** + * Returns the mutex for simulation stepping (for the simulation) + * This must be locked before locking render_buffer_mutex, then released straight after the lock is achieved + * @see updateAgentStateBuffer(const std::string &, const std::string &, const unsigned int, float *, float *, float *, float *) + */ + std::mutex& getRenderBufferMutexPre() { return render_buffer_mutex_pre; } /** * Sets the value to be rendered to the HUD step counter (if enabled) * @param stepCount The step value to be displayed @@ -381,6 +387,12 @@ class Visualiser : public ViewportExt { * Mutex is required to access render buffers for thread safety */ std::mutex render_buffer_mutex; + /** + * Double mutex to enable simulation stepping + * Visualiser must lock this prior to locking render_buffer_mutex, then release this after the render_buffer_mutex lock is achieved + * This allows sim stepping to block a re-lock of render_buffer_mutex + */ + std::mutex render_buffer_mutex_pre; /** * When this is not set to nullptr, it blocks the simulation from continuing */