feat: runtime-configurable VSync via config.toml
[display] vsync = "mailbox" # "vsync" | "mailbox" | "uncapped" VsyncMode enum with custom Deserialize — accepts string values in toml. apply_vsync_setting system reads GameConfig on every frame, updates Window.present_mode immediately on change. No restart needed.
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
initial_chunk_radius = 15
|
initial_chunk_radius = 15
|
||||||
|
|
||||||
|
[display]
|
||||||
|
vsync = "mailbox"
|
||||||
|
|
||||||
[spawn_counts]
|
[spawn_counts]
|
||||||
dorfs = 5
|
dorfs = 5
|
||||||
pigs = 5
|
pigs = 5
|
||||||
|
|||||||
@@ -8,6 +8,37 @@ use std::sync::OnceLock;
|
|||||||
pub struct GameConfig {
|
pub struct GameConfig {
|
||||||
pub initial_chunk_radius: i32,
|
pub initial_chunk_radius: i32,
|
||||||
pub spawn_counts: SpawnCounts,
|
pub spawn_counts: SpawnCounts,
|
||||||
|
#[serde(default)]
|
||||||
|
pub display: DisplaySettings,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Clone, Default)]
|
||||||
|
pub struct DisplaySettings {
|
||||||
|
#[serde(default)]
|
||||||
|
pub vsync: VsyncMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||||
|
pub enum VsyncMode {
|
||||||
|
#[default]
|
||||||
|
Vsync,
|
||||||
|
Mailbox,
|
||||||
|
Uncapped,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for VsyncMode {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
match s.as_str() {
|
||||||
|
"vsync" => Ok(VsyncMode::Vsync),
|
||||||
|
"mailbox" => Ok(VsyncMode::Mailbox),
|
||||||
|
"uncapped" => Ok(VsyncMode::Uncapped),
|
||||||
|
_ => Ok(VsyncMode::Vsync),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
|
|||||||
+17
-1
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
camera,
|
camera,
|
||||||
config::GameConfig,
|
config::{GameConfig, VsyncMode},
|
||||||
world::generation::{
|
world::generation::{
|
||||||
generate_chunk_fauna, generate_chunk_foliage, generate_chunk_forrestry,
|
generate_chunk_fauna, generate_chunk_foliage, generate_chunk_forrestry,
|
||||||
generate_chunk_weathering_and_precipitation, apply_terrain_blobs, spawn_terrain_tasks,
|
generate_chunk_weathering_and_precipitation, apply_terrain_blobs, spawn_terrain_tasks,
|
||||||
@@ -18,6 +18,21 @@ pub use chunks::management::*;
|
|||||||
pub use textures::management::*;
|
pub use textures::management::*;
|
||||||
pub use tiles::{prefabs::*, rendering::*, visibility::*};
|
pub use tiles::{prefabs::*, rendering::*, visibility::*};
|
||||||
|
|
||||||
|
pub fn apply_vsync_setting(
|
||||||
|
config: Res<GameConfig>,
|
||||||
|
mut windows: Query<&mut Window>,
|
||||||
|
) {
|
||||||
|
if config.is_changed() {
|
||||||
|
if let Ok(mut window) = windows.single_mut() {
|
||||||
|
window.present_mode = match config.display.vsync {
|
||||||
|
VsyncMode::Vsync => bevy::window::PresentMode::AutoVsync,
|
||||||
|
VsyncMode::Mailbox => bevy::window::PresentMode::Mailbox,
|
||||||
|
VsyncMode::Uncapped => bevy::window::PresentMode::AutoNoVsync,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WorldPlugin;
|
pub struct WorldPlugin;
|
||||||
|
|
||||||
impl Plugin for WorldPlugin {
|
impl Plugin for WorldPlugin {
|
||||||
@@ -58,6 +73,7 @@ impl Plugin for WorldPlugin {
|
|||||||
.after(crate::entities::item::item_tile_management_system),
|
.after(crate::entities::item::item_tile_management_system),
|
||||||
tiles::track_benchmark,
|
tiles::track_benchmark,
|
||||||
tiles::render_bench_report_system,
|
tiles::render_bench_report_system,
|
||||||
|
apply_vsync_setting,
|
||||||
handle_tile_occlusion_updates,
|
handle_tile_occlusion_updates,
|
||||||
tiles::spawn_tilemap_chunks,
|
tiles::spawn_tilemap_chunks,
|
||||||
tiles::on_camera_z_changed,
|
tiles::on_camera_z_changed,
|
||||||
|
|||||||
Reference in New Issue
Block a user