Compare commits

...

3 Commits

Author SHA1 Message Date
f98d577b89 IDK 2026-10-14 22:31:56 +02:00
7fe056a659 universe to world 2026-10-14 14:24:35 +02:00
bc9145e632 Rename universe to world 2026-10-14 14:23:39 +02:00
44 changed files with 563 additions and 245 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
project(MyEngine project(DeerithEngine
VERSION 0.1 VERSION 0.1
LANGUAGES CXX LANGUAGES CXX
) )

View File

@ -1,11 +0,0 @@
#pragma once
#include <deerith/core/universe.h>
namespace deerith
{
bool connect_to_universe(const char *address, int port);
void shutdown_universe();
bool is_universe_running();
void render_universe();
}

View File

@ -0,0 +1,15 @@
#pragma once
#include <deerith/world/world_core.h>
namespace deerith
{
struct client_t;
bool connect_to_world(const char *address, int port);
void shutdown_world();
bool is_world_running();
void render_world();
client_t *get_server_client();
}

View File

@ -1,7 +1,7 @@
#include "deerith/graphics/window.h" #include "deerith/graphics/window.h"
#include "primitive_internals.h" #include "primitive_internals.h"
#include "../network/network_internals.h" #include "../network/network_internals.h"
#include <deerith/universe.h> #include <deerith/world.h>
#include <glad/gl.h> #include <glad/gl.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@ -130,7 +130,7 @@ void deerith::shutdown_window()
ImGui::DestroyContext(); ImGui::DestroyContext();
shutdown_primitives(); shutdown_primitives();
shutdown_universe(); shutdown_world();
shutdown_network(); shutdown_network();
glfwDestroyWindow(window); glfwDestroyWindow(window);

View File

@ -1,9 +1,9 @@
#include <deerith/network/router.h> #include <deerith/network/router.h>
#include "network/network_internals.h" #include "network/network_internals.h"
#include <deerith/packets/sync_universe_tick.h> #include <deerith/packets/sync_world_tick.h>
void deerith::setup_base_protocols() void deerith::setup_base_protocols()
{ {
router_add_packet_processor<sync_universe_tick_t>(); router_add_packet_processor<sync_world_tick_packet_t>();
} }

View File

@ -1,15 +1,24 @@
#include <deerith/engine.h> #include <deerith/engine.h>
#include <deerith/network/router.h> #include <deerith/network/router.h>
#include <deerith/world.h>
#include <enet/enet.h> #include <enet/enet.h>
#include <thread> #include <thread>
#include <memory>
#include "network_internals.h" #include "network_internals.h"
namespace deerith namespace deerith
{ {
ENetHost *client; ENetHost *client;
ENetPeer *client_peer; ENetPeer *server_peer;
std::unique_ptr<client_t> server_client;
}
deerith::client_t *deerith::get_server_client()
{
return server_client.get();
} }
void deerith::connect_to_server(const char *address, int port) void deerith::connect_to_server(const char *address, int port)
@ -23,8 +32,10 @@ void deerith::connect_to_server(const char *address, int port)
client = enet_host_create(NULL, 1, 2, 0, 0); client = enet_host_create(NULL, 1, 2, 0, 0);
deerith_assert(client, "connect_to_server failed to create host"); deerith_assert(client, "connect_to_server failed to create host");
client_peer = enet_host_connect(client, &eaddress, 2, 0); server_peer = enet_host_connect(client, &eaddress, 2, 0);
deerith_assert(client_peer, "enet_host_connect failed on connect_to_server"); deerith_assert(server_peer, "enet_host_connect failed on connect_to_server");
server_client = std::make_unique<client_t>(server_peer);
} }
int deerith::init_network() int deerith::init_network()
@ -58,7 +69,7 @@ void deerith::flush_network_events()
case ENET_EVENT_TYPE_RECEIVE: case ENET_EVENT_TYPE_RECEIVE:
ENetPacket *packet = event.packet; ENetPacket *packet = event.packet;
router_process_packet(packet->data, packet->dataLength); router_process_packet(packet->data, packet->dataLength, server_client.get());
enet_packet_destroy(event.packet); enet_packet_destroy(event.packet);
break; break;
} }
@ -75,7 +86,7 @@ bool deerith::wait_till_connected_to_server()
} }
else else
{ {
enet_peer_reset(client_peer); enet_peer_reset(server_peer);
deerith_error("failed to connect to server"); deerith_error("failed to connect to server");
return false; return false;
} }

