diff --git a/include/client/state/GameState.h b/include/client/state/GameState.h index b4fcacd..80e777d 100644 --- a/include/client/state/GameState.h +++ b/include/client/state/GameState.h @@ -2,7 +2,7 @@ #include #include -#include +#include namespace td { namespace client { @@ -10,14 +10,19 @@ namespace client { class GameState : public ClientState { private: std::shared_ptr m_World; - // sim::ClientSimulation m_Simulation; + sim::ClientSimulation m_Simulation; + float m_CurrentLerp; public: - GameState(Client& a_Client, const std::shared_ptr& a_World); + GameState(Client& a_Client, const std::shared_ptr& a_World, std::uint64_t a_StepTime); ~GameState() {} virtual void Update(float a_Delta) override; + float GetCurrentLerp() const { + return m_CurrentLerp; + } + protected: virtual void HandlePacket(const protocol::PacketBase& a_Packet) override; }; diff --git a/include/td/common/StateMachine.h b/include/td/common/StateMachine.h index f4adc8e..6f4f7de 100644 --- a/include/td/common/StateMachine.h +++ b/include/td/common/StateMachine.h @@ -29,8 +29,9 @@ class StateMachine { } template - void ChangeState(Args&&... args) { + T* ChangeState(Args&&... args) { m_State = std::make_unique(static_cast(*this), std::forward(args)...); + return static_cast(m_State.get()); } private: diff --git a/include/td/display/state/DebugWorldState.h b/include/td/display/state/DebugWorldState.h index e9a1a64..f5e22cc 100644 --- a/include/td/display/state/DebugWorldState.h +++ b/include/td/display/state/DebugWorldState.h @@ -5,19 +5,17 @@ #include #include #include +#include namespace td { -class ClientHandler; - class DebugWorldState : public DisplayState { private: render::RenderPipeline m_Renderer; + render::Camera m_Camera; std::unique_ptr m_Client; std::unique_ptr m_Server; - std::unique_ptr m_Simulation; - render::Camera m_Camera; - std::unique_ptr m_ClientHandler; + client::GameState* m_ClientState; public: DebugWorldState(Display& a_Display); diff --git a/include/td/simulation/ClientSimulation.h b/include/td/simulation/ClientSimulation.h index ca6388f..7a24f29 100644 --- a/include/td/simulation/ClientSimulation.h +++ b/include/td/simulation/ClientSimulation.h @@ -14,7 +14,7 @@ using GameBuffer = std::vector>; class ClientSimulation : public protocol::PacketHandler { private: std::uint64_t m_StepTime; - game::World& m_World; + std::shared_ptr m_World; GameBuffer m_History; float m_CurrentTime; StepTime m_CurrentStep; @@ -33,13 +33,13 @@ class ClientSimulation : public protocol::PacketHandler { * \brief Replay constructor * \param a_StepTime in ms */ - ClientSimulation(game::World& a_World, GameHistory&& a_History, std::uint64_t a_StepTime); + ClientSimulation(std::shared_ptr a_World, GameHistory&& a_History, std::uint64_t a_StepTime); /** * \brief Live update constructor (continuous game updates) * \param a_StepTime in ms */ - ClientSimulation(game::World& a_World, std::uint64_t a_StepTime); + ClientSimulation(std::shared_ptr a_World, std::uint64_t a_StepTime); /** * \return the progress [0-1] between two steps diff --git a/src/client/state/GameState.cpp b/src/client/state/GameState.cpp index bb72ce5..c0d9eea 100644 --- a/src/client/state/GameState.cpp +++ b/src/client/state/GameState.cpp @@ -3,9 +3,39 @@ namespace td { namespace client { -GameState::GameState(Client& a_Client, const std::shared_ptr& a_World) : ClientState(a_Client), m_World(a_World) {} -void GameState::HandlePacket(const protocol::PacketBase& a_Packet) {} -void GameState::Update(float a_Delta) {} +class ClientHandler : public protocol::PacketHandler { + private: + sim::ClientSimulation& m_Simulation; + + using protocol::PacketHandler::Handle; + + public: + ClientHandler(sim::ClientSimulation& a_Simulation) : m_Simulation(a_Simulation) {} + + void Handle(const protocol::packets::LockStepsPacket& a_LockStep) { + m_Simulation.Handle(a_LockStep); + } + + void Handle(const protocol::packets::LockStepResponsePacket& a_LockStep) { + m_Simulation.Handle(a_LockStep); + } +}; + +GameState::GameState(Client& a_Client, const std::shared_ptr& a_World, std::uint64_t a_StepTime) : + ClientState(a_Client), m_World(a_World), m_Simulation(a_World, a_StepTime) { + m_Simulation.OnMissingLockSteps.Connect([this](const std::vector& a_MissingSteps) { + SendPacket(protocol::packets::LockStepRequestPacket(a_MissingSteps)); + }); +} + +void GameState::HandlePacket(const protocol::PacketBase& a_Packet) { + ClientHandler handler(m_Simulation); + a_Packet.Dispatch(handler); +} + +void GameState::Update(float a_Delta) { + m_CurrentLerp = m_Simulation.Update(a_Delta); +} } // namespace client } // namespace td diff --git a/src/server/state/GameState.cpp b/src/server/state/GameState.cpp index ee6c747..fdc6640 100644 --- a/src/server/state/GameState.cpp +++ b/src/server/state/GameState.cpp @@ -17,6 +17,7 @@ void GameState::HandlePacket(PlayerID a_Id, const protocol::PacketBase& a_Packet } void GameState::Update(float a_Delta) { + // TODO: don't make STEP_TIME constant static const float stepTimeSecond = static_cast(STEP_TIME) / 1000.0f; m_Time += a_Delta; if (m_Time > stepTimeSecond) { diff --git a/src/td/display/state/DebugWorldState.cpp b/src/td/display/state/DebugWorldState.cpp index 559a7ab..e21e467 100644 --- a/src/td/display/state/DebugWorldState.cpp +++ b/src/td/display/state/DebugWorldState.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -30,24 +29,6 @@ namespace td { -class ClientHandler : public protocol::PacketHandler { - private: - sim::ClientSimulation& m_Simulation; - - using protocol::PacketHandler::Handle; - - public: - ClientHandler(sim::ClientSimulation& a_Simulation) : m_Simulation(a_Simulation) {} - - void Handle(const protocol::packets::LockStepsPacket& a_LockStep) { - m_Simulation.Handle(a_LockStep); - } - - void Handle(const protocol::packets::LockStepResponsePacket& a_LockStep) { - m_Simulation.Handle(a_LockStep); - } -}; - class WorldApply : public protocol::PacketHandler { private: game::World& m_World; @@ -122,26 +103,15 @@ DebugWorldState::DebugWorldState(Display& a_Display) : DisplayState(a_Display) { m_Camera.SetCamPos({77, 7, 13}); m_Camera.UpdatePerspective(m_StateMachine.GetAspectRatio()); - m_Simulation = std::make_unique(*clientWorld, STEP_TIME); - - m_ClientHandler = std::make_unique(*m_Simulation); - - // packets from the server to the client - clientFakeSocket->OnReceive.Connect([this](const protocol::PacketBase& a_Packet) { a_Packet.Dispatch(*m_ClientHandler); }); - - m_Simulation->OnMissingLockSteps.Connect([clientFakeSocket](const std::vector& a_MissingSteps) { - clientFakeSocket->Send(protocol::packets::LockStepRequestPacket(a_MissingSteps)); - }); - + m_ClientState = m_Client->ChangeState(clientWorld, STEP_TIME); m_Server->ChangeState(serverWorld); - m_Client->ChangeState(clientWorld); } void DebugWorldState::Update(float a_Delta) { m_Server->Update(a_Delta); m_Client->Update(a_Delta); - float lerp = m_Simulation->Update(a_Delta); - m_Renderer.Render(lerp); + // TODO: m_ClientState might be invalid ! + m_Renderer.Render(m_ClientState->GetCurrentLerp()); } void DebugWorldState::OnAspectRatioChange(float a_Ratio) { diff --git a/src/td/simulation/ClientSimulation.cpp b/src/td/simulation/ClientSimulation.cpp index a45d336..c90c999 100644 --- a/src/td/simulation/ClientSimulation.cpp +++ b/src/td/simulation/ClientSimulation.cpp @@ -16,7 +16,7 @@ std::uint64_t GetTime() { std::chrono::duration_cast(std::chrono::system_clock().now().time_since_epoch()).count()); } -ClientSimulation::ClientSimulation(game::World& a_World, GameHistory&& a_History, std::uint64_t a_StepTime) : +ClientSimulation::ClientSimulation(std::shared_ptr a_World, GameHistory&& a_History, std::uint64_t a_StepTime) : m_StepTime(a_StepTime), m_World(a_World), m_CurrentTime(0), @@ -30,7 +30,7 @@ ClientSimulation::ClientSimulation(game::World& a_World, GameHistory&& a_History Step(); } -ClientSimulation::ClientSimulation(game::World& a_World, std::uint64_t a_StepTime) : +ClientSimulation::ClientSimulation(std::shared_ptr a_World, std::uint64_t a_StepTime) : m_StepTime(a_StepTime), m_World(a_World), m_History(std::numeric_limits::max()), @@ -41,7 +41,7 @@ ClientSimulation::ClientSimulation(game::World& a_World, std::uint64_t a_StepTim float ClientSimulation::Update(float a_Delta) { // TODO: handle freezes (m_CurrentTime > 2 * m_StepTime) - static const float stepTimeSecond = static_cast(STEP_TIME) / 1000.0f; + static const float stepTimeSecond = static_cast(m_StepTime) / 1000.0f; m_CurrentTime += a_Delta; if (m_CurrentTime > stepTimeSecond) { m_CurrentTime = std::fmod(m_CurrentTime, stepTimeSecond); @@ -53,13 +53,13 @@ float ClientSimulation::Update(float a_Delta) { bool ClientSimulation::Step() { const auto& step = m_History[m_CurrentStep]; if (step.has_value()) { - auto snapshot = m_World.Tick(step.value(), FpFloat(m_StepTime) / FpFloat(1000)); + auto snapshot = m_World->Tick(step.value(), FpFloat(m_StepTime) / FpFloat(1000)); if (m_LastValidStep + 1 == m_CurrentStep) { m_LastValidStep = m_CurrentStep; m_LastSnapshot = snapshot; } } else { - m_World.Tick(EMPTY_LOCKSTEP, FpFloat(m_StepTime) / FpFloat(1000)); + m_World->Tick(EMPTY_LOCKSTEP, FpFloat(m_StepTime) / FpFloat(1000)); std::cout << "Empty tick (" << m_CurrentStep << ") !\n"; } m_CurrentStep++; @@ -103,7 +103,7 @@ void ClientSimulation::FastReplay() { if (m_LastValidStep + 1 >= m_CurrentStep) return; - m_World.ResetSnapshots(m_LastSnapshot, m_LastSnapshot); + m_World->ResetSnapshots(m_LastSnapshot, m_LastSnapshot); const std::size_t stepCount = m_CurrentStep - m_LastValidStep; m_CurrentStep = m_LastValidStep;