feat(gameplay): add run mode based thread pool config

Introduce RunMode enum and thread pool sizing helpers for client,
server, and hybrid modes. Add compute pool to server world and pass
mode through server/client initialization.
This commit is contained in:
2026-08-05 19:49:06 +08:00
parent 8ff789c576
commit 2aa9d07e43
9 changed files with 202 additions and 37 deletions

View File

@@ -6,6 +6,7 @@
#include "Cubed/gameplay/game_time.hpp"
#include "Cubed/gameplay/packet.hpp"
#include "Cubed/scene/world_scene.hpp"
#include "Cubed/tools/threas_utils.hpp"
#include "Cubed/tools/time_tools.hpp"
#include <absl/container/inlined_vector.h>
@@ -363,7 +364,8 @@ void ClientWorld::send_player_water_sound(bool underwater,
}
void ClientWorld::init(std::string_view player_name,
std::shared_ptr<NetworkClient> client) {
std::shared_ptr<NetworkClient> client, RunMode mode) {
m_runmode = mode;
m_entity_manager.init();
m_player_manager.init(player_name);
m_client = client;
@@ -480,8 +482,8 @@ void ClientWorld::stop_client_thread() {
m_game_running = false;
}
void ClientWorld::start_thread_pool() {
int max_threads = std::thread::hardware_concurrency();
int threads = std::min<size_t>(max_threads, 4);
auto threads = Tools::get_client_threads(m_runmode);
Logger::info("Client pool threads {}", threads);
change_pool_threads(threads);
}
void ClientWorld::stop_thread_pool() {
@@ -500,7 +502,6 @@ void ClientWorld::change_pool_threads(int threads) {
m_max_threads = 1;
}
int used_thread = std::clamp(threads, 1, m_max_threads);
Logger::info("Create New Thread Pool Use {} Threads", used_thread);
m_thread_pool.store(std::make_shared<PriorityThreadPool>(used_thread));
}

View File

@@ -92,14 +92,10 @@ void NetworkServer::net_run() {
Logger::info("Server Started!");
}
void NetworkServer::start_server(int port) {
void NetworkServer::start_server(int port, RunMode mode) {
m_port = port;
m_config.set("port", m_port);
start_server();
}
void NetworkServer::start_server() {
m_world.init_world();
m_world.init_world(mode);
net_run();
m_started = true;
}

View File

@@ -7,6 +7,7 @@
#include "Cubed/tools/log.hpp"
#include "Cubed/tools/math_tools.hpp"
#include "Cubed/tools/net_utils.hpp"
#include "Cubed/tools/threas_utils.hpp"
#include "Cubed/tools/uuid.hpp"
#include <ranges>
@@ -178,8 +179,8 @@ void ServerWorld::send_chunk(int task_id, const std::string& uuid,
s->send(make_packet(*rsp));
}
void ServerWorld::init_world() {
void ServerWorld::init_world(RunMode mode) {
m_runmode = mode;
m_entity_manager.init();
m_entity_manager.add_entity("cubed:pig", {0, 225, 0});
register_timer("player disconnect", 5, [this]() {
@@ -361,7 +362,7 @@ void ServerWorld::submit_new_chunks(const std::string& uuid,
return dist2(a.first) < dist2(b.first);
});
const int CHUNKS_PER_PRIORITY = m_gen_pool_threads;
const int CHUNKS_PER_PRIORITY = m_gen_threads;
for (size_t i = 0; i < tasks.size(); ++i) {
int priority = 10 + static_cast<int>(i / CHUNKS_PER_PRIORITY);
@@ -411,20 +412,30 @@ void ServerWorld::start_server_thread() {
}
void ServerWorld::start_thread_pool() {
int max_thread = std::thread::hardware_concurrency();
if (m_gen_pool_threads == 0) {
m_gen_pool_threads = change_pool_threads(m_gen_thread_pool,
max_thread - RESERVED_THREADS);
if (m_gen_threads == 0) {
auto gen_threads = Tools::get_server_gen_threads(m_runmode);
Logger::info("Server Gen pool threads {}", gen_threads);
m_gen_threads = change_pool_threads(m_gen_thread_pool, gen_threads);
} else {
m_gen_pool_threads =
change_pool_threads(m_gen_thread_pool, m_gen_pool_threads);
m_gen_threads = change_pool_threads(m_gen_thread_pool, m_gen_threads);
}
if (m_net_pool_threads == 0) {
m_net_pool_threads = change_pool_threads(m_net_thread_pool, 4);
if (m_net_threads == 0) {
auto net_threads = Tools::get_server_net_pool_threads(m_runmode);
Logger::info("Server Net pool threads {}", net_threads);
m_net_threads = change_pool_threads(m_net_thread_pool, net_threads);
} else {
m_net_pool_threads =
change_pool_threads(m_net_thread_pool, m_net_pool_threads);
m_net_threads = change_pool_threads(m_net_thread_pool, m_net_threads);
}
if (m_compute_threads == 0) {
auto compute_threads = Tools::get_server_compute_treads(m_runmode);
Logger::info("Server compute pool threads {}", compute_threads);
m_compute_threads =
change_pool_threads(m_compute_thread_pool, compute_threads);
} else {
m_compute_threads =
change_pool_threads(m_compute_thread_pool, m_compute_threads);
}
}
@@ -459,6 +470,13 @@ void ServerWorld::stop_thread_pool() {
}
m_net_thread_pool.store(nullptr);
Logger::info("Net Thread Pool Stopped");
auto c = m_compute_thread_pool.load();
if (c) {
c->stop();
}
m_compute_thread_pool.store(nullptr);
Logger::info("Compute Thread Pool Stopped");
}
void ServerWorld::serever_run(std::stop_token stoken) {
@@ -910,16 +928,16 @@ void ServerWorld::per_tick_time(int ms) { m_per_tick_time = ms; }
bool ServerWorld::is_tick_running() const { return m_tick_running.load(); }
void ServerWorld::tick_running(bool run) { m_tick_running = run; }
int ServerWorld::gen_pool_threads() const { return m_gen_pool_threads.load(); }
int ServerWorld::gen_pool_threads() const { return m_gen_threads.load(); }
int ServerWorld::max_threads() const { return m_max_threads.load(); }
void ServerWorld::change_pool_threads(ThreadPoolKind kind, int threads) {
switch (kind) {
case ThreadPoolKind::NET:
m_net_pool_threads = change_pool_threads(m_net_thread_pool, threads);
m_net_threads = change_pool_threads(m_net_thread_pool, threads);
break;
case ThreadPoolKind::GEN:
m_gen_pool_threads = change_pool_threads(m_gen_thread_pool, threads);
m_gen_threads = change_pool_threads(m_gen_thread_pool, threads);
break;
}
}
@@ -946,7 +964,6 @@ int ServerWorld::change_pool_threads(
m_max_threads = 1;
}
int used_thread = std::clamp(threads, 1, m_max_threads.load());
Logger::info("Create New Thread Pool Use {} Threads", used_thread);
thread_pool.store(std::make_shared<PriorityThreadPool>(used_thread));
return used_thread;
}
@@ -1115,4 +1132,7 @@ BlockType ServerWorld::get_block_tpye(const glm::ivec3& block_pos) const {
int ServerWorld::get_per_tick_time() const { return m_per_tick_time; }
ServerEntityManager& ServerWorld::entity_manager() { return m_entity_manager; }
std::shared_ptr<ThreadPool> ServerWorld::get_compute_pool() {
return m_compute_thread_pool.load();
}
} // namespace Cubed

View File

@@ -129,10 +129,21 @@ void WorldScene::on_enter() {
load_config();
m_error_ui.init();
m_client = std::make_shared<NetworkClient>(m_client_world);
RunMode mode = RunMode::HYBRID;
if (m_argument.direct_enter) {
if (m_argument.ip) {
mode = RunMode::CLIENT_ONLY;
}
} else {
if (!m_scene_manager.world_scene_param().host_game) {
mode = RunMode::CLIENT_ONLY;
}
}
if (m_argument.direct_enter) {
if (!m_argument.ip) {
ChunkGenerator::init();
m_server.start_server(*m_argument.port);
m_server.start_server(*m_argument.port, mode);
m_client->start("127.0.0.1", *m_argument.port);
} else {
m_client->start(*m_argument.ip, *m_argument.port);
@@ -148,7 +159,7 @@ void WorldScene::on_enter() {
} else {
ChunkGenerator::init();
}
m_server.start_server(param.port);
m_server.start_server(param.port, mode);
}
m_client->start(param.ip, param.port);
@@ -157,7 +168,8 @@ void WorldScene::on_enter() {
// init will send packet
try {
m_client_world.init(m_argument.player.value_or("Unknown"), m_client);
m_client_world.init(m_argument.player.value_or("Unknown"), m_client,
mode);
Logger::info("World Init Success");
m_camera.camera_init(&m_client_world.get_player());