View File

@ -1,59 +0,0 @@
#include <deerith/engine.h>
#include <deerith/universe.h>
#include "network/network_internals.h"
#include <thread>
#include <memory>
namespace deerith
{
std::unique_ptr<std::thread> universe_thread;
std::atomic<bool> universe_running = false;
void universe_simulation();
}
bool deerith::connect_to_universe(const char *address, int port)
{
deerith_assert(!universe_running, "connect_to_universe failed because there is a current running universe");
shutdown_universe();
connect_to_server(address, port);
if (!wait_till_connected_to_server())
{
deerith_error("engine was not able to connect to server");
return false;
}
universe_running = true;
universe_thread = std::make_unique<std::thread>(universe_simulation);
return true;
}
bool deerith::is_universe_running()
{
return universe_running;
}
void deerith::universe_simulation()
{
while (universe_running)
{
flush_network_events();
wait_till_next_click();
}
universe_running = false;
deerith_trace("universe shutdown");
}
void deerith::shutdown_universe()
{
universe_running = false;
if (universe_thread && universe_thread->joinable())
universe_thread->join();
universe_thread.reset();
}

View File

@ -1,14 +0,0 @@
#include <deerith/packets/sync_universe_tick.h>
#include <deerith/network/router.h>
#include <deerith/universe.h>
namespace deerith
{
}
template <>
void deerith::process_packet(sync_universe_tick_t &universe_tick)
{
deerith_trace("sync_universe_tick_t tick set to {}", universe_tick.tick_id);
set_tick(universe_tick.tick_id);
}

View File

@ -1,5 +0,0 @@
#include <deerith/universe.h>
void deerith::render_universe()
{
}

View File

@ -0,0 +1,27 @@
#include <deerith/engine.h>
#include <deerith/graphics/input.h>
#include <deerith/network/router.h>
#include <deerith/world/character_sync_interface.h>
#include <deerith/packets/sync_character_interface.h>
#include "world/world_internals.h"
namespace deerith
{
extern character_sync_interface_t character_sync_interface;
}
void deerith::process_player_input()
{
glm::vec2 movment = get_joystick_axes(0, 0);
character_sync_interface.move_input.push_value(movment);
}
void deerith::send_player_input()
{
sync_character_interface_t sync_character_interface;
sync_character_interface.load(character_sync_interface);
router_send_packet<sync_character_interface_t>(sync_character_interface, get_server_client());
}

View File

@ -0,0 +1,25 @@
#include <deerith/engine.h>
#include <deerith/network/router.h>
#include <deerith/network/packets.h>
#include <deerith/world/entity.h>
#include <deerith/world.h>
#include "world/world_internals.h"
namespace deerith
{
}
template <>
void deerith::process_packet(deerith::sync_world_tick_packet_t &packet, client_t *client)
{
deerith_trace("tick set to {}", packet.tick_id);
set_tick(packet.tick_id);
}
template <>
void deerith::process_packet(deerith::create_player_entity_packet_t &packet, client_t *client)
{
self_entity = create_entity();
add_component<entity_sync_client_position_t>(self_entity);
}

View File

@ -0,0 +1,5 @@
#include <deerith/world.h>
void deerith::render_world()
{
}

View File

@ -0,0 +1,69 @@
#include <deerith/engine.h>
#include <deerith/world.h>
#include "network/network_internals.h"
#include "world/world_internals.h"
#include <thread>
#include <memory>
namespace deerith
{
std::unique_ptr<std::thread> world_thread;
std::atomic<bool> world_running = false;
entity_t self_entity = entt::null;
void world_simulation();
}
bool deerith::connect_to_world(const char *address, int port)
{
deerith_assert(!world_running, "connect_to_world failed because there is a current running world");
shutdown_world();
connect_to_server(address, port);
if (!wait_till_connected_to_server())
{
deerith_error("engine was not able to connect to server");
return false;
}
world_running = true;
world_thread = std::make_unique<std::thread>(world_simulation);
return true;
}
bool deerith::is_world_running()
{
return world_running;
}
void deerith::world_simulation()
{
while (world_running)
{
flush_network_events();
process_player_input();
if (get_world_tick() % 2 == 0)
{
send_player_input();
}
wait_till_next_tick();
}
world_running = false;
deerith_trace("world shutdown");
}
void deerith::shutdown_world()
{
world_running = false;
if (world_thread && world_thread->joinable())
world_thread->join();
world_thread.reset();
}

