mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
refactor: config (#30)
* refactor(config): replace singleton with dependency injection * refactor(client_player): return ChunkPosSet by value in non-const getter Copy the internal set under the mutex lock to avoid exposing a mutable reference that could be used unsafely after the lock is released. This fixes a potential data race when the caller holds the returned reference beyond the critical section. Also update the caller in `client_world` to remove the now-unnecessary `std::move`. * fix(gameplay): prevent use-after-free in pending delete queues during destruction * refactor(config): separate game and server configuration with explicit paths
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -41,6 +41,7 @@ CMakeError.log
|
|||||||
*~
|
*~
|
||||||
.DS_Store
|
.DS_Store
|
||||||
assets/config.toml
|
assets/config.toml
|
||||||
|
assets/server-config.toml
|
||||||
.venv/
|
.venv/
|
||||||
pyout/
|
pyout/
|
||||||
vcpkg_installed/
|
vcpkg_installed/
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "Cubed/gameplay/server_world.hpp"
|
#include "Cubed/gameplay/server_world.hpp"
|
||||||
#define GLFW_INCLUDE_NONE
|
#define GLFW_INCLUDE_NONE
|
||||||
#include "Cubed/camera.hpp"
|
#include "Cubed/camera.hpp"
|
||||||
|
#include "Cubed/config.hpp"
|
||||||
#include "Cubed/dev_panel.hpp"
|
#include "Cubed/dev_panel.hpp"
|
||||||
#include "Cubed/render/renderer.hpp"
|
#include "Cubed/render/renderer.hpp"
|
||||||
#include "Cubed/texture_manager.hpp"
|
#include "Cubed/texture_manager.hpp"
|
||||||
@@ -49,23 +50,23 @@ public:
|
|||||||
Window& window();
|
Window& window();
|
||||||
ClientWorld& client_world();
|
ClientWorld& client_world();
|
||||||
ServerWorld& server_world();
|
ServerWorld& server_world();
|
||||||
|
Config& config();
|
||||||
const Argument& argument() const;
|
const Argument& argument() const;
|
||||||
AudioEngine& audio();
|
AudioEngine& audio();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Config m_game_config;
|
||||||
Camera m_camera;
|
Camera m_camera;
|
||||||
TextureManager m_texture_manager;
|
TextureManager m_texture_manager;
|
||||||
NetworkServer m_server;
|
NetworkServer m_server;
|
||||||
std::shared_ptr<NetworkClient> m_client;
|
std::shared_ptr<NetworkClient> m_client;
|
||||||
|
AudioEngine m_audio;
|
||||||
ClientWorld m_client_world;
|
ClientWorld m_client_world;
|
||||||
|
|
||||||
DevPanel m_dev_panel{*this};
|
DevPanel m_dev_panel;
|
||||||
Renderer m_renderer{m_camera, m_client_world, m_texture_manager,
|
Renderer m_renderer;
|
||||||
m_dev_panel};
|
|
||||||
|
|
||||||
Window m_window{m_renderer};
|
Window m_window;
|
||||||
|
|
||||||
AudioEngine m_audio;
|
|
||||||
|
|
||||||
inline static double last_time = glfwGetTime();
|
inline static double last_time = glfwGetTime();
|
||||||
inline static double current_time = glfwGetTime();
|
inline static double current_time = glfwGetTime();
|
||||||
@@ -74,6 +75,7 @@ private:
|
|||||||
inline static int frame_count = 0;
|
inline static int frame_count = 0;
|
||||||
inline static int fps = 0;
|
inline static int fps = 0;
|
||||||
Argument m_argument;
|
Argument m_argument;
|
||||||
|
|
||||||
void init(int argc, char** argv);
|
void init(int argc, char** argv);
|
||||||
void handle_argument(int argc, char** argv);
|
void handle_argument(int argc, char** argv);
|
||||||
void handle_toml();
|
void handle_toml();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "Cubed/audio/audio_source.hpp"
|
#include "Cubed/audio/audio_source.hpp"
|
||||||
#include "Cubed/audio/sound_manager.hpp"
|
#include "Cubed/audio/sound_manager.hpp"
|
||||||
#include "Cubed/audio/source_pool.hpp"
|
#include "Cubed/audio/source_pool.hpp"
|
||||||
|
#include "Cubed/config.hpp"
|
||||||
|
|
||||||
#include <AL/al.h>
|
#include <AL/al.h>
|
||||||
#include <AL/alc.h>
|
#include <AL/alc.h>
|
||||||
@@ -17,7 +18,7 @@ class ClientWorld;
|
|||||||
|
|
||||||
class AudioEngine {
|
class AudioEngine {
|
||||||
public:
|
public:
|
||||||
AudioEngine();
|
AudioEngine(Config& config);
|
||||||
AudioEngine(const AudioEngine&) = delete;
|
AudioEngine(const AudioEngine&) = delete;
|
||||||
AudioEngine(AudioEngine&&) = delete;
|
AudioEngine(AudioEngine&&) = delete;
|
||||||
AudioEngine& operator=(const AudioEngine&) = delete;
|
AudioEngine& operator=(const AudioEngine&) = delete;
|
||||||
@@ -48,6 +49,7 @@ private:
|
|||||||
std::unique_ptr<AudioSource> m_bgm;
|
std::unique_ptr<AudioSource> m_bgm;
|
||||||
FadeMap m_fade_map;
|
FadeMap m_fade_map;
|
||||||
SoundManager m_sounds;
|
SoundManager m_sounds;
|
||||||
|
Config& m_config;
|
||||||
std::shared_ptr<SourcePool> m_pool;
|
std::shared_ptr<SourcePool> m_pool;
|
||||||
bool m_efx_supported = false;
|
bool m_efx_supported = false;
|
||||||
bool m_underwater = false;
|
bool m_underwater = false;
|
||||||
|
|||||||
@@ -1,99 +1,75 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Cubed/tools/cubed_assert.hpp"
|
|
||||||
#include "Cubed/tools/toml.utils.hpp"
|
#include "Cubed/tools/toml.utils.hpp"
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
class Config {
|
class Config {
|
||||||
public:
|
public:
|
||||||
Config();
|
explicit Config(std::string_view path);
|
||||||
|
Config(const Config&) = delete;
|
||||||
|
Config(Config&&) = delete;
|
||||||
|
Config& operator=(const Config&) = delete;
|
||||||
|
Config& operator=(Config&&) = delete;
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
static Config& get();
|
|
||||||
|
|
||||||
toml::table& table();
|
toml::table& table();
|
||||||
|
|
||||||
void load_or_create_config();
|
void load_config();
|
||||||
void save_to_file();
|
void save_to_file();
|
||||||
|
|
||||||
template <TOML::TomlValueType T> T get(std::string_view key) const {
|
template <TOML::TomlValueType T>
|
||||||
size_t cur = 0;
|
T get(std::string_view key, T default_value) {
|
||||||
auto pos = key.find('.');
|
if (auto* node = find_node(m_tbl, key)) {
|
||||||
const toml::table* table = &m_tbl;
|
if (auto value = node->value<T>())
|
||||||
while (pos != std::string_view::npos) {
|
return *value;
|
||||||
std::string_view s = key.substr(cur, pos - cur);
|
|
||||||
if (s.empty()) {
|
|
||||||
Logger::error("Empty key/table name in path '{}'", key);
|
|
||||||
ASSERT(false);
|
|
||||||
std::abort();
|
|
||||||
}
|
}
|
||||||
cur = pos + 1;
|
|
||||||
pos = key.find('.', cur);
|
set(key, default_value);
|
||||||
if (auto* next = (*table)[s].as_table()) {
|
save_to_file();
|
||||||
table = next;
|
|
||||||
|
return default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <TOML::TomlValueType T> void set(std::string_view key, T&& value) {
|
||||||
|
auto pos = key.rfind('.');
|
||||||
|
|
||||||
|
toml::table* table;
|
||||||
|
std::string_view name;
|
||||||
|
|
||||||
|
if (pos == std::string_view::npos) {
|
||||||
|
table = &m_tbl;
|
||||||
|
name = key;
|
||||||
} else {
|
} else {
|
||||||
Logger::error("Can't find table {}", s);
|
table = find_or_create_table(key.substr(0, pos));
|
||||||
ASSERT(false);
|
name = key.substr(pos + 1);
|
||||||
std::abort();
|
|
||||||
}
|
}
|
||||||
|
// Insert node at the last level's table
|
||||||
|
table->insert_or_assign(name, std::forward<T>(value));
|
||||||
}
|
}
|
||||||
std::string_view n_key = key.substr(cur);
|
|
||||||
if (n_key.empty()) {
|
|
||||||
Logger::error("Trailing dot in path '{}'", key);
|
|
||||||
ASSERT(false);
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
auto opt = (*table)[n_key].value<T>();
|
|
||||||
if (opt) {
|
|
||||||
return *opt;
|
|
||||||
} else {
|
|
||||||
Logger::error("Can't find key {}", n_key);
|
|
||||||
ASSERT(false);
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template <typename T> void set(std::string_view key, T&& val) {
|
|
||||||
if constexpr (!TOML::TomlValueType<std::decay_t<T>>) {
|
|
||||||
static_assert(false, "Type Not Support");
|
|
||||||
}
|
|
||||||
size_t cur = 0;
|
|
||||||
auto pos = key.find('.');
|
|
||||||
toml::table* table = &m_tbl;
|
|
||||||
while (pos != std::string_view::npos) {
|
|
||||||
std::string_view s = key.substr(cur, pos - cur);
|
|
||||||
if (s.empty()) {
|
|
||||||
Logger::error("Empty key/table name in path '{}'", key);
|
|
||||||
ASSERT(false);
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
cur = pos + 1;
|
|
||||||
pos = key.find('.', cur);
|
|
||||||
if (auto* next = (*table)[s].as_table()) {
|
|
||||||
table = next;
|
|
||||||
} else {
|
|
||||||
auto [it, inserted] = table->insert_or_assign(s, toml::table{});
|
|
||||||
table = it->second.as_table();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string_view n_key = key.substr(cur);
|
|
||||||
if (n_key.empty()) {
|
|
||||||
Logger::error("Trailing dot in path '{}'", key);
|
|
||||||
ASSERT(false);
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
table->insert_or_assign(n_key, std::forward<T>(val));
|
|
||||||
}
|
|
||||||
template <typename T> void set_and_save(std::string_view key, T&& val) {
|
template <typename T> void set_and_save(std::string_view key, T&& val) {
|
||||||
set(key, std::forward(val));
|
set(key, std::forward(val));
|
||||||
save_to_file();
|
save_to_file();
|
||||||
}
|
}
|
||||||
toml::node_view<toml::node> val_view(std::string_view key);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
toml::table m_tbl;
|
toml::table m_tbl;
|
||||||
constexpr static inline std::string_view CONGIF_PATH =
|
const std::string CONGIF_PATH;
|
||||||
ASSETS_PATH "config.toml";
|
const toml::node* find_node(const toml::table& root,
|
||||||
void create_config();
|
std::string_view path) const;
|
||||||
|
// Follow the path to find the last-level toml::table, creating it if it
|
||||||
|
// does not exist
|
||||||
|
toml::table* find_or_create_table(std::string_view path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline float Config::get(std::string_view key, float default_value) {
|
||||||
|
return static_cast<float>(
|
||||||
|
Config::get<double>(key, static_cast<double>(default_value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline void Config::set(std::string_view key, float&& value) {
|
||||||
|
Config::set<double>(key, static_cast<double>(value));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Cubed/config.hpp"
|
||||||
|
|
||||||
#include <toml++/toml.hpp>
|
#include <toml++/toml.hpp>
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
@@ -36,7 +38,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
App& m_app;
|
App& m_app;
|
||||||
ConfigView m_config;
|
Config& m_config;
|
||||||
|
ConfigView m_config_view;
|
||||||
ClientPlayer* m_player;
|
ClientPlayer* m_player;
|
||||||
PlayerProfile m_player_profile;
|
PlayerProfile m_player_profile;
|
||||||
bool m_need_save_config = false;
|
bool m_need_save_config = false;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public:
|
|||||||
|
|
||||||
void update_chunk_set(const ChunkPosSet& set);
|
void update_chunk_set(const ChunkPosSet& set);
|
||||||
const ChunkPosSet& get_chunk_pos_set() const;
|
const ChunkPosSet& get_chunk_pos_set() const;
|
||||||
ChunkPosSet& get_chunk_pos_set();
|
ChunkPosSet get_chunk_pos_set();
|
||||||
|
|
||||||
static AABB get_aabb(const glm::vec3& pos);
|
static AABB get_aabb(const glm::vec3& pos);
|
||||||
const glm::vec3& get_front() const;
|
const glm::vec3& get_front() const;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Cubed/audio/audio_engine.hpp"
|
#include "Cubed/audio/audio_engine.hpp"
|
||||||
|
#include "Cubed/config.hpp"
|
||||||
#include "Cubed/gameplay/block.hpp"
|
#include "Cubed/gameplay/block.hpp"
|
||||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||||
#include "Cubed/gameplay/client_chunk.hpp"
|
#include "Cubed/gameplay/client_chunk.hpp"
|
||||||
@@ -43,7 +44,7 @@ struct PlayerRenderData {
|
|||||||
|
|
||||||
class ClientWorld {
|
class ClientWorld {
|
||||||
public:
|
public:
|
||||||
ClientWorld(AudioEngine& auido);
|
ClientWorld(AudioEngine& auido, Config& config);
|
||||||
~ClientWorld();
|
~ClientWorld();
|
||||||
void init(std::string_view player_name,
|
void init(std::string_view player_name,
|
||||||
std::shared_ptr<NetworkClient> client);
|
std::shared_ptr<NetworkClient> client);
|
||||||
@@ -95,6 +96,7 @@ public:
|
|||||||
int chunk_size() const;
|
int chunk_size() const;
|
||||||
static AABB get_block_aabb(const glm::ivec3& pos);
|
static AABB get_block_aabb(const glm::ivec3& pos);
|
||||||
AudioEngine& get_audio();
|
AudioEngine& get_audio();
|
||||||
|
Config& get_config();
|
||||||
template <typename Fn>
|
template <typename Fn>
|
||||||
void register_ticktimer(std::string_view id, TickType threshold, Fn&& f) {
|
void register_ticktimer(std::string_view id, TickType threshold, Fn&& f) {
|
||||||
m_ticktimers.emplace(
|
m_ticktimers.emplace(
|
||||||
@@ -103,6 +105,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::atomic<bool> m_is_pending_delete_queue_free{false};
|
||||||
|
std::mutex m_delete_vbo_mutex;
|
||||||
|
std::mutex m_delete_vao_mutex;
|
||||||
|
std::vector<std::unique_ptr<VertexBuffer>> m_pending_delete_vbo;
|
||||||
|
std::vector<std::unique_ptr<VertexArray>> m_pending_delete_vao;
|
||||||
|
|
||||||
enum class ChunkLoadStyle { RANDOM, CENTER };
|
enum class ChunkLoadStyle { RANDOM, CENTER };
|
||||||
using ChunkHashMap =
|
using ChunkHashMap =
|
||||||
tbb::concurrent_hash_map<ChunkPos, std::shared_ptr<ClientChunk>,
|
tbb::concurrent_hash_map<ChunkPos, std::shared_ptr<ClientChunk>,
|
||||||
@@ -124,18 +132,15 @@ private:
|
|||||||
OtherPlayerHashMap m_player_info;
|
OtherPlayerHashMap m_player_info;
|
||||||
ChunkHashMap m_chunks;
|
ChunkHashMap m_chunks;
|
||||||
AudioEngine& m_audio;
|
AudioEngine& m_audio;
|
||||||
|
Config& m_config;
|
||||||
std::vector<glm::vec4> m_planes;
|
std::vector<glm::vec4> m_planes;
|
||||||
std::jthread m_client_thread;
|
std::jthread m_client_thread;
|
||||||
|
|
||||||
std::mutex m_delete_vbo_mutex;
|
|
||||||
std::mutex m_delete_vao_mutex;
|
|
||||||
mutable std::shared_mutex m_player_info_mutex;
|
mutable std::shared_mutex m_player_info_mutex;
|
||||||
|
|
||||||
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
|
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
|
||||||
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
|
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
|
||||||
tbb::concurrent_queue<PendingSound> m_pending_sound;
|
tbb::concurrent_queue<PendingSound> m_pending_sound;
|
||||||
std::vector<std::unique_ptr<VertexBuffer>> m_pending_delete_vbo;
|
|
||||||
std::vector<std::unique_ptr<VertexArray>> m_pending_delete_vao;
|
|
||||||
|
|
||||||
std::deque<ChunkPos> m_dirty_queue;
|
std::deque<ChunkPos> m_dirty_queue;
|
||||||
std::vector<const ChunkRenderSnapshot*> m_render_snapshots;
|
std::vector<const ChunkRenderSnapshot*> m_render_snapshots;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Cubed/config.hpp"
|
||||||
#include "Cubed/gameplay/server_world.hpp"
|
#include "Cubed/gameplay/server_world.hpp"
|
||||||
#include "Cubed/gameplay/session.hpp"
|
#include "Cubed/gameplay/session.hpp"
|
||||||
|
|
||||||
@@ -8,17 +9,19 @@ namespace Cubed {
|
|||||||
|
|
||||||
class NetworkServer {
|
class NetworkServer {
|
||||||
public:
|
public:
|
||||||
NetworkServer(int port = 25530);
|
explicit NetworkServer();
|
||||||
~NetworkServer();
|
~NetworkServer();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
// Run in another thread after initialization is complete
|
// Run in another thread after initialization is complete
|
||||||
void start_server(int port = 25530);
|
void start_server(int port);
|
||||||
|
void start_server();
|
||||||
int port() const;
|
int port() const;
|
||||||
ServerWorld& server_world();
|
ServerWorld& server_world();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Config m_config;
|
||||||
|
|
||||||
asio::io_context m_io;
|
asio::io_context m_io;
|
||||||
std::thread m_net_thread;
|
std::thread m_net_thread;
|
||||||
int m_port = 25530;
|
int m_port = 25530;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Cubed/config.hpp"
|
||||||
#include "Cubed/gameplay/cave_carver.hpp"
|
#include "Cubed/gameplay/cave_carver.hpp"
|
||||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||||
#include "Cubed/gameplay/game_time.hpp"
|
#include "Cubed/gameplay/game_time.hpp"
|
||||||
@@ -25,7 +26,7 @@ class Session;
|
|||||||
class ServerWorld {
|
class ServerWorld {
|
||||||
public:
|
public:
|
||||||
enum class ThreadPoolKind { NET, GEN };
|
enum class ThreadPoolKind { NET, GEN };
|
||||||
ServerWorld();
|
ServerWorld(Config& config);
|
||||||
~ServerWorld();
|
~ServerWorld();
|
||||||
void stop();
|
void stop();
|
||||||
void handle_player_exit(const std::string& uuid);
|
void handle_player_exit(const std::string& uuid);
|
||||||
@@ -118,6 +119,9 @@ private:
|
|||||||
|
|
||||||
using uuid_acc = PlayerUUIDMap::accessor;
|
using uuid_acc = PlayerUUIDMap::accessor;
|
||||||
using uuid_cacc = PlayerUUIDMap::const_accessor;
|
using uuid_cacc = PlayerUUIDMap::const_accessor;
|
||||||
|
|
||||||
|
Config& m_config;
|
||||||
|
|
||||||
// key = uuid
|
// key = uuid
|
||||||
PlayerHashMap m_players;
|
PlayerHashMap m_players;
|
||||||
ChunkHashMap m_chunks;
|
ChunkHashMap m_chunks;
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
// #include <string>
|
|
||||||
// #include <unordered_map>
|
|
||||||
// #include <vector>
|
|
||||||
namespace Cubed {
|
|
||||||
|
|
||||||
class MapTable {
|
|
||||||
private:
|
|
||||||
/*
|
|
||||||
static inline std::unordered_map<unsigned, std::string> id_to_name_map;
|
|
||||||
static inline std::unordered_map<size_t, unsigned> name_to_id_map;
|
|
||||||
static inline std::vector<std::string> item_id_to_name;
|
|
||||||
*/
|
|
||||||
public:
|
|
||||||
// please using reference
|
|
||||||
/*
|
|
||||||
static std::string_view get_name_from_id(unsigned id);
|
|
||||||
static unsigned get_id_from_name(const std::string& name);
|
|
||||||
|
|
||||||
static std::string_view item_name(unsigned id);
|
|
||||||
static const std::vector<std::string>& item_map();
|
|
||||||
*/
|
|
||||||
static void init_map();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Cubed
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Cubed/config.hpp"
|
||||||
#include "Cubed/constants.hpp"
|
#include "Cubed/constants.hpp"
|
||||||
#include "Cubed/primitive_data.hpp"
|
#include "Cubed/primitive_data.hpp"
|
||||||
#include "Cubed/render/player_renderer.hpp"
|
#include "Cubed/render/player_renderer.hpp"
|
||||||
@@ -23,7 +24,8 @@ public:
|
|||||||
constexpr static int NUM_VAO = 7;
|
constexpr static int NUM_VAO = 7;
|
||||||
|
|
||||||
Renderer(const Camera& camera, ClientWorld& world,
|
Renderer(const Camera& camera, ClientWorld& world,
|
||||||
const TextureManager& texture_manager, DevPanel& dev_panel);
|
const TextureManager& texture_manager, DevPanel& dev_panel,
|
||||||
|
Config& config);
|
||||||
~Renderer();
|
~Renderer();
|
||||||
void hot_reload();
|
void hot_reload();
|
||||||
void init(bool debug_on);
|
void init(bool debug_on);
|
||||||
@@ -109,7 +111,7 @@ private:
|
|||||||
std::vector<Vertex2D> m_ui;
|
std::vector<Vertex2D> m_ui;
|
||||||
|
|
||||||
WorldRenderer m_world_renderer;
|
WorldRenderer m_world_renderer;
|
||||||
|
Config& m_config;
|
||||||
void init_quad();
|
void init_quad();
|
||||||
void init_text();
|
void init_text();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Cubed/config.hpp"
|
||||||
#include "Cubed/gameplay/block.hpp"
|
#include "Cubed/gameplay/block.hpp"
|
||||||
#include "Cubed/render/texture.hpp"
|
#include "Cubed/render/texture.hpp"
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ private:
|
|||||||
std::unique_ptr<Texture> m_skin;
|
std::unique_ptr<Texture> m_skin;
|
||||||
std::vector<std::unique_ptr<Texture>> m_item_textures;
|
std::vector<std::unique_ptr<Texture>> m_item_textures;
|
||||||
GLfloat m_max_aniso = 0.0f;
|
GLfloat m_max_aniso = 0.0f;
|
||||||
|
Config& m_config;
|
||||||
int m_aniso = 1;
|
int m_aniso = 1;
|
||||||
|
|
||||||
void load_block_status(unsigned status_id);
|
void load_block_status(unsigned status_id);
|
||||||
@@ -36,7 +37,7 @@ private:
|
|||||||
void hot_reload();
|
void hot_reload();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextureManager();
|
TextureManager(Config& config);
|
||||||
~TextureManager();
|
~TextureManager();
|
||||||
|
|
||||||
void delete_texture();
|
void delete_texture();
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ concept TomlValueType =
|
|||||||
std::same_as<std::decay_t<T>, toml::date> ||
|
std::same_as<std::decay_t<T>, toml::date> ||
|
||||||
std::same_as<std::decay_t<T>, toml::time> ||
|
std::same_as<std::decay_t<T>, toml::time> ||
|
||||||
std::same_as<std::decay_t<T>, toml::date_time> ||
|
std::same_as<std::decay_t<T>, toml::date_time> ||
|
||||||
|
std::same_as<std::decay_t<T>, float> ||
|
||||||
std::same_as<std::decay_t<T>, std::string>;
|
std::same_as<std::decay_t<T>, std::string>;
|
||||||
|
|
||||||
template <TomlValueType T>
|
template <TomlValueType T>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Cubed/config.hpp"
|
||||||
|
|
||||||
#define GLFW_INCLUDE_NONE
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
@@ -6,7 +9,7 @@ namespace Cubed {
|
|||||||
class Renderer;
|
class Renderer;
|
||||||
class Window {
|
class Window {
|
||||||
public:
|
public:
|
||||||
Window(Renderer& renderer);
|
Window(Renderer& renderer, Config& config);
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
bool is_mouse_enable() const;
|
bool is_mouse_enable() const;
|
||||||
@@ -29,6 +32,7 @@ private:
|
|||||||
int m_width;
|
int m_width;
|
||||||
int m_height;
|
int m_height;
|
||||||
Renderer& m_renderer;
|
Renderer& m_renderer;
|
||||||
|
Config& m_config;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -10,7 +10,6 @@ target_sources(${PROJECT_NAME}
|
|||||||
gameplay/chunk_generator.cpp
|
gameplay/chunk_generator.cpp
|
||||||
gameplay/tree.cpp
|
gameplay/tree.cpp
|
||||||
input.cpp
|
input.cpp
|
||||||
map_table.cpp
|
|
||||||
render/renderer.cpp
|
render/renderer.cpp
|
||||||
shader.cpp
|
shader.cpp
|
||||||
texture_manager.cpp
|
texture_manager.cpp
|
||||||
|
|||||||
12
src/app.cpp
12
src/app.cpp
@@ -12,7 +12,14 @@
|
|||||||
#include <imgui_impl_glfw.h>
|
#include <imgui_impl_glfw.h>
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
App::App() : m_client_world(m_audio) {}
|
App::App()
|
||||||
|
|
||||||
|
: m_game_config(ASSETS_PATH "config.toml"),
|
||||||
|
m_texture_manager(m_game_config), m_audio(m_game_config),
|
||||||
|
m_client_world(m_audio, m_game_config), m_dev_panel(*this),
|
||||||
|
m_renderer(m_camera, m_client_world, m_texture_manager, m_dev_panel,
|
||||||
|
m_game_config),
|
||||||
|
m_window(m_renderer, m_game_config) {}
|
||||||
|
|
||||||
App::~App() {
|
App::~App() {
|
||||||
if (m_client) {
|
if (m_client) {
|
||||||
@@ -357,7 +364,7 @@ void App::update() {
|
|||||||
const auto& player = m_client_world.get_player();
|
const auto& player = m_client_world.get_player();
|
||||||
if (player_gait != player.get_gait()) {
|
if (player_gait != player.get_gait()) {
|
||||||
player_gait = player.get_gait();
|
player_gait = player.get_gait();
|
||||||
float fov = static_cast<float>(Config::get().get<double>("player.fov"));
|
float fov = m_game_config.get("player.fov", 70.0f);
|
||||||
if (player_gait == Gait::WALK) {
|
if (player_gait == Gait::WALK) {
|
||||||
m_renderer.update_fov(fov);
|
m_renderer.update_fov(fov);
|
||||||
}
|
}
|
||||||
@@ -401,6 +408,7 @@ TextureManager& App::texture_manager() { return m_texture_manager; }
|
|||||||
Window& App::window() { return m_window; }
|
Window& App::window() { return m_window; }
|
||||||
ClientWorld& App::client_world() { return m_client_world; }
|
ClientWorld& App::client_world() { return m_client_world; }
|
||||||
ServerWorld& App::server_world() { return m_server.server_world(); }
|
ServerWorld& App::server_world() { return m_server.server_world(); }
|
||||||
|
Config& App::config() { return m_game_config; }
|
||||||
const App::Argument& App::argument() const { return m_argument; }
|
const App::Argument& App::argument() const { return m_argument; }
|
||||||
AudioEngine& App::audio() { return m_audio; }
|
AudioEngine& App::audio() { return m_audio; }
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
#include "Cubed/audio/audio_engine.hpp"
|
#include "Cubed/audio/audio_engine.hpp"
|
||||||
|
|
||||||
#include "Cubed/audio/audio_error.hpp"
|
#include "Cubed/audio/audio_error.hpp"
|
||||||
#include "Cubed/config.hpp"
|
|
||||||
#include "Cubed/tools/cubed_assert.hpp"
|
#include "Cubed/tools/cubed_assert.hpp"
|
||||||
#include "Cubed/tools/log.hpp"
|
#include "Cubed/tools/log.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
AudioEngine::AudioEngine() {};
|
AudioEngine::AudioEngine(Config& config) : m_config(config) {};
|
||||||
|
|
||||||
AudioEngine::~AudioEngine() {
|
AudioEngine::~AudioEngine() {
|
||||||
if (!m_init) {
|
if (!m_init) {
|
||||||
@@ -64,10 +63,8 @@ void AudioEngine::init() {
|
|||||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||||
check_al_error();
|
check_al_error();
|
||||||
|
|
||||||
auto& config = Config::get();
|
m_music_volume = m_config.get("volume.music", 1.0f);
|
||||||
|
m_sfx_volume = m_config.get("volume.SFX", 1.0f);
|
||||||
m_music_volume = static_cast<float>(config.get<double>("volume.music"));
|
|
||||||
m_sfx_volume = static_cast<float>(config.get<double>("volume.SFX"));
|
|
||||||
|
|
||||||
m_sounds.init();
|
m_sounds.init();
|
||||||
|
|
||||||
@@ -187,10 +184,8 @@ void AudioEngine::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioEngine::reload_config() {
|
void AudioEngine::reload_config() {
|
||||||
auto& config = Config::get();
|
m_music_volume = m_config.get("volume.music", 1.0f);
|
||||||
|
m_sfx_volume = m_config.get("volume.SFX", 1.0f);
|
||||||
m_music_volume = static_cast<float>(config.get<double>("volume.music"));
|
|
||||||
m_sfx_volume = static_cast<float>(config.get<double>("volume.SFX"));
|
|
||||||
if (m_bgm) {
|
if (m_bgm) {
|
||||||
m_bgm->set_target_volume(m_music_volume);
|
m_bgm->set_target_volume(m_music_volume);
|
||||||
}
|
}
|
||||||
|
|||||||
126
src/config.cpp
126
src/config.cpp
@@ -1,6 +1,5 @@
|
|||||||
#include "Cubed/config.hpp"
|
#include "Cubed/config.hpp"
|
||||||
|
|
||||||
#include "Cubed/tools/cubed_assert.hpp"
|
|
||||||
#include "Cubed/tools/log.hpp"
|
#include "Cubed/tools/log.hpp"
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@@ -11,71 +10,24 @@ using namespace std::string_view_literals;
|
|||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
Config::Config() { load_or_create_config(); }
|
Config::Config(std::string_view path) : CONGIF_PATH(path) { load_config(); }
|
||||||
|
|
||||||
Config::~Config() { save_to_file(); }
|
Config::~Config() { save_to_file(); }
|
||||||
|
|
||||||
Config& Config::get() {
|
|
||||||
static Config instance;
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
toml::table& Config::table() { return m_tbl; }
|
toml::table& Config::table() { return m_tbl; }
|
||||||
|
|
||||||
void Config::create_config() {
|
void Config::load_config() {
|
||||||
static constexpr auto SOURCE = R"(
|
|
||||||
|
|
||||||
[window]
|
|
||||||
width = 800
|
|
||||||
height = 600
|
|
||||||
fullscreen = false
|
|
||||||
V-Sync = true
|
|
||||||
|
|
||||||
[player]
|
|
||||||
fov = 70.0
|
|
||||||
mouse_sensitivity = 0.15
|
|
||||||
|
|
||||||
[world]
|
|
||||||
rendering_distance = 24
|
|
||||||
|
|
||||||
[devpanel]
|
|
||||||
theme = 0 # 0 is Dark Theme, 1 is Light Theme
|
|
||||||
|
|
||||||
[texture]
|
|
||||||
aniso = 1 # i is the minimun value, indicating off
|
|
||||||
|
|
||||||
[volume]
|
|
||||||
music = 1.0
|
|
||||||
SFX = 1.0
|
|
||||||
|
|
||||||
|
|
||||||
)"sv;
|
|
||||||
|
|
||||||
try {
|
|
||||||
m_tbl = toml::parse(SOURCE);
|
|
||||||
} catch (const toml::parse_error& err) {
|
|
||||||
Logger::error("Load Config Error {}", err.what());
|
|
||||||
ASSERT(false);
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
Logger::info("Create New Config File Success");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Config::load_or_create_config() {
|
|
||||||
fs::path config_path{CONGIF_PATH};
|
fs::path config_path{CONGIF_PATH};
|
||||||
if (!fs::is_regular_file(config_path)) {
|
|
||||||
create_config();
|
if (fs::is_regular_file(config_path)) {
|
||||||
} else
|
|
||||||
try {
|
try {
|
||||||
m_tbl = toml::parse_file(config_path.string());
|
m_tbl = toml::parse_file(config_path.string());
|
||||||
|
Logger::info("Load Config File Success");
|
||||||
} catch (const toml::parse_error& err) {
|
} catch (const toml::parse_error& err) {
|
||||||
Logger::error("Load Config Error: \"{}\"", err.what());
|
Logger::error("Load Config Error: \"{}\"", err.what());
|
||||||
create_config();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Logger::info("Load Config File Success");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::save_to_file() {
|
void Config::save_to_file() {
|
||||||
fs::path config_path{CONGIF_PATH};
|
fs::path config_path{CONGIF_PATH};
|
||||||
std::ofstream file{config_path};
|
std::ofstream file{config_path};
|
||||||
@@ -83,40 +35,54 @@ void Config::save_to_file() {
|
|||||||
Logger::info("Save File Success");
|
Logger::info("Save File Success");
|
||||||
}
|
}
|
||||||
|
|
||||||
toml::node_view<toml::node> Config::val_view(std::string_view key) {
|
const toml::node* Config::find_node(const toml::table& root,
|
||||||
|
std::string_view path) const {
|
||||||
|
const toml::table* table = &root;
|
||||||
|
|
||||||
size_t cur = 0;
|
size_t cur = 0;
|
||||||
auto pos = key.find('.');
|
auto pos = path.find('.');
|
||||||
toml::table* table = &m_tbl;
|
|
||||||
while (pos != std::string_view::npos) {
|
while (pos != std::string_view::npos) {
|
||||||
std::string_view s = key.substr(cur, pos - cur);
|
auto name = path.substr(cur, pos - cur);
|
||||||
if (s.empty()) {
|
|
||||||
Logger::error("Empty key/table name in path '{}'", key);
|
if (auto* next = (*table)[name].as_table()) {
|
||||||
ASSERT(false);
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
cur = pos + 1;
|
|
||||||
pos = key.find('.', cur);
|
|
||||||
if (auto* next = (*table)[s].as_table()) {
|
|
||||||
table = next;
|
table = next;
|
||||||
} else {
|
} else {
|
||||||
Logger::error("Can't find table {}", s);
|
return nullptr;
|
||||||
ASSERT(false);
|
|
||||||
std::abort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cur = pos + 1;
|
||||||
|
pos = path.find('.', cur);
|
||||||
}
|
}
|
||||||
std::string_view n_key = key.substr(cur);
|
|
||||||
if (n_key.empty()) {
|
auto key = path.substr(cur);
|
||||||
Logger::error("Trailing dot in path '{}'", key);
|
|
||||||
ASSERT(false);
|
return (*table)[key].node();
|
||||||
std::abort();
|
}
|
||||||
|
|
||||||
|
toml::table* Config::find_or_create_table(std::string_view path) {
|
||||||
|
toml::table* table = &m_tbl;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto pos = path.find('.');
|
||||||
|
auto part = pos == std::string_view::npos ? path : path.substr(0, pos);
|
||||||
|
|
||||||
|
if (auto* next = (*table)[part].as_table()) {
|
||||||
|
// If there is a table, proceed to the next
|
||||||
|
table = next;
|
||||||
|
} else {
|
||||||
|
// If there is no table, create a new one
|
||||||
|
auto [it, _] = table->insert(part, toml::table{});
|
||||||
|
table = it->second.as_table();
|
||||||
}
|
}
|
||||||
auto view = (*table)[n_key];
|
|
||||||
if (!view) {
|
if (pos == std::string_view::npos)
|
||||||
Logger::error("The view is null");
|
break;
|
||||||
ASSERT(false);
|
|
||||||
std::abort();
|
path.remove_prefix(pos + 1);
|
||||||
}
|
}
|
||||||
return view;
|
|
||||||
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -46,7 +46,7 @@ constexpr float DELTA_ANGLE_MAX = 30.0f;
|
|||||||
constexpr int PATH_STEP_MIN = 1;
|
constexpr int PATH_STEP_MIN = 1;
|
||||||
constexpr int PATH_STEP_MAX = 1000;
|
constexpr int PATH_STEP_MAX = 1000;
|
||||||
|
|
||||||
DevPanel::DevPanel(App& app) : m_app(app) {}
|
DevPanel::DevPanel(App& app) : m_app(app), m_config(app.config()) {}
|
||||||
|
|
||||||
void DevPanel::init() {
|
void DevPanel::init() {
|
||||||
m_player = &m_app.client_world().get_player();
|
m_player = &m_app.client_world().get_player();
|
||||||
@@ -355,96 +355,95 @@ void DevPanel::show_chunk_table_bar() {
|
|||||||
|
|
||||||
void DevPanel::show_settings_tab_item() {
|
void DevPanel::show_settings_tab_item() {
|
||||||
if (ImGui::BeginTabItem("settings")) {
|
if (ImGui::BeginTabItem("settings")) {
|
||||||
if (ImGui::SliderFloat("FOV", &m_config.fov, 1.0f, 140.0f)) {
|
if (ImGui::SliderFloat("FOV", &m_config_view.fov, 1.0f, 140.0f)) {
|
||||||
Config::get().set("player.fov", static_cast<double>(m_config.fov));
|
m_config.set("player.fov", static_cast<double>(m_config_view.fov));
|
||||||
m_app.renderer().hot_reload();
|
m_app.renderer().hot_reload();
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button("default##1")) {
|
if (ImGui::Button("default##1")) {
|
||||||
m_config.fov = DEFAULT_FOV;
|
m_config_view.fov = DEFAULT_FOV;
|
||||||
Config::get().set("player.fov", static_cast<double>(m_config.fov));
|
m_config.set("player.fov", static_cast<double>(m_config_view.fov));
|
||||||
m_app.renderer().hot_reload();
|
m_app.renderer().hot_reload();
|
||||||
}
|
}
|
||||||
if (ImGui::SliderFloat("Sensitivity", &m_config.mouse_sensitivity,
|
if (ImGui::SliderFloat("Sensitivity", &m_config_view.mouse_sensitivity,
|
||||||
0.01f, 1.0f)) {
|
0.01f, 1.0f)) {
|
||||||
Config::get().set("player.mouse_sensitivity",
|
m_config.set("player.mouse_sensitivity",
|
||||||
static_cast<double>(m_config.mouse_sensitivity));
|
static_cast<double>(m_config_view.mouse_sensitivity));
|
||||||
m_player->hot_reload();
|
m_player->hot_reload();
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button("default##2")) {
|
if (ImGui::Button("default##2")) {
|
||||||
m_config.mouse_sensitivity = 0.15f;
|
m_config_view.mouse_sensitivity = 0.15f;
|
||||||
Config::get().set("player.mouse_sensitivity",
|
m_config.set("player.mouse_sensitivity",
|
||||||
static_cast<double>(m_config.mouse_sensitivity));
|
static_cast<double>(m_config_view.mouse_sensitivity));
|
||||||
m_player->hot_reload();
|
m_player->hot_reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::SliderInt("Distance", &m_config.rendering_distance, 2,
|
if (ImGui::SliderInt("Distance", &m_config_view.rendering_distance, 2,
|
||||||
128)) {
|
128)) {
|
||||||
Config::get().set("world.rendering_distance",
|
m_config.set("world.rendering_distance",
|
||||||
m_config.rendering_distance);
|
m_config_view.rendering_distance);
|
||||||
m_app.client_world().hot_reload();
|
m_app.client_world().hot_reload();
|
||||||
}
|
}
|
||||||
if (ImGui::Checkbox("Fullscreen", &m_config.fullscreen)) {
|
if (ImGui::Checkbox("Fullscreen", &m_config_view.fullscreen)) {
|
||||||
Config::get().set("window.fullscreen", m_config.fullscreen);
|
m_config.set("window.fullscreen", m_config_view.fullscreen);
|
||||||
m_app.window().hot_reload();
|
m_app.window().hot_reload();
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Checkbox("V-Sync", &m_config.v_sync)) {
|
if (ImGui::Checkbox("V-Sync", &m_config_view.v_sync)) {
|
||||||
Config::get().set("window.V-Sync", m_config.v_sync);
|
m_config.set("window.V-Sync", m_config_view.v_sync);
|
||||||
m_app.window().hot_reload();
|
m_app.window().hot_reload();
|
||||||
}
|
}
|
||||||
if (ImGui::Checkbox("Aniso", &m_config.is_enable_aniso)) {
|
if (ImGui::Checkbox("Aniso", &m_config_view.is_enable_aniso)) {
|
||||||
m_config.is_reload = false;
|
m_config_view.is_reload = false;
|
||||||
if (m_config.is_enable_aniso) {
|
if (m_config_view.is_enable_aniso) {
|
||||||
m_config.max_aniso = m_app.texture_manager().max_aniso();
|
m_config_view.max_aniso = m_app.texture_manager().max_aniso();
|
||||||
if (m_config.max_aniso < 2) {
|
if (m_config_view.max_aniso < 2) {
|
||||||
m_config.is_support_aniso = false;
|
m_config_view.is_support_aniso = false;
|
||||||
} else {
|
} else {
|
||||||
m_config.aniso = 2;
|
m_config_view.aniso = 2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_config.aniso = 1;
|
m_config_view.aniso = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_config.is_enable_aniso) {
|
if (m_config_view.is_enable_aniso) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (!m_config.is_support_aniso) {
|
if (!m_config_view.is_support_aniso) {
|
||||||
ImGui::Text("Not Support\n");
|
ImGui::Text("Not Support\n");
|
||||||
} else {
|
} else {
|
||||||
if (ImGui::SliderInt("##aniso", &m_config.aniso, 2,
|
if (ImGui::SliderInt("##aniso", &m_config_view.aniso, 2,
|
||||||
m_config.max_aniso)) {
|
m_config_view.max_aniso)) {
|
||||||
m_config.is_reload = false;
|
m_config_view.is_reload = false;
|
||||||
int log =
|
int log =
|
||||||
static_cast<int>(std::log2(m_config.aniso) + 0.5f);
|
static_cast<int>(std::log2(m_config_view.aniso) + 0.5f);
|
||||||
m_config.aniso = static_cast<int>(std::pow(2, log));
|
m_config_view.aniso = static_cast<int>(std::pow(2, log));
|
||||||
if (m_config.aniso < 2) {
|
if (m_config_view.aniso < 2) {
|
||||||
m_config.aniso = 2;
|
m_config_view.aniso = 2;
|
||||||
}
|
}
|
||||||
if (m_config.aniso > m_config.max_aniso) {
|
if (m_config_view.aniso > m_config_view.max_aniso) {
|
||||||
m_config.aniso = m_config.max_aniso;
|
m_config_view.aniso = m_config_view.max_aniso;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::Button("ReloadTexture")) {
|
if (ImGui::Button("ReloadTexture")) {
|
||||||
Config::get().set("texture.aniso", m_config.aniso);
|
m_config.set("texture.aniso", m_config_view.aniso);
|
||||||
m_app.texture_manager().need_reload();
|
m_app.texture_manager().need_reload();
|
||||||
m_config.is_reload = true;
|
m_config_view.is_reload = true;
|
||||||
}
|
}
|
||||||
if (!m_config.is_reload) {
|
if (!m_config_view.is_reload) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Text("Your need to click this button to apply config\n");
|
ImGui::Text("Your need to click this button to apply config\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::SliderFloat("Music", &m_config.volume_music, 0.0f, 1.0f)) {
|
if (ImGui::SliderFloat("Music", &m_config_view.volume_music, 0.0f,
|
||||||
Config::get().set("volume.music",
|
1.0f)) {
|
||||||
static_cast<double>(m_config.volume_music));
|
m_config.set("volume.music", m_config_view.volume_music);
|
||||||
m_app.audio().reload_config();
|
m_app.audio().reload_config();
|
||||||
}
|
}
|
||||||
if (ImGui::SliderFloat("SFX", &m_config.volume_sfx, 0.0f, 1.0f)) {
|
if (ImGui::SliderFloat("SFX", &m_config_view.volume_sfx, 0.0f, 1.0f)) {
|
||||||
Config::get().set("volume.SFX",
|
m_config.set("volume.SFX", m_config_view.volume_sfx);
|
||||||
static_cast<double>(m_config.volume_sfx));
|
|
||||||
m_app.audio().reload_config();
|
m_app.audio().reload_config();
|
||||||
}
|
}
|
||||||
if (ImGui::Combo("Theme", &m_theme, THEMES, IM_ARRAYSIZE(THEMES))) {
|
if (ImGui::Combo("Theme", &m_theme, THEMES, IM_ARRAYSIZE(THEMES))) {
|
||||||
@@ -453,10 +452,10 @@ void DevPanel::show_settings_tab_item() {
|
|||||||
} else if (m_theme == 1) {
|
} else if (m_theme == 1) {
|
||||||
ImGui::StyleColorsLight();
|
ImGui::StyleColorsLight();
|
||||||
}
|
}
|
||||||
Config::get().set("devpanel.theme", m_theme);
|
m_config.set("devpanel.theme", m_theme);
|
||||||
}
|
}
|
||||||
if (ImGui::Button("save")) {
|
if (ImGui::Button("save")) {
|
||||||
Config::get().save_to_file();
|
m_config.save_to_file();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
@@ -750,32 +749,28 @@ void DevPanel::show_shader_tab_item() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DevPanel::update_config_view() {
|
void DevPanel::update_config_view() {
|
||||||
auto config = Config::get();
|
m_config_view.fov = m_config.get("player.fov", 70.0f);
|
||||||
m_config.fov =
|
m_config_view.fullscreen = m_config.get("window.fullscreen", false);
|
||||||
static_cast<float>(config.val_view("player.fov").value_or(70.0));
|
m_config_view.v_sync = m_config.get("window.V-Sync", true);
|
||||||
m_config.fullscreen = config.val_view("window.fullscreen").value_or(false);
|
m_config_view.mouse_sensitivity =
|
||||||
m_config.v_sync = config.val_view("window.V-Sync").value_or(true);
|
m_config.get("player.mouse_sensitivity", 0.15f);
|
||||||
m_config.mouse_sensitivity = static_cast<float>(
|
m_config_view.width = m_config.get("window.width", 800);
|
||||||
config.val_view("player.mouse_sensitivity").value_or(0.15));
|
m_config_view.height = m_config.get("window.height", 600);
|
||||||
m_config.width = config.val_view("window.width").value_or(800);
|
m_config_view.rendering_distance =
|
||||||
m_config.height = config.val_view("window.height").value_or(600);
|
m_config.get("world.rendering_distance", 24);
|
||||||
m_config.rendering_distance =
|
m_theme = m_config.get("devpanel.theme", 0);
|
||||||
config.val_view("world.rendering_distance").value_or(24);
|
|
||||||
m_theme = config.val_view("devpanel.theme").value_or(0);
|
|
||||||
if (m_theme != 1 && m_theme != 0) {
|
if (m_theme != 1 && m_theme != 0) {
|
||||||
m_theme = 0;
|
m_theme = 0;
|
||||||
}
|
}
|
||||||
m_config.aniso = config.val_view("texture.aniso").value_or(1);
|
m_config_view.aniso = m_config.get("texture.aniso", 1);
|
||||||
m_config.max_aniso = m_app.texture_manager().max_aniso();
|
m_config_view.max_aniso = m_app.texture_manager().max_aniso();
|
||||||
if (m_config.aniso <= 1) {
|
if (m_config_view.aniso <= 1) {
|
||||||
m_config.is_enable_aniso = false;
|
m_config_view.is_enable_aniso = false;
|
||||||
} else {
|
} else {
|
||||||
m_config.is_enable_aniso = true;
|
m_config_view.is_enable_aniso = true;
|
||||||
}
|
}
|
||||||
m_config.volume_music =
|
m_config_view.volume_music = m_config.get("volume.music", 1.0f);
|
||||||
static_cast<float>(config.val_view("volume.music").value_or(1.0));
|
m_config_view.volume_sfx = m_config.get("volume.SFX", 1.0f);
|
||||||
m_config.volume_sfx =
|
|
||||||
static_cast<float>(config.val_view("volume.SFX").value_or(1.0));
|
|
||||||
}
|
}
|
||||||
void DevPanel::update_player_profile() {
|
void DevPanel::update_player_profile() {
|
||||||
if (!m_player) {
|
if (!m_player) {
|
||||||
|
|||||||
@@ -121,9 +121,8 @@ void ClientPlayer::change_mode(GameMode mode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ClientPlayer::hot_reload() {
|
void ClientPlayer::hot_reload() {
|
||||||
auto& config = Config::get();
|
auto& config = m_world.get_config();
|
||||||
m_sensitivity =
|
m_sensitivity = config.get("player.mouse_sensitivity", 0.15f);
|
||||||
static_cast<float>(config.get<double>("player.mouse_sensitivity"));
|
|
||||||
}
|
}
|
||||||
void ClientPlayer::set_player_pos(const glm::vec3& pos) { m_player_pos = pos; }
|
void ClientPlayer::set_player_pos(const glm::vec3& pos) { m_player_pos = pos; }
|
||||||
|
|
||||||
@@ -562,7 +561,7 @@ const ClientPlayer::ChunkPosSet& ClientPlayer::get_chunk_pos_set() const {
|
|||||||
return m_player_chunk_pos_set;
|
return m_player_chunk_pos_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientPlayer::ChunkPosSet& ClientPlayer::get_chunk_pos_set() {
|
ClientPlayer::ChunkPosSet ClientPlayer::get_chunk_pos_set() {
|
||||||
std::lock_guard lock(m_chunk_pos_mutex);
|
std::lock_guard lock(m_chunk_pos_mutex);
|
||||||
return m_player_chunk_pos_set;
|
return m_player_chunk_pos_set;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,15 +21,26 @@ struct ChunkRenderData {
|
|||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ClientWorld::ClientWorld(AudioEngine& auido)
|
ClientWorld::ClientWorld(AudioEngine& auido, Config& config)
|
||||||
: m_player(*this), m_audio(auido) {}
|
: m_player(*this), m_audio(auido), m_config(config) {}
|
||||||
|
|
||||||
ClientWorld::~ClientWorld() {
|
ClientWorld::~ClientWorld() {
|
||||||
|
m_client->close();
|
||||||
|
|
||||||
stop_client_thread();
|
stop_client_thread();
|
||||||
stop_thread_pool();
|
stop_thread_pool();
|
||||||
|
// Must first clean up and push the generated chunk data into
|
||||||
|
// m_pending_delete_vbo and m_pending_delete_vao; cannot delete them in the
|
||||||
|
// destructor, otherwise it will cause leaks and use-after-free.
|
||||||
|
m_dirty_chunk_queue.clear();
|
||||||
|
m_pending_upload_queue.clear();
|
||||||
|
|
||||||
m_chunks.clear();
|
m_chunks.clear();
|
||||||
|
|
||||||
|
if (m_is_pending_delete_queue_free.exchange(true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard lk(m_delete_vbo_mutex);
|
std::lock_guard lk(m_delete_vbo_mutex);
|
||||||
m_pending_delete_vbo.clear();
|
m_pending_delete_vbo.clear();
|
||||||
@@ -262,10 +273,18 @@ void ClientWorld::set_block(const glm::ivec3& block_pos, unsigned id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ClientWorld::push_delete_vbo(std::unique_ptr<VertexBuffer>& vbo) {
|
void ClientWorld::push_delete_vbo(std::unique_ptr<VertexBuffer>& vbo) {
|
||||||
|
if (m_is_pending_delete_queue_free) {
|
||||||
|
Logger::error("Push delete vbo Use After Free");
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::lock_guard lk(m_delete_vbo_mutex);
|
std::lock_guard lk(m_delete_vbo_mutex);
|
||||||
m_pending_delete_vbo.push_back(std::move(vbo));
|
m_pending_delete_vbo.push_back(std::move(vbo));
|
||||||
}
|
}
|
||||||
void ClientWorld::push_delete_vao(std::unique_ptr<VertexArray>& vao) {
|
void ClientWorld::push_delete_vao(std::unique_ptr<VertexArray>& vao) {
|
||||||
|
if (m_is_pending_delete_queue_free) {
|
||||||
|
Logger::error("Push delete vao Use After Free");
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::lock_guard lk(m_delete_vao_mutex);
|
std::lock_guard lk(m_delete_vao_mutex);
|
||||||
m_pending_delete_vao.push_back(std::move(vao));
|
m_pending_delete_vao.push_back(std::move(vao));
|
||||||
}
|
}
|
||||||
@@ -504,8 +523,7 @@ void ClientWorld::change_pool_threads(int threads) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::hot_reload() {
|
void ClientWorld::hot_reload() {
|
||||||
auto& config = Config::get();
|
int dist = m_config.get<int>("world.rendering_distance", PRE_LOAD_DISTANCE);
|
||||||
int dist = config.get<int>("world.rendering_distance");
|
|
||||||
Logger::info("Get Config Randering dist {}", dist);
|
Logger::info("Get Config Randering dist {}", dist);
|
||||||
m_rendering_distance = dist <= MAX_DISTANCE ? dist : MAX_DISTANCE;
|
m_rendering_distance = dist <= MAX_DISTANCE ? dist : MAX_DISTANCE;
|
||||||
request_chunk();
|
request_chunk();
|
||||||
@@ -591,7 +609,7 @@ void ClientWorld::request_chunk() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChunkPosSet old = std::move(m_player.get_chunk_pos_set());
|
ChunkPosSet old = m_player.get_chunk_pos_set();
|
||||||
m_player.update_chunk_set(required_chunks);
|
m_player.update_chunk_set(required_chunks);
|
||||||
|
|
||||||
ChunkPosVector need_send_pos;
|
ChunkPosVector need_send_pos;
|
||||||
@@ -699,6 +717,7 @@ AABB ClientWorld::get_block_aabb(const glm::ivec3& pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AudioEngine& ClientWorld::get_audio() { return m_audio; }
|
AudioEngine& ClientWorld::get_audio() { return m_audio; }
|
||||||
|
Config& ClientWorld::get_config() { return m_config; }
|
||||||
|
|
||||||
void ClientWorld::request_exit() {
|
void ClientWorld::request_exit() {
|
||||||
if (m_receive_exit) {
|
if (m_receive_exit) {
|
||||||
|
|||||||
@@ -4,7 +4,10 @@
|
|||||||
using asio::ip::tcp;
|
using asio::ip::tcp;
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
NetworkServer::NetworkServer(int port) : m_port(port) {}
|
NetworkServer::NetworkServer()
|
||||||
|
: m_config(ASSETS_PATH "server-config.toml"), m_world(m_config) {
|
||||||
|
m_port = m_config.get("port", 25530);
|
||||||
|
}
|
||||||
|
|
||||||
NetworkServer::~NetworkServer() { stop(); }
|
NetworkServer::~NetworkServer() { stop(); }
|
||||||
|
|
||||||
@@ -84,6 +87,11 @@ void NetworkServer::net_run() {
|
|||||||
|
|
||||||
void NetworkServer::start_server(int port) {
|
void NetworkServer::start_server(int port) {
|
||||||
m_port = port;
|
m_port = port;
|
||||||
|
m_config.set("port", m_port);
|
||||||
|
start_server();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkServer::start_server() {
|
||||||
m_world.init_world();
|
m_world.init_world();
|
||||||
net_run();
|
net_run();
|
||||||
m_started = true;
|
m_started = true;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "Cubed/gameplay/server_world.hpp"
|
#include "Cubed/gameplay/server_world.hpp"
|
||||||
|
|
||||||
#include "Cubed/config.hpp"
|
|
||||||
#include "Cubed/gameplay/packet.hpp"
|
#include "Cubed/gameplay/packet.hpp"
|
||||||
#include "Cubed/gameplay/session.hpp"
|
#include "Cubed/gameplay/session.hpp"
|
||||||
#include "Cubed/tools/cubed_assert.hpp"
|
#include "Cubed/tools/cubed_assert.hpp"
|
||||||
@@ -14,7 +13,7 @@ using namespace std::chrono_literals;
|
|||||||
using namespace google::protobuf;
|
using namespace google::protobuf;
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
ServerWorld::ServerWorld() {}
|
ServerWorld::ServerWorld(Config& config) : m_config(config) {}
|
||||||
|
|
||||||
ServerWorld::~ServerWorld() { stop(); }
|
ServerWorld::~ServerWorld() { stop(); }
|
||||||
|
|
||||||
@@ -501,8 +500,7 @@ bool ServerWorld::set_block(const glm::ivec3& block_pos, unsigned id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServerWorld::hot_reload() {
|
void ServerWorld::hot_reload() {
|
||||||
auto& config = Config::get();
|
int dist = m_config.get("server_distance", 24);
|
||||||
int dist = config.get<int>("world.rendering_distance");
|
|
||||||
m_rendering_distance = dist <= MAX_DISTANCE ? dist : MAX_DISTANCE;
|
m_rendering_distance = dist <= MAX_DISTANCE ? dist : MAX_DISTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
#include "Cubed/map_table.hpp"
|
|
||||||
|
|
||||||
namespace Cubed {
|
|
||||||
/*
|
|
||||||
std::string_view MapTable::get_name_from_id(unsigned id) {
|
|
||||||
auto it = id_to_name_map.find(id);
|
|
||||||
ASSERT_MSG(it != id_to_name_map.end(),
|
|
||||||
"Id: " + std::to_string(id) + " is not exist");
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned MapTable::get_id_from_name(const std::string& name) {
|
|
||||||
auto it = name_to_id_map.find(HASH::str(name));
|
|
||||||
ASSERT_MSG(it != name_to_id_map.end(), "Name " + name + " is not exist");
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string_view MapTable::item_name(unsigned id) {
|
|
||||||
ASSERT_MSG(id < item_id_to_name.size(), "ID is invalid");
|
|
||||||
return item_id_to_name[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string>& MapTable::item_map() { return item_id_to_name; }
|
|
||||||
*/
|
|
||||||
void MapTable::init_map() {
|
|
||||||
/*
|
|
||||||
id_to_name_map.reserve(MAX_BLOCK_NUM);
|
|
||||||
name_to_id_map.reserve(MAX_BLOCK_NUM);
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_BLOCK_NUM; i++) {
|
|
||||||
id_to_name_map[i] = BLOCK_REISTER[i];
|
|
||||||
name_to_id_map[HASH::str(BLOCK_REISTER[i])] = i;
|
|
||||||
}
|
|
||||||
for (auto s : BLOCK_REISTER) {
|
|
||||||
item_id_to_name.emplace_back(s);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Cubed
|
|
||||||
@@ -20,10 +20,11 @@
|
|||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
Renderer::Renderer(const Camera& camera, ClientWorld& world,
|
Renderer::Renderer(const Camera& camera, ClientWorld& world,
|
||||||
const TextureManager& texture_manager, DevPanel& dev_panel)
|
const TextureManager& texture_manager, DevPanel& dev_panel,
|
||||||
|
Config& config)
|
||||||
: m_camera(camera), m_dev_panel(dev_panel),
|
: m_camera(camera), m_dev_panel(dev_panel),
|
||||||
m_texture_manager(texture_manager), m_world(world),
|
m_texture_manager(texture_manager), m_world(world),
|
||||||
m_world_renderer(*this) {}
|
m_world_renderer(*this), m_config(config) {}
|
||||||
|
|
||||||
Renderer::~Renderer() {
|
Renderer::~Renderer() {
|
||||||
if (m_init) {
|
if (m_init) {
|
||||||
@@ -38,10 +39,7 @@ Renderer::~Renderer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::hot_reload() {
|
void Renderer::hot_reload() { update_fov(m_config.get("player.fov", 70.0f)); }
|
||||||
auto& config = Config::get();
|
|
||||||
update_fov(config.get<double>("player.fov"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::init(bool debug_on) {
|
void Renderer::init(bool debug_on) {
|
||||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "Cubed/config.hpp"
|
#include "Cubed/config.hpp"
|
||||||
#include "Cubed/constants.hpp"
|
#include "Cubed/constants.hpp"
|
||||||
#include "Cubed/map_table.hpp"
|
|
||||||
#include "Cubed/tools/cubed_assert.hpp"
|
#include "Cubed/tools/cubed_assert.hpp"
|
||||||
#include "Cubed/tools/log.hpp"
|
#include "Cubed/tools/log.hpp"
|
||||||
#include "Cubed/tools/shader_tools.hpp"
|
#include "Cubed/tools/shader_tools.hpp"
|
||||||
@@ -32,7 +31,7 @@ unsigned char* generate_flat_normal_map(int width = BLOCK_NORMAL_SIZE,
|
|||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
TextureManager::TextureManager() {}
|
TextureManager::TextureManager(Config& config) : m_config(config) {}
|
||||||
|
|
||||||
TextureManager::~TextureManager() { delete_texture(); }
|
TextureManager::~TextureManager() { delete_texture(); }
|
||||||
|
|
||||||
@@ -286,10 +285,9 @@ void TextureManager::init_texture() {
|
|||||||
Logger::info("Support anisotropic filtering max_aniso is {}",
|
Logger::info("Support anisotropic filtering max_aniso is {}",
|
||||||
m_max_aniso);
|
m_max_aniso);
|
||||||
}
|
}
|
||||||
m_aniso = Config::get().get<int>("texture.aniso");
|
m_aniso = m_config.get("texture.aniso", 1);
|
||||||
m_aniso = std::min(static_cast<int>(m_max_aniso), m_aniso);
|
m_aniso = std::min(static_cast<int>(m_max_aniso), m_aniso);
|
||||||
Logger::info("Setting Texture Aniso is {}", m_aniso);
|
Logger::info("Setting Texture Aniso is {}", m_aniso);
|
||||||
MapTable::init_map();
|
|
||||||
Logger::info("Map Init Success");
|
Logger::info("Map Init Success");
|
||||||
|
|
||||||
init_block();
|
init_block();
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "Cubed/window.hpp"
|
#include "Cubed/window.hpp"
|
||||||
|
|
||||||
#include "Cubed/config.hpp"
|
|
||||||
#include "Cubed/render/renderer.hpp"
|
#include "Cubed/render/renderer.hpp"
|
||||||
#include "Cubed/tools/cubed_assert.hpp"
|
#include "Cubed/tools/cubed_assert.hpp"
|
||||||
#include "Cubed/tools/font.hpp"
|
#include "Cubed/tools/font.hpp"
|
||||||
@@ -15,7 +14,8 @@ namespace Cubed {
|
|||||||
static int windowed_xpos = 0, windowed_ypos = 0;
|
static int windowed_xpos = 0, windowed_ypos = 0;
|
||||||
static int windowed_width = 800, windowed_height = 600;
|
static int windowed_width = 800, windowed_height = 600;
|
||||||
|
|
||||||
Window::Window(Renderer& renderer) : m_renderer(renderer) {}
|
Window::Window(Renderer& renderer, Config& config)
|
||||||
|
: m_renderer(renderer), m_config(config) {}
|
||||||
|
|
||||||
Window::~Window() {
|
Window::~Window() {
|
||||||
if (m_imgui_init) {
|
if (m_imgui_init) {
|
||||||
@@ -47,9 +47,8 @@ void Window::update_viewport() {
|
|||||||
glViewport(0, 0, m_width, m_height);
|
glViewport(0, 0, m_width, m_height);
|
||||||
m_renderer.update_proj_matrix(m_aspect, m_width, m_height);
|
m_renderer.update_proj_matrix(m_aspect, m_width, m_height);
|
||||||
m_renderer.updata_framebuffer(m_width, m_height);
|
m_renderer.updata_framebuffer(m_width, m_height);
|
||||||
auto& config = Config::get();
|
m_config.set("window.width", windowed_width);
|
||||||
config.set("window.width", windowed_width);
|
m_config.set("window.height", windowed_height);
|
||||||
config.set("window.height", windowed_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::init() {
|
void Window::init() {
|
||||||
@@ -61,10 +60,9 @@ void Window::init() {
|
|||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||||
auto& config = Config::get();
|
m_width = m_config.get("window.width", 800);
|
||||||
m_width = config.get<int>("window.width");
|
m_height = m_config.get("window.height", 600);
|
||||||
m_height = config.get<int>("window.height");
|
if (m_config.get("window.fullscreen", false)) {
|
||||||
if (config.get<bool>("window.fullscreen")) {
|
|
||||||
GLFWmonitor* primary_monitor = glfwGetPrimaryMonitor();
|
GLFWmonitor* primary_monitor = glfwGetPrimaryMonitor();
|
||||||
const GLFWvidmode* mode = glfwGetVideoMode(primary_monitor);
|
const GLFWvidmode* mode = glfwGetVideoMode(primary_monitor);
|
||||||
m_window = glfwCreateWindow(mode->width, mode->height, "Cubed",
|
m_window = glfwCreateWindow(mode->width, mode->height, "Cubed",
|
||||||
@@ -74,7 +72,7 @@ void Window::init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glfwMakeContextCurrent(m_window);
|
glfwMakeContextCurrent(m_window);
|
||||||
if (config.get<bool>("window.V-Sync")) {
|
if (m_config.get("window.V-Sync", true)) {
|
||||||
glfwSwapInterval(1);
|
glfwSwapInterval(1);
|
||||||
} else {
|
} else {
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
@@ -94,18 +92,17 @@ void Window::init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Window::hot_reload() {
|
void Window::hot_reload() {
|
||||||
auto& config = Config::get();
|
|
||||||
// V-Sync
|
// V-Sync
|
||||||
if (config.get<bool>("window.V-Sync")) {
|
if (m_config.get("window.V-Sync", true)) {
|
||||||
glfwSwapInterval(1);
|
glfwSwapInterval(1);
|
||||||
} else {
|
} else {
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
}
|
}
|
||||||
// Window
|
// Window
|
||||||
windowed_width = config.get<int>("window.width");
|
windowed_width = m_config.get("window.width", 800);
|
||||||
windowed_height = config.get<int>("window.height");
|
windowed_height = m_config.get("window.height", 600);
|
||||||
|
|
||||||
if (config.get<bool>("window.fullscreen")) {
|
if (m_config.get("window.fullscreen", false)) {
|
||||||
glfwGetWindowPos(m_window, &windowed_xpos, &windowed_ypos);
|
glfwGetWindowPos(m_window, &windowed_xpos, &windowed_ypos);
|
||||||
glfwGetWindowSize(m_window, &windowed_width, &windowed_height);
|
glfwGetWindowSize(m_window, &windowed_width, &windowed_height);
|
||||||
|
|
||||||
@@ -134,13 +131,12 @@ void Window::hot_reload() {
|
|||||||
|
|
||||||
void Window::toggle_fullscreen() {
|
void Window::toggle_fullscreen() {
|
||||||
|
|
||||||
auto& config = Config::get();
|
|
||||||
GLFWmonitor* monitor = glfwGetWindowMonitor(m_window);
|
GLFWmonitor* monitor = glfwGetWindowMonitor(m_window);
|
||||||
if (monitor != nullptr) {
|
if (monitor != nullptr) {
|
||||||
glfwSetWindowMonitor(m_window, nullptr, windowed_xpos, windowed_ypos,
|
glfwSetWindowMonitor(m_window, nullptr, windowed_xpos, windowed_ypos,
|
||||||
windowed_width, windowed_height, 0);
|
windowed_width, windowed_height, 0);
|
||||||
|
|
||||||
config.set("window.fullscreen", false);
|
m_config.set("window.fullscreen", false);
|
||||||
} else {
|
} else {
|
||||||
glfwGetWindowPos(m_window, &windowed_xpos, &windowed_ypos);
|
glfwGetWindowPos(m_window, &windowed_xpos, &windowed_ypos);
|
||||||
glfwGetWindowSize(m_window, &windowed_width, &windowed_height);
|
glfwGetWindowSize(m_window, &windowed_width, &windowed_height);
|
||||||
@@ -150,7 +146,7 @@ void Window::toggle_fullscreen() {
|
|||||||
|
|
||||||
glfwSetWindowMonitor(m_window, primary, 0, 0, mode->width, mode->height,
|
glfwSetWindowMonitor(m_window, primary, 0, 0, mode->width, mode->height,
|
||||||
GL_DONT_CARE);
|
GL_DONT_CARE);
|
||||||
config.set("window.fullscreen", true);
|
m_config.set("window.fullscreen", true);
|
||||||
}
|
}
|
||||||
update_viewport();
|
update_viewport();
|
||||||
}
|
}
|
||||||
@@ -194,14 +190,14 @@ void Window::imgui_init() {
|
|||||||
// the game to fully control
|
// the game to fully control
|
||||||
// cursor appearance (e.g.,
|
// cursor appearance (e.g.,
|
||||||
// hidden/disabled custom cursor).
|
// hidden/disabled custom cursor).
|
||||||
auto theme = Config::get().get<int>("devpanel.theme");
|
auto theme = m_config.get("devpanel.theme", 0);
|
||||||
if (theme == 0) {
|
if (theme == 0) {
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
} else if (theme == 1) {
|
} else if (theme == 1) {
|
||||||
ImGui::StyleColorsLight();
|
ImGui::StyleColorsLight();
|
||||||
} else {
|
} else {
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
Config::get().set("devpanel.theme", 0);
|
m_config.set("devpanel.theme", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
|||||||
Reference in New Issue
Block a user