From 5e8a110f45f7d91e1fa6fdf88e2980695064ddb5 Mon Sep 17 00:00:00 2001 From: Christoph Urlacher Date: Tue, 24 Feb 2026 02:05:44 +0100 Subject: [PATCH] wip: don't lock command mutex for each mass/spring in FillGraph() --- include/config.hpp | 2 +- include/physics.hpp | 4 ++++ src/main.cpp | 4 ++-- src/physics.cpp | 16 ++++++++++++++++ src/state.cpp | 18 +++++++++++++----- 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index 7440163..88029bf 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -30,7 +30,7 @@ constexpr float ROT_SPEED = 1.0; constexpr float CAMERA_SMOOTH_SPEED = 15.0; // Physics Engine -constexpr float SIM_SPEED = 4.0; // How large each update should be +constexpr float SIM_SPEED = 0.2; // How large each update should be constexpr float TIMESTEP = 1.0 / 90; // Do 90 physics updates per second constexpr float MASS = 1.0; // Mass spring system constexpr float SPRING_CONSTANT = 5.0; // Mass spring system diff --git a/include/physics.hpp b/include/physics.hpp index 92f96be..6e8349e 100644 --- a/include/physics.hpp +++ b/include/physics.hpp @@ -188,6 +188,10 @@ public: auto AddSpringCmd(const State &a, const State &b) -> void; auto ClearCmd() -> void; + + auto NonLockingAddMassCmd(const State &_state) -> void; + + auto NonLockingAddSpringCmd(const State &a, const State &b) -> void; }; // https://en.cppreference.com/w/cpp/utility/variant/visit diff --git a/src/main.cpp b/src/main.cpp index 405238e..fc8c98b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,7 +39,7 @@ auto main(int argc, char *argv[]) -> int { OrbitCamera3D camera; Renderer renderer(camera); ThreadedPhysics physics; - StateManager state(physics); + StateManager state(physics); // TODO: What is this warning? InputHandler input(state, renderer); std::vector masses; // Read from physics @@ -74,7 +74,7 @@ auto main(int argc, char *argv[]) -> int { */ // Read positions from physics thread - // TODO: We're reading a HUGE amount of SHIT, because the state + // TODO: We're copying a HUGE amount of SHIT, because the state // representations (std::string, ~100 Bytes) are copied ~3 times per // spring: state_masses and state_springs<, // int> diff --git a/src/physics.cpp b/src/physics.cpp index 850cc7f..9f0e486 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -366,11 +366,18 @@ auto ThreadedPhysics::PhysicsThread(ThreadedPhysics::PhysicsState &state) } // Physics update + // TODO: I need this thread to run at a constant rate mass_springs.ClearForces(); mass_springs.CalculateSpringForces(); mass_springs.CalculateRepulsionForces(); mass_springs.VerletUpdate(TIMESTEP * SIM_SPEED); + // TODO: Notify the main thread of update + // TODO: Just wait here until the main thread has fetched the data? + // Then only the copying would be sequential, while the main thread + // renders this thread can already calculate the physics... + // TODO: Would std::swap help in any way? + // Publish the positions for the renderer (copy) { std::lock_guard lock(state.pos_mtx); @@ -402,3 +409,12 @@ auto ThreadedPhysics::ClearCmd() -> void { state.pending_commands.push(ClearGraph{}); } } + +auto ThreadedPhysics::NonLockingAddMassCmd(const State &_state) -> void { + state.pending_commands.push(AddMass{_state}); +} + +auto ThreadedPhysics::NonLockingAddSpringCmd(const State &a, const State &b) + -> void { + state.pending_commands.push(AddSpring{a, b}); +} diff --git a/src/state.cpp b/src/state.cpp index a49b663..2a8933c 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -37,12 +37,20 @@ auto StateManager::FillGraph() -> void { std::pair, std::vector>> closure = current_state.Closure(); - for (const auto &state : closure.first) { - physics.AddMassCmd(state); - } - for (const auto &[from, to] : closure.second) { - physics.AddSpringCmd(from, to); + + { + std::lock_guard lock(physics.state.command_mtx); + for (const auto &state : closure.first) { + physics.NonLockingAddMassCmd(state); + } + for (const auto &[from, to] : closure.second) { + physics.NonLockingAddSpringCmd(from, to); + } } + + // TODO: We have only dispatched the commands, the states won't be downloaded + // when calling this... Make FindWinningStates() another command? + // Or recalculate whenever masses.size() changes? FindWinningStates(); }