View File

@ -0,0 +1,10 @@
#pragma once
#include <deerith/world.h>
namespace deerith
{
extern entity_t self_entity;
void process_player_input();
void send_player_input();
}

View File

@ -0,0 +1,5 @@
#include <deerith/world.h>
void deerith::render_world()
{
}

View File

@ -38,5 +38,6 @@ target_link_libraries(DeerithCore
spdlog::spdlog spdlog::spdlog
fmt::fmt fmt::fmt
glm::glm glm::glm
EnTT::EnTT
${ENET_LIBRARY} ${ENET_LIBRARY}
) )

View File

@ -0,0 +1,18 @@
#pragma once
#include <glm/glm.hpp>
namespace cereal
{
template <class Archive>
void serialize(Archive &archive, glm::vec2 &vec)
{
archive(vec.x, vec.y);
}
template <class Archive>
void serialize(Archive &archive, glm::vec3 &vec)
{
archive(vec.x, vec.y, vec.z);
}
}

View File

@ -1,10 +0,0 @@
#pragma once
#include <deerith/engine.h>
namespace deerith
{
uint32_t get_universe_tick();
void wait_till_next_click();
void set_tick(uint32_t);
}

View File

@ -3,8 +3,9 @@
#include <deerith/core/log.h> #include <deerith/core/log.h>
#include <deerith/core/core.h> #include <deerith/core/core.h>
#define UNIVERSE_SIMULATION_TICK_FREQ 50 #define world_SIMULATION_TICK_FREQ 50
#define NETWORK_RELATIVE_TICK 2 #define NETWORK_RELATIVE_TICK 2
#define NETWORK_DELAY 10 #define NETWORK_DELAY 10
namespace deerith namespace deerith

View File

@ -0,0 +1,17 @@
#pragma once
#include <enet/enet.h>
#include <entt/entt.hpp>
namespace deerith
{
using entity_registry_t = entt::registry;
using entity_t = entt::entity;
struct client_t
{
ENetPeer *peer;
entity_t entity_id = entt::null;
client_t(ENetPeer *_peer) : peer(_peer) {}
};
}

View File

