migrate main
This commit is contained in:
@@ -15,6 +15,8 @@ class Client : public StateMachine<Client, void, float> {
|
|||||||
public:
|
public:
|
||||||
Client(const std::shared_ptr<IClientSocket>& a_Socket) : m_Socket(a_Socket) {}
|
Client(const std::shared_ptr<IClientSocket>& a_Socket) : m_Socket(a_Socket) {}
|
||||||
|
|
||||||
|
void SendPacket(const protocol::PacketBase& a_Packet);
|
||||||
|
|
||||||
friend class ClientState;
|
friend class ClientState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace client {
|
|||||||
class GameState : public ClientState {
|
class GameState : public ClientState {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<game::World> m_World;
|
std::shared_ptr<game::World> m_World;
|
||||||
|
// sim::ClientSimulation m_Simulation;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameState(Client& a_Client, const std::shared_ptr<game::World>& a_World);
|
GameState(Client& a_Client, const std::shared_ptr<game::World>& a_World);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace server {
|
|||||||
|
|
||||||
class FakeSocket : public IServerSocket {
|
class FakeSocket : public IServerSocket {
|
||||||
private:
|
private:
|
||||||
std::vector<std::optional<std::shared_ptr<client::FakeSocket>>> m_Clients;
|
std::vector<std::optional<std::weak_ptr<client::FakeSocket>>> m_Clients;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FakeSocket() {}
|
FakeSocket() {}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
@@ -19,16 +20,17 @@ class StateMachine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
StateMachine() {}
|
StateMachine() {}
|
||||||
|
StateMachine(StateMachine&&) = default;
|
||||||
virtual ~StateMachine() {}
|
virtual ~StateMachine() {}
|
||||||
|
|
||||||
TReturn Update(TArgs... args) {
|
virtual TReturn Update(TArgs... args) {
|
||||||
assert(m_State);
|
assert(m_State && "You must change state at least once before updating !");
|
||||||
return m_State->Update(args...);
|
return m_State->Update(args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
void ChangeState(Args&&... args) {
|
void ChangeState(Args&&... args) {
|
||||||
m_State = std::make_unique<T>(static_cast<TDerived&>(*this), args...);
|
m_State = std::make_unique<T>(static_cast<TDerived&>(*this), std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -2,13 +2,23 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <SDL3/SDL_video.h>
|
|
||||||
#include <SDL3/SDL_keycode.h>
|
#include <SDL3/SDL_keycode.h>
|
||||||
|
#include <SDL3/SDL_video.h>
|
||||||
|
#include <td/common/StateMachine.h>
|
||||||
#include <td/misc/Signal.h>
|
#include <td/misc/Signal.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
class Display {
|
class Display : public StateMachine<Display, void, float> {
|
||||||
|
private:
|
||||||
|
SDL_Window* m_Window;
|
||||||
|
SDL_GLContext m_GLContext;
|
||||||
|
|
||||||
|
int m_LastWidth, m_LastHeight;
|
||||||
|
float m_AspectRatio;
|
||||||
|
|
||||||
|
bool m_ShouldClose;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
utils::Signal<float> OnAspectRatioChange;
|
utils::Signal<float> OnAspectRatioChange;
|
||||||
utils::Signal<SDL_Keycode> OnKeyDown;
|
utils::Signal<SDL_Keycode> OnKeyDown;
|
||||||
@@ -17,7 +27,8 @@ class Display {
|
|||||||
~Display();
|
~Display();
|
||||||
|
|
||||||
void PollEvents();
|
void PollEvents();
|
||||||
void Update();
|
void Update(float a_Delta) override;
|
||||||
|
void Close();
|
||||||
|
|
||||||
bool IsCloseRequested() {
|
bool IsCloseRequested() {
|
||||||
return m_ShouldClose;
|
return m_ShouldClose;
|
||||||
@@ -34,15 +45,6 @@ class Display {
|
|||||||
int GetWindowHeight() {
|
int GetWindowHeight() {
|
||||||
return m_LastHeight;
|
return m_LastHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
SDL_Window* m_Window;
|
|
||||||
SDL_GLContext m_GLContext;
|
|
||||||
|
|
||||||
int m_LastWidth, m_LastHeight;
|
|
||||||
float m_AspectRatio;
|
|
||||||
|
|
||||||
bool m_ShouldClose;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
16
include/td/display/DisplayState.h
Normal file
16
include/td/display/DisplayState.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/display/Display.h>
|
||||||
|
#include <td/misc/SlotGuard.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
class DisplayState : public Display::State, private utils::SlotGuard {
|
||||||
|
public:
|
||||||
|
DisplayState(Display& a_Display);
|
||||||
|
virtual ~DisplayState() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnAspectRatioChange(float a_Ratio) {}
|
||||||
|
virtual void OnKeyDown(SDL_Keycode a_Key) {}
|
||||||
|
};
|
||||||
|
} // namespace td
|
||||||
33
include/td/display/state/DebugWorldState.h
Normal file
33
include/td/display/state/DebugWorldState.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <client/Client.h>
|
||||||
|
#include <server/Server.h>
|
||||||
|
#include <td/display/DisplayState.h>
|
||||||
|
#include <td/render/Renderer.h>
|
||||||
|
#include <td/simulation/ClientSimulation.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class ClientHandler;
|
||||||
|
|
||||||
|
class DebugWorldState : public DisplayState {
|
||||||
|
private:
|
||||||
|
render::RenderPipeline m_Renderer;
|
||||||
|
std::unique_ptr<client::Client> m_Client;
|
||||||
|
std::unique_ptr<server::Server> m_Server;
|
||||||
|
std::unique_ptr<sim::ClientSimulation> m_Simulation;
|
||||||
|
render::Camera m_Camera;
|
||||||
|
std::unique_ptr<ClientHandler> m_ClientHandler;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DebugWorldState(Display& a_Display);
|
||||||
|
~DebugWorldState();
|
||||||
|
|
||||||
|
virtual void Update(float a_Delta) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnAspectRatioChange(float a_Ratio) override;
|
||||||
|
virtual void OnKeyDown(SDL_Keycode a_Key) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
@@ -3,7 +3,9 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
|
void Client::SendPacket(const protocol::PacketBase& a_Packet) {
|
||||||
|
m_Socket->Send(a_Packet);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
158
src/main.cpp
158
src/main.cpp
@@ -1,107 +1,5 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <fstream>
|
#include <td/display/state/DebugWorldState.h>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <td/game/World.h>
|
|
||||||
#include <td/input/Display.h>
|
|
||||||
#include <td/protocol/packet/PacketSerialize.h>
|
|
||||||
#include <td/protocol/packet/Packets.h>
|
|
||||||
#include <td/render/renderer/EntityRenderer.h>
|
|
||||||
#include <td/render/renderer/TowerRenderer.h>
|
|
||||||
#include <td/render/renderer/WorldRenderer.h>
|
|
||||||
#include <td/simulation/ClientSimulation.h>
|
|
||||||
|
|
||||||
#include <sp/common/DataBuffer.h>
|
|
||||||
#include <sp/extensions/Compress.h>
|
|
||||||
#include <sp/io/MessageStream.h>
|
|
||||||
#include <sp/io/StdIo.h>
|
|
||||||
|
|
||||||
#include <server/Server.h>
|
|
||||||
#include <server/socket/FakeSocket.h>
|
|
||||||
#include <server/state/GameState.h>
|
|
||||||
|
|
||||||
#include <client/Client.h>
|
|
||||||
#include <client/socket/FakeSocket.h>
|
|
||||||
#include <client/state/GameState.h>
|
|
||||||
|
|
||||||
class WorldApply : public td::protocol::PacketHandler {
|
|
||||||
private:
|
|
||||||
td::game::World& m_World;
|
|
||||||
using td::protocol::PacketHandler::Handle;
|
|
||||||
|
|
||||||
public:
|
|
||||||
WorldApply(td::game::World& a_World) : m_World(a_World) {}
|
|
||||||
|
|
||||||
void Handle(const td::protocol::packets::WorldHeaderPacket& a_Header) override {
|
|
||||||
m_World.LoadMap(*a_Header);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Handle(const td::protocol::packets::WorldDataPacket& a_Data) override {
|
|
||||||
m_World.LoadMap(*a_Data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ClientHandler : public td::protocol::PacketHandler {
|
|
||||||
private:
|
|
||||||
td::sim::ClientSimulation& m_Simulation;
|
|
||||||
|
|
||||||
using td::protocol::PacketHandler::Handle;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ClientHandler(td::sim::ClientSimulation& a_Simulation) : m_Simulation(a_Simulation) {}
|
|
||||||
|
|
||||||
void Handle(const td::protocol::packets::LockStepsPacket& a_LockStep) {
|
|
||||||
m_Simulation.Handle(a_LockStep);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Handle(const td::protocol::packets::LockStepResponsePacket& a_LockStep) {
|
|
||||||
m_Simulation.Handle(a_LockStep);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void Save(const td::protocol::PacketBase& header, const td::protocol::PacketBase& data) {
|
|
||||||
auto comp = std::make_shared<sp::ZlibCompress>();
|
|
||||||
|
|
||||||
std::ofstream fStream("test/tdmap.tdmap3");
|
|
||||||
auto out = std::make_shared<sp::StdOuput>(fStream);
|
|
||||||
|
|
||||||
sp::MessageStream<td::protocol::PacketFactory> stream(std::move(out), std::move(comp));
|
|
||||||
|
|
||||||
stream.WriteMessage(header, false);
|
|
||||||
stream.WriteMessage(data, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
td::game::WorldPtr GetWorld() {
|
|
||||||
auto comp = std::make_shared<sp::ZlibCompress>();
|
|
||||||
|
|
||||||
std::ifstream fStream("test/tdmap.tdmap2");
|
|
||||||
auto out = std::make_shared<sp::StdInput>(fStream);
|
|
||||||
|
|
||||||
sp::MessageStream<td::protocol::PacketFactory> stream(std::move(out), std::move(comp));
|
|
||||||
|
|
||||||
auto header = stream.ReadMessage(td::protocol::PacketID::WorldHeader);
|
|
||||||
auto data = stream.ReadMessage(td::protocol::PacketID::WorldData);
|
|
||||||
|
|
||||||
auto w = std::make_shared<td::game::World>();
|
|
||||||
auto wa = std::make_shared<WorldApply>(*w);
|
|
||||||
|
|
||||||
td::protocol::PacketDispatcher d;
|
|
||||||
d.RegisterHandler(wa);
|
|
||||||
|
|
||||||
d.Dispatch(*header);
|
|
||||||
d.Dispatch(*data);
|
|
||||||
|
|
||||||
Save(*header, *data);
|
|
||||||
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FastForward(td::game::World& a_World, const td::sim::GameHistory& a_LockSteps) {
|
|
||||||
const td::FpFloat delta = td::FpFloat(1) / td::FpFloat(75);
|
|
||||||
for (const auto& lockstep : a_LockSteps) {
|
|
||||||
a_World.Tick(lockstep, delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float GetDelta() {
|
float GetDelta() {
|
||||||
static std::chrono::time_point<std::chrono::system_clock> m_LastTime = std::chrono::system_clock::now();
|
static std::chrono::time_point<std::chrono::system_clock> m_LastTime = std::chrono::system_clock::now();
|
||||||
@@ -112,65 +10,15 @@ float GetDelta() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
td::game::WorldPtr serverWorld = GetWorld();
|
|
||||||
|
|
||||||
// server
|
|
||||||
auto serverFakeSocket = std::make_shared<td::server::FakeSocket>();
|
|
||||||
td::server::Server server(serverFakeSocket);
|
|
||||||
|
|
||||||
// client
|
|
||||||
auto clientFakeSocket = td::client::FakeSocket::Connect(serverFakeSocket);
|
|
||||||
td::client::Client client(clientFakeSocket);
|
|
||||||
|
|
||||||
// init GL context
|
// init GL context
|
||||||
td::Display display(1920, 1080, "Tower-Defense 2");
|
td::Display display(1920, 1080, "Tower-Defense 2");
|
||||||
|
|
||||||
td::render::Camera cam;
|
display.ChangeState<td::DebugWorldState>();
|
||||||
|
|
||||||
display.OnAspectRatioChange.Connect([&cam](float a_AspectRatio) { cam.UpdatePerspective(a_AspectRatio); });
|
|
||||||
|
|
||||||
td::game::WorldPtr clientWorld = GetWorld();
|
|
||||||
|
|
||||||
td::render::RenderPipeline renderer;
|
|
||||||
renderer.AddRenderer<td::render::WorldRenderer>(cam, *clientWorld);
|
|
||||||
renderer.AddRenderer<td::render::EntityRenderer>(cam, *clientWorld);
|
|
||||||
renderer.AddRenderer<td::render::TowerRenderer>(cam, *clientWorld);
|
|
||||||
|
|
||||||
cam.SetCamPos({77, 7, 13});
|
|
||||||
cam.UpdatePerspective(display.GetAspectRatio());
|
|
||||||
|
|
||||||
td::sim::ClientSimulation simulation(*clientWorld, td::STEP_TIME);
|
|
||||||
ClientHandler clientHandler(simulation);
|
|
||||||
|
|
||||||
// packets from the server to the client
|
|
||||||
clientFakeSocket->OnReceive.Connect([&clientHandler](const td::protocol::PacketBase& a_Packet) {
|
|
||||||
a_Packet.Dispatch(clientHandler);
|
|
||||||
});
|
|
||||||
|
|
||||||
simulation.OnMissingLockSteps.Connect([&clientFakeSocket](const std::vector<td::StepTime>& a_MissingSteps) {
|
|
||||||
clientFakeSocket->Send(td::protocol::packets::LockStepRequestPacket(a_MissingSteps));
|
|
||||||
});
|
|
||||||
|
|
||||||
// temporary tests
|
|
||||||
display.OnKeyDown.Connect([&clientFakeSocket](SDL_Keycode key) {
|
|
||||||
if (key == SDLK_A) {
|
|
||||||
clientFakeSocket->Send(td::protocol::packets::SpawnTroopPacket(td::EntityType::Zombie, 1));
|
|
||||||
} else if (key == SDLK_Z) {
|
|
||||||
clientFakeSocket->Send(td::protocol::packets::PlaceTowerPacket(td::TowerType::Archer, td::TowerCoords(77, 13)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
server.ChangeState<td::server::GameState>(serverWorld);
|
|
||||||
client.ChangeState<td::client::GameState>(clientWorld);
|
|
||||||
|
|
||||||
while (!display.IsCloseRequested()) {
|
while (!display.IsCloseRequested()) {
|
||||||
display.PollEvents();
|
display.PollEvents();
|
||||||
float delta = GetDelta();
|
float delta = GetDelta();
|
||||||
server.Update(delta);
|
display.Update(delta);
|
||||||
client.Update(delta);
|
|
||||||
float lerp = simulation.Update(delta);
|
|
||||||
renderer.Render(lerp);
|
|
||||||
display.Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ namespace server {
|
|||||||
void FakeSocket::SendPeer(PeerID a_Peer, const protocol::PacketBase& a_Packet) {
|
void FakeSocket::SendPeer(PeerID a_Peer, const protocol::PacketBase& a_Packet) {
|
||||||
auto socket = m_Clients.at(a_Peer);
|
auto socket = m_Clients.at(a_Peer);
|
||||||
assert(socket.has_value());
|
assert(socket.has_value());
|
||||||
socket.value()->OnReceive(a_Packet);
|
assert(!socket.value().expired());
|
||||||
|
socket.value().lock()->OnReceive(a_Packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeSocket::ReceiveFromFakePeer(PeerID a_Peer, const protocol::PacketBase& a_Packet) {
|
void FakeSocket::ReceiveFromFakePeer(PeerID a_Peer, const protocol::PacketBase& a_Packet) {
|
||||||
@@ -29,7 +30,8 @@ PeerID FakeSocket::ConnectFakePeer(const std::shared_ptr<client::FakeSocket>& a_
|
|||||||
void FakeSocket::DisconnectFakePeer(PeerID a_Peer) {
|
void FakeSocket::DisconnectFakePeer(PeerID a_Peer) {
|
||||||
auto socket = m_Clients.at(a_Peer);
|
auto socket = m_Clients.at(a_Peer);
|
||||||
assert(socket.has_value());
|
assert(socket.has_value());
|
||||||
socket.value()->OnDisconnect();
|
assert(!socket.value().expired());
|
||||||
|
socket.value().lock()->OnDisconnect();
|
||||||
OnDisconnectPeer(a_Peer);
|
OnDisconnectPeer(a_Peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <td/input/Display.h>
|
#include <td/display/Display.h>
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
@@ -125,6 +125,9 @@ Display::Display(int a_Width, int a_Height, const std::string& a_Title) :
|
|||||||
ImGui_ImplOpenGL3_Init("#version 330");
|
ImGui_ImplOpenGL3_Init("#version 330");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Display::Close() {
|
||||||
|
m_ShouldClose = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Display::PollEvents() {
|
void Display::PollEvents() {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
@@ -161,7 +164,8 @@ void Display::PollEvents() {
|
|||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::Update() {
|
void Display::Update(float a_Delta) {
|
||||||
|
StateMachine::Update(a_Delta);
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
||||||
10
src/td/display/DisplayState.cpp
Normal file
10
src/td/display/DisplayState.cpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include <td/display/DisplayState.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
DisplayState::DisplayState(Display& a_Display) : Display::State(a_Display) {
|
||||||
|
Connect(m_StateMachine.OnKeyDown, std::bind(&DisplayState::OnKeyDown, this, std::placeholders::_1));
|
||||||
|
Connect(m_StateMachine.OnAspectRatioChange, std::bind(&DisplayState::OnAspectRatioChange, this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
162
src/td/display/state/DebugWorldState.cpp
Normal file
162
src/td/display/state/DebugWorldState.cpp
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
#include <td/display/state/DebugWorldState.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <td/game/World.h>
|
||||||
|
#include <td/protocol/packet/PacketSerialize.h>
|
||||||
|
#include <td/protocol/packet/Packets.h>
|
||||||
|
#include <td/render/renderer/EntityRenderer.h>
|
||||||
|
#include <td/render/renderer/TowerRenderer.h>
|
||||||
|
#include <td/render/renderer/WorldRenderer.h>
|
||||||
|
#include <td/simulation/ClientSimulation.h>
|
||||||
|
|
||||||
|
#include <sp/common/DataBuffer.h>
|
||||||
|
#include <sp/extensions/Compress.h>
|
||||||
|
#include <sp/io/MessageStream.h>
|
||||||
|
#include <sp/io/StdIo.h>
|
||||||
|
|
||||||
|
#include <server/Server.h>
|
||||||
|
#include <server/socket/FakeSocket.h>
|
||||||
|
#include <server/state/GameState.h>
|
||||||
|
|
||||||
|
#include <client/Client.h>
|
||||||
|
#include <client/socket/FakeSocket.h>
|
||||||
|
#include <client/state/GameState.h>
|
||||||
|
|
||||||
|
#include <td/display/Display.h>
|
||||||
|
#include <td/display/state/DebugWorldState.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
using protocol::PacketHandler::Handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WorldApply(game::World& a_World) : m_World(a_World) {}
|
||||||
|
|
||||||
|
void Handle(const protocol::packets::WorldHeaderPacket& a_Header) override {
|
||||||
|
m_World.LoadMap(*a_Header);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handle(const protocol::packets::WorldDataPacket& a_Data) override {
|
||||||
|
m_World.LoadMap(*a_Data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void Save(const protocol::PacketBase& header, const protocol::PacketBase& data) {
|
||||||
|
auto comp = std::make_shared<sp::ZlibCompress>();
|
||||||
|
|
||||||
|
std::ofstream fStream("test/tdmap.tdmap3");
|
||||||
|
auto out = std::make_shared<sp::StdOuput>(fStream);
|
||||||
|
|
||||||
|
sp::MessageStream<protocol::PacketFactory> stream(std::move(out), std::move(comp));
|
||||||
|
|
||||||
|
stream.WriteMessage(header, false);
|
||||||
|
stream.WriteMessage(data, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
game::WorldPtr GetWorld() {
|
||||||
|
auto comp = std::make_shared<sp::ZlibCompress>();
|
||||||
|
|
||||||
|
std::ifstream fStream("test/tdmap.tdmap2");
|
||||||
|
auto out = std::make_shared<sp::StdInput>(fStream);
|
||||||
|
|
||||||
|
sp::MessageStream<protocol::PacketFactory> stream(std::move(out), std::move(comp));
|
||||||
|
|
||||||
|
auto header = stream.ReadMessage(protocol::PacketID::WorldHeader);
|
||||||
|
auto data = stream.ReadMessage(protocol::PacketID::WorldData);
|
||||||
|
|
||||||
|
auto w = std::make_shared<game::World>();
|
||||||
|
auto wa = std::make_shared<WorldApply>(*w);
|
||||||
|
|
||||||
|
protocol::PacketDispatcher d;
|
||||||
|
d.RegisterHandler(wa);
|
||||||
|
|
||||||
|
d.Dispatch(*header);
|
||||||
|
d.Dispatch(*data);
|
||||||
|
|
||||||
|
Save(*header, *data);
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugWorldState::DebugWorldState(Display& a_Display) : DisplayState(a_Display) {
|
||||||
|
game::WorldPtr serverWorld = GetWorld();
|
||||||
|
|
||||||
|
// server
|
||||||
|
auto serverFakeSocket = std::make_shared<server::FakeSocket>();
|
||||||
|
m_Server = std::make_unique<server::Server>(serverFakeSocket);
|
||||||
|
|
||||||
|
// client
|
||||||
|
auto clientFakeSocket = client::FakeSocket::Connect(serverFakeSocket);
|
||||||
|
m_Client = std::make_unique<client::Client>(clientFakeSocket);
|
||||||
|
|
||||||
|
game::WorldPtr clientWorld = GetWorld();
|
||||||
|
|
||||||
|
m_Renderer.AddRenderer<render::WorldRenderer>(m_Camera, *clientWorld);
|
||||||
|
m_Renderer.AddRenderer<render::EntityRenderer>(m_Camera, *clientWorld);
|
||||||
|
m_Renderer.AddRenderer<render::TowerRenderer>(m_Camera, *clientWorld);
|
||||||
|
|
||||||
|
m_Camera.SetCamPos({77, 7, 13});
|
||||||
|
m_Camera.UpdatePerspective(m_StateMachine.GetAspectRatio());
|
||||||
|
|
||||||
|
m_Simulation = std::make_unique<sim::ClientSimulation>(*clientWorld, STEP_TIME);
|
||||||
|
|
||||||
|
m_ClientHandler = std::make_unique<ClientHandler>(*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<td::StepTime>& a_MissingSteps) {
|
||||||
|
clientFakeSocket->Send(protocol::packets::LockStepRequestPacket(a_MissingSteps));
|
||||||
|
});
|
||||||
|
|
||||||
|
m_Server->ChangeState<server::GameState>(serverWorld);
|
||||||
|
m_Client->ChangeState<client::GameState>(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugWorldState::OnAspectRatioChange(float a_Ratio) {
|
||||||
|
m_Camera.UpdatePerspective(a_Ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugWorldState::OnKeyDown(SDL_Keycode a_Key) {
|
||||||
|
// temporary tests
|
||||||
|
if (a_Key == SDLK_A) {
|
||||||
|
m_Client->SendPacket(td::protocol::packets::SpawnTroopPacket(td::EntityType::Zombie, 1));
|
||||||
|
} else if (a_Key == SDLK_Z) {
|
||||||
|
m_Client->SendPacket(td::protocol::packets::PlaceTowerPacket(td::TowerType::Archer, td::TowerCoords(77, 13)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugWorldState::~DebugWorldState() {}
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
Reference in New Issue
Block a user