mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(gameplay): add entity managers and refactor to ECS components
This commit is contained in:
54
include/Cubed/gameplay/client_entity_manager.hpp
Normal file
54
include/Cubed/gameplay/client_entity_manager.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/ecs/entity.hpp"
|
||||
#include "glm/ext/vector_float3.hpp"
|
||||
#include "world/entity.pb.h"
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
#include <tbb/concurrent_hash_map.h>
|
||||
#include <tbb/concurrent_queue.h>
|
||||
namespace Cubed {
|
||||
class ClientWorld;
|
||||
class ClientEntityManager {
|
||||
public:
|
||||
enum class Command { CREATE };
|
||||
|
||||
ClientEntityManager(ClientWorld& world);
|
||||
void update();
|
||||
void init();
|
||||
// not thread safe
|
||||
void add_entity(EntityID id, std::string_view name, const glm::vec3& pos);
|
||||
|
||||
void receive_entity_create(S2CEntityCreate& s2c);
|
||||
|
||||
private:
|
||||
struct EntityCreateElement {
|
||||
EntityID id;
|
||||
std::string name;
|
||||
glm::vec3 pos;
|
||||
};
|
||||
using EntityMap = tbb::concurrent_hash_map<EntityID, entt::entity>;
|
||||
using acc = EntityMap::accessor;
|
||||
using cacc = EntityMap::const_accessor;
|
||||
using CreateFunc = std::function<void(EntityID id)>;
|
||||
using TaskElement = std::variant<EntityCreateElement>;
|
||||
using TaskPair = std::pair<Command, TaskElement>;
|
||||
|
||||
ClientWorld& m_world;
|
||||
entt::registry m_registry;
|
||||
EntityMap m_entities;
|
||||
std::unordered_map<std::string_view, CreateFunc> m_factories;
|
||||
tbb::concurrent_queue<TaskPair> m_tasks;
|
||||
|
||||
void handle_task();
|
||||
|
||||
template <typename... Args> void add_entity(EntityID id, Args&&... args) {
|
||||
auto entity = m_registry.create();
|
||||
|
||||
((m_registry.emplace<std::remove_cvref_t<Args>>(
|
||||
entity, std::forward<Args>(args))),
|
||||
...);
|
||||
m_entities.emplace(id, entity);
|
||||
return;
|
||||
}
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -1,15 +1,9 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/ecs/animation.hpp"
|
||||
#include "Cubed/gameplay/ecs/entity.hpp"
|
||||
#include "Cubed/gameplay/ecs/identity.hpp"
|
||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||
#include "Cubed/gameplay/model.hpp"
|
||||
namespace Cubed {
|
||||
struct ClientEntity {
|
||||
|
||||
Entity entity;
|
||||
|
||||
EntityInfo info;
|
||||
struct BaseClientCreature {
|
||||
|
||||
Transform transform;
|
||||
|
||||
|
||||
@@ -1,32 +1,27 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/ecs/entity.hpp"
|
||||
#include "Cubed/gameplay/ecs/health.hpp"
|
||||
#include "Cubed/gameplay/ecs/identity.hpp"
|
||||
#include "Cubed/gameplay/ecs/movement.hpp"
|
||||
#include "Cubed/gameplay/ecs/state.hpp"
|
||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||
#include "Cubed/gameplay/hitbox.hpp"
|
||||
namespace Cubed {
|
||||
struct ServerEntity {
|
||||
|
||||
Entity entity;
|
||||
struct BaseServerCreature {
|
||||
Transform transform{};
|
||||
|
||||
EntityInfo info;
|
||||
Velocity velocity{};
|
||||
|
||||
Transform transform;
|
||||
Movement movement{};
|
||||
|
||||
Velocity velocity;
|
||||
MoveState move_state{};
|
||||
|
||||
Movement movement;
|
||||
Direction direction{};
|
||||
|
||||
MoveState move_state;
|
||||
Gravity gravity{};
|
||||
|
||||
Direction direction;
|
||||
Health health{};
|
||||
|
||||
Gravity gravity;
|
||||
|
||||
Health health;
|
||||
|
||||
HitboxID hitbox;
|
||||
HitboxID hitbox{};
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -16,9 +16,9 @@ struct Direction {
|
||||
};
|
||||
|
||||
struct Transform {
|
||||
Position position;
|
||||
Orientation orientation;
|
||||
Direction direction;
|
||||
Position position{};
|
||||
Orientation orientation{};
|
||||
Direction direction{};
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -60,6 +60,7 @@ enum class PacketEnum : uint16_t {
|
||||
BLOCK_CHANGE_REQ = 3003,
|
||||
BLOCK_CHANGE_RSP = 3004,
|
||||
S2C_CLEAR_ALL_CHUNKS = 3005,
|
||||
S2C_ENTITY_CREATE = 3006,
|
||||
UPDATE_TIME = 3006,
|
||||
CHAT_MSG = 4001,
|
||||
VOICE_MSG = 4002,
|
||||
@@ -111,6 +112,9 @@ template <> constexpr uint16_t get_packet_id<BlockChangeRsp>() {
|
||||
template <> constexpr uint16_t get_packet_id<S2C_ClearAllChunks>() {
|
||||
return std::to_underlying(PacketEnum::S2C_CLEAR_ALL_CHUNKS);
|
||||
}
|
||||
template <> constexpr uint16_t get_packet_id<S2CEntityCreate>() {
|
||||
return std::to_underlying(PacketEnum::S2C_ENTITY_CREATE);
|
||||
}
|
||||
template <> constexpr uint16_t get_packet_id<UpdateTime>() {
|
||||
return std::to_underlying(PacketEnum::UPDATE_TIME);
|
||||
}
|
||||
|
||||
42
include/Cubed/gameplay/server_entity_manager.hpp
Normal file
42
include/Cubed/gameplay/server_entity_manager.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/ecs/entity.hpp"
|
||||
#include "glm/ext/vector_float3.hpp"
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
#include <tbb/concurrent_hash_map.h>
|
||||
namespace Cubed {
|
||||
class ServerWorld;
|
||||
class ServerEntityManager {
|
||||
public:
|
||||
ServerEntityManager(ServerWorld& world);
|
||||
|
||||
void init();
|
||||
// not thread safe
|
||||
void add_entity(std::string_view name, const glm::vec3& pos);
|
||||
|
||||
private:
|
||||
using EntityMap = tbb::concurrent_hash_map<EntityID, entt::entity>;
|
||||
using acc = EntityMap::accessor;
|
||||
using cacc = EntityMap::const_accessor;
|
||||
using CreateFunc = std::function<EntityID()>;
|
||||
ServerWorld& m_world;
|
||||
entt::registry m_registry;
|
||||
EntityID m_next = 0;
|
||||
EntityMap m_entities;
|
||||
std::unordered_map<std::string_view, CreateFunc> m_factories;
|
||||
|
||||
void send_entity_create(EntityID id, std::string_view name,
|
||||
const glm::vec3& pos);
|
||||
|
||||
template <typename... Args> EntityID add_entity(Args&&... args) {
|
||||
auto entity = m_registry.create();
|
||||
|
||||
((m_registry.emplace<std::remove_cvref_t<Args>>(
|
||||
entity, std::forward<Args>(args))),
|
||||
...);
|
||||
auto id = m_next++;
|
||||
m_entities.emplace(id, entity);
|
||||
return id;
|
||||
}
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Cubed/gameplay/packet.hpp" // IWYU pragma: keep
|
||||
#include "Cubed/gameplay/river_worm.hpp"
|
||||
#include "Cubed/gameplay/server_chunk.hpp"
|
||||
#include "Cubed/gameplay/server_entity_manager.hpp"
|
||||
#include "Cubed/gameplay/server_player.hpp"
|
||||
#include "Cubed/gameplay/world.hpp"
|
||||
#include "Cubed/tools/priority_thread_pool.hpp"
|
||||
@@ -87,6 +88,8 @@ public:
|
||||
void handle_voice_message(VoiceMsg& msg);
|
||||
int chunk_size() const;
|
||||
|
||||
std::vector<std::shared_ptr<Session>> get_all_session() const;
|
||||
|
||||
int get_block(const glm::ivec3& block_pos) const override;
|
||||
bool is_solid(const glm::ivec3& block_pos) const override;
|
||||
bool can_pass_block(const glm::ivec3& block_pos) const override;
|
||||
@@ -132,7 +135,7 @@ private:
|
||||
using uuid_cacc = PlayerUUIDMap::const_accessor;
|
||||
|
||||
Config& m_config;
|
||||
|
||||
ServerEntityManager m_entity_manager;
|
||||
// key = uuid
|
||||
PlayerHashMap m_players;
|
||||
ChunkHashMap m_chunks;
|
||||
@@ -162,7 +165,7 @@ private:
|
||||
std::atomic<bool> m_tick_running{true};
|
||||
std::atomic<int> m_per_tick_time = DEFAULT_PER_TICK_TIME; // ms
|
||||
|
||||
mutable std::shared_mutex m_player_mutex;
|
||||
mutable std::shared_mutex m_players_mutex;
|
||||
std::mutex m_need_gen_queue_mutex;
|
||||
std::condition_variable_any m_gen_cv;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#include "Cubed//gameplay/ecs/server_entity.hpp"
|
||||
#include "Cubed/gameplay/ecs/movement.hpp"
|
||||
#include "Cubed/gameplay/ecs/state.hpp"
|
||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||
#include "Cubed/gameplay/world.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
@@ -7,10 +9,6 @@ class PhysicalSystem {
|
||||
public:
|
||||
static glm::vec3 get_move_distance(float dt, const Direction& d,
|
||||
const Velocity& v);
|
||||
static std::tuple<bool, bool, bool> update(float dt, ServerEntity& e,
|
||||
World& world);
|
||||
static std::tuple<bool, bool, bool>
|
||||
update(float dt, ServerEntity& e, World& world, glm::vec3& moved_pos);
|
||||
|
||||
static std::tuple<bool, bool, bool>
|
||||
update(float dt, World& world, glm::vec3& moved_pos, Velocity& v,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/ecs/server_entity.hpp"
|
||||
#include "Cubed/gameplay/ecs/movement.hpp"
|
||||
#include "Cubed/gameplay/ecs/state.hpp"
|
||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||
|
||||
namespace Cubed {
|
||||
class SpeedSystem {
|
||||
public:
|
||||
static void update(float dt, ServerEntity& e);
|
||||
static void update(float dt, Velocity& v, MoveState& move_state,
|
||||
Movement& movement, Direction& direction,
|
||||
const Gravity& g);
|
||||
|
||||
7
include/Cubed/tools/cubed_concepts.hpp
Normal file
7
include/Cubed/tools/cubed_concepts.hpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
namespace Cubed {
|
||||
template <typename T>
|
||||
concept Ptr = std::is_pointer_v<T>;
|
||||
}
|
||||
15
include/Cubed/tools/net_utils.hpp
Normal file
15
include/Cubed/tools/net_utils.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/tools/cubed_concepts.hpp"
|
||||
#include "common/vector3.pb.h"
|
||||
#include "glm/ext/vector_float3.hpp"
|
||||
namespace Cubed {
|
||||
namespace Tools {
|
||||
template <Ptr T> void set_net_pos(T ptr, const glm::vec3& pos) {
|
||||
Vec3* p = ptr->mutable_pos();
|
||||
p->set_x(pos.x);
|
||||
p->set_y(pos.y);
|
||||
p->set_z(pos.z);
|
||||
}
|
||||
} // namespace Tools
|
||||
} // namespace Cubed
|
||||
Reference in New Issue
Block a user