@ -3,7 +3,7 @@
namespace deerith namespace deerith
{ {
struct sync_universe_tick_t struct sync_world_tick_packet_t
{ {
static constexpr uint16_t packet_id = 1; static constexpr uint16_t packet_id = 1;
static constexpr bool reliable = true; static constexpr bool reliable = true;
@ -16,4 +16,10 @@ namespace deerith
archive(tick_id); archive(tick_id);
} }
}; };
struct create_player_entity_packet_t
{
static constexpr uint16_t packet_id = 2;
static constexpr bool reliable = true;
};
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <deerith/engine.h> #include <deerith/engine.h>
#include <deerith/network/client.h>
#include <cereal/cereal.hpp> #include <cereal/cereal.hpp>
#include <cereal/archives/portable_binary.hpp> #include <cereal/archives/portable_binary.hpp>
@ -10,25 +11,31 @@
namespace deerith namespace deerith
{ {
using packet_processor_t = std::function<void(const uint8_t *, size_t)>; using packet_processor_t = std::function<void(const uint8_t *, size_t, client_t *)>;
extern std::unordered_map<uint16_t, packet_processor_t> packet_processors; extern std::unordered_map<uint16_t, packet_processor_t> packet_processors;
template <typename T> template <typename T>
void router_add_packet_processor(); void router_add_packet_processor();
void router_process_packet(const uint8_t *data, size_t size); void router_process_packet(const uint8_t *data, size_t size, client_t *client);
template <typename T> template <typename T>
void router_send_packet(T &, ENetPeer *); void router_send_packet(T &, client_t *);
template <typename T> template <typename T>
void process_packet(T &); void process_packet(T &, client_t *client);
} }
template <typename T> template <typename T>
void deerith::router_add_packet_processor() void deerith::router_add_packet_processor()
{ {
packet_processors[T::packet_id] = [](const uint8_t *data, size_t size) packet_processors[T::packet_id] = [](const uint8_t *data, size_t size, client_t *client)
{ {
if (!client)
{
deerith_error("router_add_packet_processor client is nullptr");
return;
}
std::string buffer(reinterpret_cast<const char *>(data), size); std::string buffer(reinterpret_cast<const char *>(data), size);
std::istringstream stream(buffer, std::ios::in | std::ios::binary); std::istringstream stream(buffer, std::ios::in | std::ios::binary);
@ -37,14 +44,20 @@ void deerith::router_add_packet_processor()
T packet{}; T packet{};
archive(packet); archive(packet);
process_packet<T>(packet); process_packet<T>(packet, client);
}; };
} }
template <typename T> template <typename T>
void deerith::router_send_packet(T &packet, ENetPeer *peer) void deerith::router_send_packet(T &packet, client_t *client)
{ {
if (!client)
{
deerith_error("router_send_packet client is nullptr");
return;
}
std::ostringstream stream(std::ios::out | std::ios::binary); std::ostringstream stream(std::ios::out | std::ios::binary);
cereal::PortableBinaryOutputArchive archive(stream); cereal::PortableBinaryOutputArchive archive(stream);
@ -73,7 +86,7 @@ void deerith::router_send_packet(T &packet, ENetPeer *peer)
return; return;
} }
if (enet_peer_send(peer, 0, enet_packet) < 0) if (enet_peer_send(client->peer, 0, enet_packet) < 0)
{ {
enet_packet_destroy(enet_packet); enet_packet_destroy(enet_packet);
deerith_error("failed to send ENet packet"); deerith_error("failed to send ENet packet");

View File

@ -1,11 +0,0 @@
#pragma once
#include <deerith/network/sync_variable.h>
namespace deerith
{
struct sync_user_t
{
sync_variable_t<glm::vec2> move_input;
sync_variable_t<glm::vec2> position;
};
}

View File

@ -1,27 +1,110 @@
#pragma once #pragma once
#include <deerith/engine.h> #include <deerith/engine.h>
#include <deerith/world.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <array> #include <array>
#define BUFFER_SIZE (NETWORK_DELAY + 20) #include <cereal/types/array.hpp>
#include <deerith/core/serialization_ext.h>
#define SYNC_VARIABLE_STORAGE 30
#define BUFFER_SIZE (NETWORK_DELAY + SYNC_VARIABLE_STORAGE)
namespace deerith namespace deerith
{ {
inline size_t get_sync_variable_index(size_t tick = get_world_tick())
{
return ((size_t)tick) % BUFFER_SIZE;
};
template <typename T>
struct sync_variable_transport_t;
template <typename T> template <typename T>
struct sync_variable_entry_t struct sync_variable_entry_t
{ {
T value; T value;
uint32_t tick_id; int tick_id = 0;
template <typename Archive>
void serialize(Archive &archive)
{
archive(value);
archive(tick_id);
}
}; };
template <typename T> template <typename T>
class sync_variable_t class sync_variable_t
{ {
public: public:
~sync_variable_t() override = default; T pull_value()
{
sync_variable_entry_t<T> &entry = buffer[get_sync_variable_index()];
if (entry.tick_id != get_world_tick())
{
return T();
}
return entry.value;
}
void push_value(const T &v)
{
set_value(v, get_world_tick() + NETWORK_DELAY);
}
void set_value(const T &v, int tick_id = 0)
{
if (tick_id > get_world_tick() + SYNC_VARIABLE_STORAGE)
{
deerith_error("set_value error, tick_id > get_world_tick() + SYNC_VARIABLE_STORAGE, tick_id : {}", tick_id);
return;
}
sync_variable_entry_t<T> &entry = buffer[get_sync_variable_index(tick_id)];
entry.tick_id = tick_id;
entry.value = v;
}
private: private:
std::array<sync_variable_entry_t<T>, BUFFER_SIZE> buffer; std::array<sync_variable_entry_t<T>, BUFFER_SIZE> buffer;
friend sync_variable_transport_t<T>;
}; };
template <typename T>
struct sync_variable_transport_t
{
std::array<sync_variable_entry_t<T>, NETWORK_DELAY> variable_transport_data;
void load(const sync_variable_t<T> &sync_var)
{
int begin_tick_id = get_world_tick();
for (int i = 0; i < NETWORK_DELAY; i++)
{
variable_transport_data[i] =
sync_var.buffer[get_sync_variable_index(i + begin_tick_id)];
}
}
void dipose(sync_variable_t<T> &sync_var)
{
int begin_tick_id = get_world_tick();
for (int i = 0; i < NETWORK_DELAY; i++)
{
const sync_variable_entry_t<T> &entry = variable_transport_data[i];
if (entry.tick_id < begin_tick_id || entry.tick_id >= begin_tick_id + NETWORK_DELAY)
{
continue;
}
sync_var.buffer[get_sync_variable_index(entry.tick_id)] = entry;
}
}
template <typename Archive>
void serialize(Archive &archive)
{
archive(variable_transport_data);
}
};
} }

View File

@ -0,0 +1,10 @@
#pragma once
#include <deerith/world/character_sync_interface.h>
namespace deerith
{
struct character_t
{
};
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <deerith/network/client.h>
#include <deerith/network/sync_variable.h>
namespace deerith
{
// struct for linking a entity to a client, mostly in the server
struct entity_link_to_client_t
{
client_t *client = nullptr;
};
// struct for linking a entity to a client
struct entity_sync_client_position_t
{
sync_variable_t<glm::vec2> move_input;
sync_variable_t<glm::vec2> position;
};
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <deerith/engine.h>
#include <entt/entt.hpp>
namespace deerith
{
using entity_registry_t = entt::registry;
using entity_t = entt::entity;
uint32_t get_world_tick();
void wait_till_next_tick();
void set_tick(uint32_t);
entity_registry_t &get_entity_registry_t();
inline entity_t create_entity() { return get_entity_registry_t().create(); }
template <typename T>
T &add_component(entity_t ent)
{
return get_entity_registry_t().emplace<T>(ent);
}
template <typename T>
T &get_component(entity_t ent)
{
return get_entity_registry_t().get<T>(ent);
}
}

View File

@ -6,4 +6,5 @@ namespace deerith
void init_network(); void init_network();
void shutdown_network(); void shutdown_network();
} }

View File

@ -8,7 +8,7 @@ namespace deerith
std::unordered_map<uint16_t, packet_processor_t> packet_processors; std::unordered_map<uint16_t, packet_processor_t> packet_processors;
} }
void deerith::router_process_packet(const uint8_t *data, size_t size) void deerith::router_process_packet(const uint8_t *data, size_t size, client_t *client)
{ {
if (size <= 2) if (size <= 2)
{ {
@ -23,5 +23,5 @@ void deerith::router_process_packet(const uint8_t *data, size_t size)
return; return;
} }
packet_processors[packet_id](&data[2], size - 2); packet_processors[packet_id](&data[2], size - 2, client);
} }

