mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(gameplay): integrate network client and thread-safe player pos
This commit is contained in:
@@ -8,18 +8,20 @@
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
namespace Cubed {
|
||||
enum class Gait { WALK = 0, RUN };
|
||||
class ClientWorld;
|
||||
class ClientPlayer {
|
||||
public:
|
||||
ClientPlayer(ClientWorld& world, const std::string& name);
|
||||
ClientPlayer(ClientWorld& world, std::string_view name);
|
||||
~ClientPlayer();
|
||||
AABB get_aabb() const;
|
||||
const glm::vec3& get_front() const;
|
||||
const Gait& get_gait() const;
|
||||
const std::optional<LookBlock>& get_look_block_pos() const;
|
||||
const glm::vec3& get_player_pos() const;
|
||||
// thread safe
|
||||
glm::vec3 get_player_pos() const;
|
||||
const MoveState& get_move_state() const;
|
||||
|
||||
void change_mode(GameMode mode);
|
||||
@@ -48,6 +50,7 @@ public:
|
||||
|
||||
void set_uuid(std::string_view uuid);
|
||||
const std::string& get_uuid() const;
|
||||
const std::string& get_name() const;
|
||||
|
||||
private:
|
||||
using enum GameMode;
|
||||
@@ -94,6 +97,9 @@ private:
|
||||
std::string m_name{};
|
||||
std::string m_uuid;
|
||||
ClientWorld& m_world;
|
||||
|
||||
std::shared_mutex m_player_pos_mutex;
|
||||
|
||||
bool ray_cast(const glm::vec3& start, const glm::vec3& dir,
|
||||
glm::ivec3& block_pos, glm::vec3& normal,
|
||||
float distance = 4.0f);
|
||||
@@ -101,8 +107,8 @@ private:
|
||||
void update_direction();
|
||||
void update_lookup_block();
|
||||
void update_move(float delta_time);
|
||||
void update_x_move();
|
||||
void update_y_move();
|
||||
void update_z_move();
|
||||
void update_x_move(glm::vec3& player_pos);
|
||||
void update_y_move(glm::vec3& player_pos);
|
||||
void update_z_move(glm::vec3& player_pos);
|
||||
};
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/client_chunk.hpp"
|
||||
#include "Cubed/gameplay/client_player.hpp"
|
||||
#include "Cubed/gameplay/game_time.hpp"
|
||||
#include "Cubed/gameplay/network_client.hpp"
|
||||
|
||||
#include <deque>
|
||||
#include <tbb/concurrent_unordered_map.h>
|
||||
@@ -11,7 +13,8 @@ namespace Cubed {
|
||||
|
||||
class ClientWorld {
|
||||
public:
|
||||
ClientWorld();
|
||||
ClientWorld(std::string_view player_name,
|
||||
std::shared_ptr<NetworkClient> client);
|
||||
~ClientWorld();
|
||||
void init();
|
||||
void update(float delta_time);
|
||||
@@ -32,16 +35,23 @@ public:
|
||||
|
||||
int rendering_distance() const;
|
||||
void rendering_distance(int rendering_distance);
|
||||
void start_client_thread();
|
||||
void start_client_thread(std::string_view uuid);
|
||||
void stop_client_thread();
|
||||
|
||||
std::vector<glm::vec4>& planes();
|
||||
std::vector<ChunkRenderSnapshot>& render_snapshots();
|
||||
glm::vec3 sunlight_dir() const;
|
||||
void receive_chunk(const ChunkDataRsp& data);
|
||||
template <typename Fn>
|
||||
void register_timer(std::string_view id, TickType 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:
|
||||
using ChunkHashMap =
|
||||
tbb::concurrent_unordered_map<ChunkPos, ClientChunk, ChunkPos::Hash>;
|
||||
using ChunkPosSet = std::unordered_set<ChunkPos, ChunkPos::Hash>;
|
||||
ClientPlayer m_player;
|
||||
ChunkHashMap m_chunks;
|
||||
std::vector<glm::vec4> m_planes;
|
||||
@@ -50,10 +60,23 @@ private:
|
||||
mutable std::shared_mutex m_chunks_mutex;
|
||||
std::mutex m_delete_vbo_mutex;
|
||||
std::mutex m_delete_vao_mutex;
|
||||
std::mutex m_pending_queue_mutex;
|
||||
std::deque<ClientChunk> m_pending_queue;
|
||||
|
||||
std::vector<GLuint> m_pending_delete_vbo;
|
||||
std::vector<GLuint> m_pending_delete_vao;
|
||||
std::deque<ChunkPos> m_dirty_queue;
|
||||
std::vector<ChunkRenderSnapshot> m_render_snapshots;
|
||||
tbb::concurrent_unordered_map<std::string, Timer> m_timers;
|
||||
std::atomic<bool> m_game_running{false};
|
||||
std::atomic<int> m_rendering_distance{24};
|
||||
std::shared_ptr<NetworkClient> m_client;
|
||||
void client_run(std::stop_token token);
|
||||
|
||||
void set_player_pos();
|
||||
|
||||
void report_player_pos();
|
||||
|
||||
void request_chunk();
|
||||
};
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -1,10 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
// Prevent unsigned underflow issues in subtraction
|
||||
#include "Cubed/tools/cubed_assert.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
namespace Cubed {
|
||||
using TickType = long long;
|
||||
|
||||
constexpr int DEFAULT_PER_TICK_TIME = 50;
|
||||
|
||||
constexpr TickType DAY_TIME = 24000;
|
||||
|
||||
constexpr TickType PER_HOUR = 1000;
|
||||
constexpr TickType PER_HOUR = 1000;
|
||||
|
||||
class Timer {
|
||||
public:
|
||||
template <typename Fn>
|
||||
Timer(TickType threshold, Fn&& f)
|
||||
: m_fn(std::forward<Fn>(f)), m_threshold(threshold) {
|
||||
ASSERT_MSG(threshold > 0, "Threshold Must Rreater Than 0");
|
||||
}
|
||||
bool update() {
|
||||
if (++m_current >= m_threshold) {
|
||||
m_current = 0;
|
||||
m_fn();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void reset() { m_current = 0; }
|
||||
|
||||
private:
|
||||
std::function<void()> m_fn;
|
||||
TickType m_threshold;
|
||||
TickType m_current = 0;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
#include <thread>
|
||||
namespace Cubed {
|
||||
using asio::ip::tcp;
|
||||
class ClientWorld;
|
||||
class NetworkClient : std::enable_shared_from_this<NetworkClient> {
|
||||
public:
|
||||
NetworkClient();
|
||||
NetworkClient(ClientWorld& world);
|
||||
~NetworkClient();
|
||||
void close();
|
||||
asio::awaitable<void> connect(std::string ip, int port);
|
||||
@@ -29,7 +30,7 @@ private:
|
||||
std::atomic<bool> m_closed{false};
|
||||
|
||||
// ClientWorld is managed by App
|
||||
// ClientWorld& m_world;
|
||||
ClientWorld& m_world;
|
||||
|
||||
void do_write();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user