diff --git a/include/td/simulation/ServerSimulation.h b/include/td/simulation/ServerSimulation.h index 2114fd1..aaadbad 100644 --- a/include/td/simulation/ServerSimulation.h +++ b/include/td/simulation/ServerSimulation.h @@ -1,21 +1,34 @@ #pragma once +#include #include namespace td { namespace sim { // TODO: OnEnd signal -class ServerSimulation { +/** + * \note This class is thread safe + */ +class ServerSimulation : public protocol::CommandHandler { private: + std::mutex m_Mutex; game::World& m_World; std::uint64_t m_StepTime; std::uint64_t m_CurrentTime; + std::vector m_History; + + using protocol::CommandHandler::Handle; public: ServerSimulation(game::World& a_World, std::uint64_t a_StepTime); - void Update(); + protocol::packets::LockStepsPacket Update(); + + // no checks are done ! + + virtual void Handle(const protocol::commands::SpawnTroopCommand& a_SpawnTroop) override; + virtual void Handle(const protocol::commands::PlaceTowerCommand& a_PlaceTower) override; }; } // namespace sim diff --git a/src/td/simulation/ServerSimulation.cpp b/src/td/simulation/ServerSimulation.cpp new file mode 100644 index 0000000..497d866 --- /dev/null +++ b/src/td/simulation/ServerSimulation.cpp @@ -0,0 +1,36 @@ +#include + +namespace td { +namespace sim { + +ServerSimulation::ServerSimulation(game::World& a_World, std::uint64_t a_StepTime) : + m_World(a_World), m_StepTime(a_StepTime), m_CurrentTime(0) {} + +protocol::packets::LockStepsPacket ServerSimulation::Update() { + std::lock_guard lock(m_Mutex); + + m_World.Tick(m_History[m_CurrentTime], FpFloat(m_StepTime) / FpFloat(1000)); + m_CurrentTime++; + + std::array nextSteps; + std::copy(m_History.begin() + m_CurrentTime, m_History.begin() + m_CurrentTime + nextSteps.size(), nextSteps.begin()); + return {m_CurrentTime, std::move(nextSteps)}; +} + +template +void AddToCommandHistory(protocol::LockStep& a_LockStep, const T& a_Cmd) { + a_LockStep.push_back({std::make_shared(a_Cmd)}); +} + +void ServerSimulation::Handle(const protocol::commands::SpawnTroopCommand& a_SpawnTroop) { + std::lock_guard lock(m_Mutex); + AddToCommandHistory(m_History[m_CurrentTime + LOCKSTEP_BUFFER_SIZE], a_SpawnTroop); +} + +void ServerSimulation::Handle(const protocol::commands::PlaceTowerCommand& a_PlaceTower) { + std::lock_guard lock(m_Mutex); + AddToCommandHistory(m_History[m_CurrentTime + LOCKSTEP_BUFFER_SIZE], a_PlaceTower); +} + +} // namespace sim +} // namespace td