View File

@ -1,4 +1,4 @@
#include <deerith/core/universe.h> #include <deerith/world/world_core.h>
#include <chrono> #include <chrono>
#include <thread> #include <thread>
@ -13,12 +13,12 @@ void deerith::set_tick(uint32_t v)
tick_id = v; tick_id = v;
} }
uint32_t deerith::get_universe_tick() uint32_t deerith::get_world_tick()
{ {
return tick_id; return tick_id;
} }
void deerith::wait_till_next_click() void deerith::wait_till_next_tick()
{ {
using clock = std::chrono::steady_clock; using clock = std::chrono::steady_clock;

View File

@ -0,0 +1,11 @@
#include <deerith/world/world_core.h>
namespace deerith
{
entity_registry_t entity_registry;
}
entt::registry &deerith::get_entity_registry_t()
{
return entity_registry;
}

View File

@ -11,6 +11,8 @@ target_sources(DeerithServer
) )
target_include_directories(DeerithServer target_include_directories(DeerithServer
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
PUBLIC PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include
) )

View File

@ -1,10 +0,0 @@
#pragma once
#include <deerith/core/universe.h>
namespace deerith
{
void run_universe(int port);
void shutdown_universe();
bool is_universe_running();
}

View File

@ -0,0 +1,10 @@
#pragma once
#include <deerith/world/world_core.h>
namespace deerith
{
void run_world(int port);
void shutdown_world();
bool is_world_running();
}

View File

@ -0,0 +1,9 @@
#include "network/network_internals.h"
#include <deerith/network/router.h>
#include <deerith/packets/sync_character_interface.h>
void deerith::load_base_protocols()
{
router_add_packet_processor<sync_character_interface_t>();
}

View File

@ -1,18 +1,26 @@
#include <deerith/core/log.h> #include <deerith/core/log.h>
#include <enet/enet.h> #include <deerith/network/client.h>
#include <deerith/network/router.h>
#include <deerith/packets/sync_world_tick.h>
#include <deerith/core/log.h> #include <deerith/world.h>
#include <enet/enet.h>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <memory>
#include "network_internals.h" #include "network_internals.h"
#include "world/world_internals.h"
namespace deerith namespace deerith
{ {
ENetHost *server; ENetHost *server;
std::vector<ENetPeer *> new_clients; std::vector<std::unique_ptr<client_t>> clients;
void create_client(ENetPeer *peer);
} }
bool deerith::init_server(int port) bool deerith::init_server(int port)
@ -29,6 +37,9 @@ bool deerith::init_server(int port)
deerith_error("init_server failed"); deerith_error("init_server failed");
return false; return false;
} }
load_base_protocols();
return true; return true;
} }
@ -48,23 +59,15 @@ void deerith::shutdown_network()
enet_deinitialize(); enet_deinitialize();
} }
std::vector<ENetPeer *> &deerith::get_new_clients()
{
return new_clients;
}
void deerith::flush_network_events() void deerith::flush_network_events()
{ {
ENetEvent event; ENetEvent event;
new_clients.clear(); while (enet_host_service(server, &event, 0) > 0)
int result = 1;
while ((result = enet_host_service(server, &event, 0)) > 0)
{ {
switch (event.type) switch (event.type)
{ {
case ENET_EVENT_TYPE_CONNECT: case ENET_EVENT_TYPE_CONNECT:
new_clients.push_back(event.peer); create_client(event.peer);
break; break;
case ENET_EVENT_TYPE_DISCONNECT: case ENET_EVENT_TYPE_DISCONNECT:
@ -72,17 +75,23 @@ void deerith::flush_network_events()
break; break;
case ENET_EVENT_TYPE_RECEIVE: case ENET_EVENT_TYPE_RECEIVE:
printf("A packet of length %lu containing %s was received from %s on channel %u.\n", ENetPacket *packet = event.packet;
event.packet->dataLength, router_process_packet(packet->data, packet->dataLength, (client_t *)event.peer->data);
event.packet->data,
event.peer->data,
event.channelID);
enet_packet_destroy(event.packet); enet_packet_destroy(event.packet);
break; break;
case ENET_EVENT_TYPE_NONE:
break;
} }
} }
} }
void deerith::create_client(ENetPeer *peer)
{
char enet_address[32];
enet_address_get_host_ip(&peer->address, enet_address, 31);
deerith_trace("a new client has connected : {}", enet_address);
std::unique_ptr<client_t> client = std::make_unique<client_t>(peer);
peer->data = client.get();
clients.push_back(std::move(client));
client_connects((client_t *)peer->data);
}

