diff --git a/include/Cubed/gameplay/client_entity_manager.hpp b/include/Cubed/gameplay/client_entity_manager.hpp index 99d2e9b..39739d2 100644 --- a/include/Cubed/gameplay/client_entity_manager.hpp +++ b/include/Cubed/gameplay/client_entity_manager.hpp @@ -10,7 +10,7 @@ namespace Cubed { class ClientWorld; class ClientEntityManager { public: - enum class Command { CREATE }; + enum class Command { CREATE, DESTORY }; ClientEntityManager(ClientWorld& world); void update(); @@ -19,7 +19,7 @@ public: void add_entity(EntityID id, std::string_view name, const glm::vec3& pos); void receive_entity_create(S2CEntityCreate& s2c); - + void destory(EntityID id); const entt::registry& get_registry() const; private: @@ -32,7 +32,7 @@ private: using acc = EntityMap::accessor; using cacc = EntityMap::const_accessor; using CreateFunc = std::function; - using TaskElement = std::variant; + using TaskElement = std::variant; using TaskPair = std::pair; ClientWorld& m_world; @@ -42,7 +42,7 @@ private: tbb::concurrent_queue m_tasks; void handle_task(); - + void handle_entity_destory(EntityID id); template void create_entity_in_registry(EntityID id, Args&&... args) { { diff --git a/include/Cubed/gameplay/packet.hpp b/include/Cubed/gameplay/packet.hpp index 5508eb6..f83fad3 100644 --- a/include/Cubed/gameplay/packet.hpp +++ b/include/Cubed/gameplay/packet.hpp @@ -62,6 +62,7 @@ enum class PacketEnum : uint16_t { S2C_CLEAR_ALL_CHUNKS = 3005, UPDATE_TIME = 3006, S2C_ENTITY_CREATE = 3007, + S2C_ENTITY_DESTORY = 3008, CHAT_MSG = 4001, VOICE_MSG = 4002, PING = 9001, @@ -115,6 +116,9 @@ template <> constexpr uint16_t get_packet_id() { template <> constexpr uint16_t get_packet_id() { return std::to_underlying(PacketEnum::S2C_ENTITY_CREATE); } +template <> constexpr uint16_t get_packet_id() { + return std::to_underlying(PacketEnum::S2C_ENTITY_DESTORY); +} template <> constexpr uint16_t get_packet_id() { return std::to_underlying(PacketEnum::UPDATE_TIME); } diff --git a/include/Cubed/gameplay/server_entity_manager.hpp b/include/Cubed/gameplay/server_entity_manager.hpp index a97ef57..e924ec5 100644 --- a/include/Cubed/gameplay/server_entity_manager.hpp +++ b/include/Cubed/gameplay/server_entity_manager.hpp @@ -16,11 +16,11 @@ public: void update(); // not thread safe void add_entity(std::string_view name, const glm::vec3& pos); - + void destory(EntityID id); void handle_player_login(std::shared_ptr session); private: - enum class Command { CREATE, SEND_ALL_ENTITIES }; + enum class Command { CREATE, SEND_ALL_ENTITIES, DESTORY }; struct EntityCreateElement { std::string name; glm::vec3 pos; @@ -30,7 +30,7 @@ private: using cacc = EntityMap::const_accessor; using CreateFunc = std::function; using TaskElement = - std::variant, EntityCreateElement>; + std::variant, EntityCreateElement, EntityID>; using TaskPair = std::pair; ServerWorld& m_world; tbb::concurrent_queue m_tasks; @@ -39,8 +39,9 @@ private: EntityMap m_entities; std::unordered_map m_factories; void create_entity(std::string_view name, const glm::vec3& pos); - void send_entity_create(EntityID id, std::string_view name, - const glm::vec3& pos); + void handle_entity_create(EntityID id, std::string_view name, + const glm::vec3& pos); + void handle_entity_destory(EntityID id); void handle_task(); void send_all_entities(std::shared_ptr& session); template EntityID add_entity(Args&&... args) { diff --git a/src/gameplay/client_entity_manager.cpp b/src/gameplay/client_entity_manager.cpp index 1cdc8a1..88a34f9 100644 --- a/src/gameplay/client_entity_manager.cpp +++ b/src/gameplay/client_entity_manager.cpp @@ -39,19 +39,38 @@ void ClientEntityManager::receive_entity_create(S2CEntityCreate& s2c) { m_tasks.emplace(Command::CREATE, std::move(c)); } +void ClientEntityManager::destory(EntityID id) { + m_tasks.emplace(Command::DESTORY, id); +} + void ClientEntityManager::handle_task() { TaskPair pair; while (m_tasks.try_pop(pair)) { switch (pair.first) { - case Command::CREATE: + case Command::CREATE: { auto* p = std::get_if(&pair.second); ASSERT(p); add_entity(p->id, p->name, p->pos); - break; + + } break; + case Command::DESTORY: { + auto* p = std::get_if(&pair.second); + ASSERT(p); + handle_entity_destory(*p); + } break; } } } +void ClientEntityManager::handle_entity_destory(EntityID id) { + acc a; + if (!m_entities.find(a, id)) { + return; + } + m_registry.destroy(a->second); + m_entities.erase(a); +} + const entt::registry& ClientEntityManager::get_registry() const { return m_registry; } diff --git a/src/gameplay/network_client.cpp b/src/gameplay/network_client.cpp index 971b874..066995b 100644 --- a/src/gameplay/network_client.cpp +++ b/src/gameplay/network_client.cpp @@ -150,6 +150,12 @@ asio::awaitable NetworkClient::read_loop() { } } break; + case std::to_underlying(PacketEnum::S2C_ENTITY_DESTORY): { + auto* msg = Arena::Create(&arena); + if (decode_packet(*msg, body_data, header)) { + m_world.entity_manager().destory(msg->id()); + } + } break; } } } catch (const asio::system_error& e) { diff --git a/src/gameplay/server_entity_manager.cpp b/src/gameplay/server_entity_manager.cpp index 3bd6885..97b59f7 100644 --- a/src/gameplay/server_entity_manager.cpp +++ b/src/gameplay/server_entity_manager.cpp @@ -37,6 +37,11 @@ void ServerEntityManager::handle_task() { ASSERT(c); send_all_entities(*c); } break; + case Command::DESTORY: { + auto* c = std::get_if(&pair.second); + ASSERT(c); + handle_entity_destory(*c); + } break; } } } @@ -47,6 +52,10 @@ void ServerEntityManager::add_entity(std::string_view name, EntityCreateElement{std::string(name), pos}); } +void ServerEntityManager::destory(EntityID id) { + m_tasks.emplace(Command::DESTORY, id); +} + void ServerEntityManager::handle_player_login( std::shared_ptr session) { m_tasks.emplace(Command::SEND_ALL_ENTITIES, std::move(session)); @@ -62,7 +71,7 @@ void ServerEntityManager::create_entity(std::string_view name, ASSERT(t); t->transform.position.value = pos; } - send_entity_create(e, name, pos); + handle_entity_create(e, name, pos); } void ServerEntityManager::send_all_entities(std::shared_ptr& session) { @@ -79,8 +88,9 @@ void ServerEntityManager::send_all_entities(std::shared_ptr& session) { } } -void ServerEntityManager::send_entity_create(EntityID id, std::string_view name, - const glm::vec3& pos) { +void ServerEntityManager::handle_entity_create(EntityID id, + std::string_view name, + const glm::vec3& pos) { auto sessions = m_world.get_all_session(); Arena arena; @@ -94,4 +104,20 @@ void ServerEntityManager::send_entity_create(EntityID id, std::string_view name, } } +void ServerEntityManager::handle_entity_destory(EntityID id) { + acc a; + if (!m_entities.find(a, id)) { + return; + } + m_registry.destroy(a->second); + m_entities.erase(a); + auto sessions = m_world.get_all_session(); + Arena arena; + auto* s2c = Arena::Create(&arena); + s2c->set_id(id); + for (auto& s : sessions) { + s->send(make_packet(*s2c)); + } +} + } // namespace Cubed \ No newline at end of file diff --git a/src/proto/world/entity.proto b/src/proto/world/entity.proto index fd63ff0..d4b9575 100644 --- a/src/proto/world/entity.proto +++ b/src/proto/world/entity.proto @@ -6,4 +6,8 @@ message S2CEntityCreate { uint64 id = 1; string name = 2; Vec3 pos = 3; +} + +message S2CEntityDestory { + uint64 id = 1; } \ No newline at end of file