mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 09:47:01 +08:00
refactor(gameplay): replace client thread with timer-based system and add entity manager
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "Cubed/gameplay/chat_message.hpp"
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/client_chunk.hpp"
|
||||
#include "Cubed/gameplay/client_entity_manager.hpp"
|
||||
#include "Cubed/gameplay/client_player_manager.hpp"
|
||||
#include "Cubed/gameplay/game_time.hpp"
|
||||
#include "Cubed/gameplay/local_player.hpp"
|
||||
@@ -84,6 +85,7 @@ public:
|
||||
Config& get_config();
|
||||
WorldScene& world_scene();
|
||||
ClientPlayerManager& player_manager();
|
||||
ClientEntityManager& entity_manager();
|
||||
void set_direct_exit();
|
||||
|
||||
void receive_chat_message(ChatMsg& msg);
|
||||
@@ -92,10 +94,10 @@ public:
|
||||
bool enable_voice_chat() const;
|
||||
int get_per_tick_time() const override;
|
||||
template <typename Fn>
|
||||
void register_ticktimer(std::string_view id, TickType threshold, Fn&& f) {
|
||||
m_ticktimers.emplace(
|
||||
std::piecewise_construct, std::forward_as_tuple(std::string(id)),
|
||||
std::forward_as_tuple(threshold, std::forward<Fn>(f)));
|
||||
void register_timer(std::string_view id, float threshold, Fn&& f) {
|
||||
m_timers.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(std::string(id)),
|
||||
std::forward_as_tuple(threshold, std::forward<Fn>(f)));
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -126,14 +128,13 @@ private:
|
||||
|
||||
static constexpr int WORLD_EXIT_TIMEOUT = 200;
|
||||
static constexpr int MAX_UPLOAD_CHUNK_SUM = 16;
|
||||
|
||||
ClientEntityManager m_entity_manager;
|
||||
ClientPlayerManager m_player_manager;
|
||||
ChunkHashMap m_chunks;
|
||||
AudioEngine& m_audio;
|
||||
Config& m_config;
|
||||
WorldScene& m_world_scene;
|
||||
std::vector<glm::vec4> m_planes;
|
||||
std::jthread m_client_thread;
|
||||
|
||||
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
|
||||
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
|
||||
@@ -144,7 +145,6 @@ private:
|
||||
std::deque<ChunkPos> m_dirty_queue;
|
||||
std::vector<const ChunkRenderSnapshot*> m_render_snapshots;
|
||||
|
||||
tbb::concurrent_unordered_map<std::string, TickTimer> m_ticktimers;
|
||||
std::unordered_map<std::string, Timer> m_timers;
|
||||
std::atomic<bool> m_exit_direct{false};
|
||||
std::atomic<bool> m_game_running{false};
|
||||
@@ -164,8 +164,6 @@ private:
|
||||
|
||||
Random m_random;
|
||||
|
||||
void client_run(std::stop_token token);
|
||||
|
||||
void set_block(const glm::ivec3& pos, unsigned id);
|
||||
|
||||
void update_chunk(const ChunkPosSet& old, const ChunkPosSet& now);
|
||||
|
||||
@@ -60,8 +60,8 @@ 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,
|
||||
S2C_ENTITY_CREATE = 3007,
|
||||
CHAT_MSG = 4001,
|
||||
VOICE_MSG = 4002,
|
||||
PING = 9001,
|
||||
|
||||
@@ -23,8 +23,8 @@ struct ChunkRenderData {
|
||||
} // namespace
|
||||
|
||||
ClientWorld::ClientWorld(AudioEngine& auido, Config& config, WorldScene& scene)
|
||||
: m_player_manager(*this), m_audio(auido), m_config(config),
|
||||
m_world_scene(scene) {}
|
||||
: m_entity_manager(*this), m_player_manager(*this), m_audio(auido),
|
||||
m_config(config), m_world_scene(scene) {}
|
||||
|
||||
ClientWorld::~ClientWorld() {
|
||||
m_client->close();
|
||||
@@ -51,7 +51,7 @@ ClientWorld::~ClientWorld() {
|
||||
std::lock_guard lk(m_delete_vao_mutex);
|
||||
m_pending_delete_vao.clear();
|
||||
}
|
||||
m_ticktimers.clear();
|
||||
m_timers.clear();
|
||||
}
|
||||
|
||||
const std::optional<LookBlock>& ClientWorld::get_look_block_pos() const {
|
||||
@@ -363,6 +363,7 @@ void ClientWorld::send_player_water_sound(bool underwater,
|
||||
|
||||
void ClientWorld::init(std::string_view player_name,
|
||||
std::shared_ptr<NetworkClient> client) {
|
||||
m_entity_manager.init();
|
||||
m_player_manager.init(player_name);
|
||||
m_client = client;
|
||||
|
||||
@@ -371,10 +372,10 @@ void ClientWorld::init(std::string_view player_name,
|
||||
m_random.init(ChunkGenerator::seed());
|
||||
|
||||
// timer
|
||||
register_ticktimer("player_pos", 1, [this]() {
|
||||
register_timer("player_pos", 0.05f, [this]() {
|
||||
m_player_manager.report_player_info(m_client.get());
|
||||
});
|
||||
m_timers.try_emplace("Birds Sound", 60.0f, [this]() {
|
||||
register_timer("Birds Sound", 60.0f, [this]() {
|
||||
auto player_pos = m_player_manager.get_local().get_player_pos();
|
||||
if (player_pos.y < SEA_LEVEL) {
|
||||
return;
|
||||
@@ -390,7 +391,7 @@ void ClientWorld::init(std::string_view player_name,
|
||||
}
|
||||
});
|
||||
|
||||
m_timers.try_emplace("Ocean Wave", 3.0f, [this]() {
|
||||
register_timer("Ocean Wave", 3.0f, [this]() {
|
||||
auto player_pos = m_player_manager.get_local().get_player_pos();
|
||||
if (player_pos.y < SEA_LEVEL - 10 || player_pos.y > SEA_LEVEL + 10) {
|
||||
return;
|
||||
@@ -410,7 +411,7 @@ void ClientWorld::init(std::string_view player_name,
|
||||
}
|
||||
});
|
||||
|
||||
m_timers.try_emplace("under water bubble", 1.5f, [this]() {
|
||||
register_timer("under water bubble", 1.5f, [this]() {
|
||||
if (m_player_manager.get_local().is_underwater()) {
|
||||
auto ans = m_random.random_int(1, 2);
|
||||
std::string sound =
|
||||
@@ -420,7 +421,7 @@ void ClientWorld::init(std::string_view player_name,
|
||||
}
|
||||
});
|
||||
|
||||
m_timers.try_emplace("bgm change", 350.0f, [this]() {
|
||||
register_timer("bgm change", 350.0f, [this]() {
|
||||
if (m_day_tick >= 17000 || m_day_tick < 5000) {
|
||||
m_audio.change_bgm("bgm/bgm002.ogg");
|
||||
} else {
|
||||
@@ -455,11 +456,11 @@ void ClientWorld::start_client_thread(std::string_view uuid) {
|
||||
}
|
||||
// response
|
||||
m_player_manager.get_local().set_uuid(uuid);
|
||||
|
||||
/*
|
||||
m_client_thread = std::jthread([this](std::stop_token token) {
|
||||
m_game_running = true;
|
||||
client_run(token);
|
||||
});
|
||||
});*/
|
||||
|
||||
// Wait for 20 ticks, after the server's central chunk is generated, then
|
||||
// request chunks
|
||||
@@ -470,10 +471,11 @@ void ClientWorld::start_client_thread(std::string_view uuid) {
|
||||
}
|
||||
|
||||
void ClientWorld::stop_client_thread() {
|
||||
/*
|
||||
m_client_thread.request_stop();
|
||||
if (m_client_thread.joinable()) {
|
||||
m_client_thread.join();
|
||||
}
|
||||
}*/
|
||||
m_game_running = false;
|
||||
}
|
||||
void ClientWorld::start_thread_pool() {
|
||||
@@ -512,6 +514,7 @@ void ClientWorld::reload_config(bool chunk_build) {
|
||||
m_player_manager.reload_config();
|
||||
}
|
||||
|
||||
/*
|
||||
void ClientWorld::client_run(std::stop_token stoken) {
|
||||
Logger::info("Client Thread Started");
|
||||
using Clock = std::chrono::steady_clock;
|
||||
@@ -527,6 +530,7 @@ void ClientWorld::client_run(std::stop_token stoken) {
|
||||
std::this_thread::sleep_until(next);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void ClientWorld::update_chunk(const ChunkPosSet& old, const ChunkPosSet& now) {
|
||||
|
||||
@@ -677,6 +681,7 @@ const AudioEngine& ClientWorld::get_audio() const { return m_audio; }
|
||||
Config& ClientWorld::get_config() { return m_config; }
|
||||
WorldScene& ClientWorld::world_scene() { return m_world_scene; }
|
||||
ClientPlayerManager& ClientWorld::player_manager() { return m_player_manager; }
|
||||
ClientEntityManager& ClientWorld::entity_manager() { return m_entity_manager; }
|
||||
void ClientWorld::set_direct_exit() { m_exit_direct = true; }
|
||||
void ClientWorld::request_exit() {
|
||||
if (m_receive_exit) {
|
||||
|
||||
@@ -142,7 +142,13 @@ asio::awaitable<void> NetworkClient::read_loop() {
|
||||
if (decode_packet(*msg, body_data, header)) {
|
||||
m_world.receive_voice_message(*msg);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case std::to_underlying(PacketEnum::S2C_ENTITY_CREATE): {
|
||||
auto* msg = Arena::Create<S2CEntityCreate>(&arena);
|
||||
if (decode_packet(*msg, body_data, header)) {
|
||||
m_world.entity_manager().receive_entity_create(*msg);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
} catch (const asio::system_error& e) {
|
||||
|
||||
Reference in New Issue
Block a user