View File

@ -10,5 +10,5 @@ namespace deerith
bool init_server(int port); bool init_server(int port);
void flush_network_events(); void flush_network_events();
std::vector<ENetPeer *> &get_new_clients(); void load_base_protocols();
} }

View File

@ -1,70 +0,0 @@
#include <deerith/universe.h>
#include <deerith/core/log.h>
#include <deerith/network/router.h>
#include <deerith/packets/sync_universe_tick.h>
#include "network/network_internals.h"
#include <csignal>
#include <atomic>
namespace deerith
{
int universe_tick = 0;
void universe_simulation();
std::atomic<bool> running = true;
void create_client(ENetPeer *peer);
void handle_signal(int signal);
}
void deerith::handle_signal(int signal)
{
if (signal == SIGTERM)
running = false;
}
void deerith::run_universe(int port)
{
std::signal(SIGTERM, handle_signal);
if (init_server(port))
{
deerith_trace("server init on port {}", port);
while (running)
{
universe_simulation();
}
}
else
{
deerith_error("could not init server");
}
}
void deerith::universe_simulation()
{
flush_network_events();
for (ENetPeer *new_client : get_new_clients())
{
create_client(new_client);
}
wait_till_next_click();
}
void deerith::create_client(ENetPeer *client)
{
char enet_address[32];
enet_address_get_host_ip(&client->address, enet_address, 31);
deerith_trace("A new client has connected : {}", enet_address);
sync_universe_tick_t sync_universe_tick;
sync_universe_tick.tick_id = get_universe_tick();
router_send_packet<sync_universe_tick_t>(sync_universe_tick, client);
}

View File

@ -0,0 +1,74 @@
#include <deerith/world.h>
#include <deerith/core/log.h>
#include <deerith/network/router.h>
#include "network/network_internals.h"
#include "world/world_internals.h"
#include <deerith/world/entity.h>
#include <deerith/packets.h>
#include <csignal>
#include <atomic>
namespace deerith
{
int world_tick = 0;
void world_simulation();
std::atomic<bool> running = true;
void create_client(ENetPeer *peer);
void handle_signal(int signal);
}
void deerith::handle_signal(int signal)
{
if (signal == SIGTERM)
running = false;
}
void deerith::run_world(int port)
{
std::signal(SIGTERM, handle_signal);
if (init_server(port))
{
deerith_trace("server init on port {}", port);
while (running)
{
world_simulation();
}
}
else
{
deerith_error("could not init server");
}
}
void deerith::world_simulation()
{
flush_network_events();
// process movments
wait_till_next_tick();
}
void deerith::client_connects(client_t *client)
{
sync_world_tick_packet_t sync_world_tick;
sync_world_tick.tick_id = get_world_tick();
create_player_entity_packet_t create_player_entity;
router_send_packet(sync_world_tick, client);
router_send_packet(create_player_entity, client);
entity_t entity = create_entity();
entity_link_to_client_t &link = add_component<entity_link_to_client_t>(entity);
entity_sync_client_position_t &position_sync = add_component<entity_sync_client_position_t>(entity);
link.client = client;
client->entity_id = entity;
}

View File

@ -0,0 +1,15 @@
#include <deerith/engine.h>
#include <deerith/packets/sync_character_interface.h>
#include <deerith/network/router.h>
namespace deerith
{
}
template <>
void deerith::process_packet(sync_character_interface_t &interface, client_t *client)
{
deerith_trace("sync player input {} {}");
}

View File

@ -0,0 +1,8 @@
#pragma once
#include <deerith/network/client.h>
namespace deerith
{
void update_players_characters();
void client_connects(client_t *client);
}

View File

@ -0,0 +1,5 @@
#include "world/world_internals.h"
void update_players_characters()
{
}

View File

@ -1,5 +1,5 @@
#include <deerith/engine.h> #include <deerith/engine.h>
#include <deerith/universe.h> #include <deerith/world.h>
#include <thread> #include <thread>
#ifdef DEERITH_CLIENT #ifdef DEERITH_CLIENT
@ -11,7 +11,7 @@ int main(int args_count, const char **args)
deerith::init_engine(); deerith::init_engine();
#ifdef DEERITH_SERVER #ifdef DEERITH_SERVER
deerith::run_universe(8080); deerith::run_world(8080);
#endif #endif
#ifdef DEERITH_CLIENT #ifdef DEERITH_CLIENT
@ -24,13 +24,13 @@ int main(int args_count, const char **args)
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (deerith::connect_to_universe("127.0.0.1", 8080)) if (deerith::connect_to_world("127.0.0.1", 8080))
{ {
deerith_assert(deerith::init_window() == 0, "Failed to init_window"); deerith_assert(deerith::init_window() == 0, "Failed to init_window");
while (deerith::begin_window_display()) while (deerith::begin_window_display())
{ {
deerith::render_universe(); deerith::render_world();
deerith::finish_window_display(); deerith::finish_window_display();
} }