mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-10-21 19:20:34 +00:00
refactor(dev-tools): reorganize dev tools module code
This commit is contained in:
parent
dca6747f83
commit
9ecb38b442
126
src/dev_tools.rs
126
src/dev_tools.rs
@ -1,126 +0,0 @@
|
||||
//! Development tools for the game. This plugin is only enabled in dev builds.
|
||||
|
||||
use bevy::{
|
||||
dev_tools::{
|
||||
states::log_transitions,
|
||||
ui_debug_overlay::{DebugUiPlugin, UiDebugOptions},
|
||||
},
|
||||
input::common_conditions::input_just_pressed,
|
||||
prelude::*,
|
||||
window::PrimaryWindow,
|
||||
};
|
||||
|
||||
use bevy_inspector_egui::{bevy_egui::EguiContext, DefaultInspectorConfigPlugin};
|
||||
|
||||
use crate::{
|
||||
maze::{events::RecreateMazeEvent, MazeConfig},
|
||||
screens::Screen,
|
||||
};
|
||||
use bevy_egui::{
|
||||
egui::{self, Button, Color32, DragValue, ScrollArea},
|
||||
EguiPlugin,
|
||||
};
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
// Log `Screen` state transitions.
|
||||
app.add_systems(Update, log_transitions::<Screen>)
|
||||
.add_plugins(EguiPlugin)
|
||||
.add_plugins(DebugUiPlugin)
|
||||
.add_plugins(DefaultInspectorConfigPlugin)
|
||||
.add_systems(Update, inspector_ui)
|
||||
// Toggle the debug overlay for UI.
|
||||
.add_systems(
|
||||
Update,
|
||||
toggle_debug_ui.run_if(input_just_pressed(TOGGLE_KEY)),
|
||||
);
|
||||
}
|
||||
|
||||
const TOGGLE_KEY: KeyCode = KeyCode::Backquote;
|
||||
|
||||
fn toggle_debug_ui(mut options: ResMut<UiDebugOptions>) {
|
||||
options.toggle();
|
||||
}
|
||||
|
||||
fn inspector_ui(world: &mut World) {
|
||||
let Ok(egui_context) = world
|
||||
.query_filtered::<&mut EguiContext, With<PrimaryWindow>>()
|
||||
.get_single(world)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut egui_context = egui_context.clone();
|
||||
|
||||
egui::Window::new("UI").show(egui_context.get_mut(), |ui| {
|
||||
ScrollArea::vertical().show(ui, |ui| {
|
||||
bevy_inspector_egui::bevy_inspector::ui_for_world(world, ui);
|
||||
});
|
||||
});
|
||||
|
||||
egui::Window::new("Maze Controls").show(egui_context.get_mut(), |ui| {
|
||||
if let Some(mut maze_config) = world.get_resource_mut::<MazeConfig>() {
|
||||
ui.heading("Maze Configuration");
|
||||
|
||||
// radius controls
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Radius:");
|
||||
ui.add(
|
||||
DragValue::new(&mut maze_config.radius)
|
||||
.speed(1)
|
||||
.range(1..=100),
|
||||
);
|
||||
});
|
||||
|
||||
// height controls
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Height:");
|
||||
ui.add(
|
||||
DragValue::new(&mut maze_config.height)
|
||||
.speed(0.5)
|
||||
.range(1.0..=50.),
|
||||
);
|
||||
});
|
||||
|
||||
// start position
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Start Position:");
|
||||
ui.add(
|
||||
DragValue::new(&mut maze_config.start_pos.x)
|
||||
.speed(1)
|
||||
.prefix("x: "),
|
||||
);
|
||||
ui.add(
|
||||
DragValue::new(&mut maze_config.start_pos.y)
|
||||
.speed(1)
|
||||
.prefix("y: "),
|
||||
);
|
||||
});
|
||||
|
||||
// end position
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("End Position:");
|
||||
ui.add(
|
||||
DragValue::new(&mut maze_config.end_pos.x)
|
||||
.speed(1)
|
||||
.prefix("x: "),
|
||||
);
|
||||
ui.add(
|
||||
DragValue::new(&mut maze_config.end_pos.y)
|
||||
.speed(1)
|
||||
.prefix("y: "),
|
||||
);
|
||||
});
|
||||
|
||||
ui.add_space(8.);
|
||||
|
||||
let button = Button::new("Recreate maze").fill(Color32::from_rgb(108, 108, 108));
|
||||
if ui.add(button).clicked() {
|
||||
if let Some(mut event_writer) =
|
||||
world.get_resource_mut::<Events<RecreateMazeEvent>>()
|
||||
{
|
||||
event_writer.send(RecreateMazeEvent { floor: 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
4
src/dev_tools/mod.rs
Normal file
4
src/dev_tools/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod plugin;
|
||||
mod ui;
|
||||
|
||||
pub use plugin::DevToolsPlugin;
|
||||
36
src/dev_tools/plugin.rs
Normal file
36
src/dev_tools/plugin.rs
Normal file
@ -0,0 +1,36 @@
|
||||
use crate::screens::Screen;
|
||||
use bevy::{
|
||||
dev_tools::{
|
||||
states::log_transitions,
|
||||
ui_debug_overlay::{DebugUiPlugin, UiDebugOptions},
|
||||
},
|
||||
input::common_conditions::input_just_pressed,
|
||||
prelude::*,
|
||||
};
|
||||
use bevy_egui::EguiPlugin;
|
||||
use bevy_inspector_egui::DefaultInspectorConfigPlugin;
|
||||
|
||||
use super::ui::{inspector_ui, maze_controls_ui};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DevToolsPlugin;
|
||||
|
||||
impl Plugin for DevToolsPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Update, log_transitions::<Screen>)
|
||||
.add_plugins(EguiPlugin)
|
||||
.add_plugins(DebugUiPlugin)
|
||||
.add_plugins(DefaultInspectorConfigPlugin)
|
||||
.add_systems(Update, (inspector_ui, maze_controls_ui))
|
||||
.add_systems(
|
||||
Update,
|
||||
toggle_debug_ui.run_if(input_just_pressed(TOGGLE_KEY)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const TOGGLE_KEY: KeyCode = KeyCode::Backquote;
|
||||
|
||||
fn toggle_debug_ui(mut options: ResMut<UiDebugOptions>) {
|
||||
options.toggle();
|
||||
}
|
||||
20
src/dev_tools/ui/inspector.rs
Normal file
20
src/dev_tools/ui/inspector.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use bevy::{prelude::*, window::PrimaryWindow};
|
||||
use bevy_egui::egui::{self, ScrollArea};
|
||||
use bevy_inspector_egui::bevy_egui::EguiContext;
|
||||
|
||||
pub(crate) fn inspector_ui(world: &mut World) {
|
||||
let Ok(egui_context) = world
|
||||
.query_filtered::<&mut EguiContext, With<PrimaryWindow>>()
|
||||
.get_single(world)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut egui_context = egui_context.clone();
|
||||
|
||||
egui::Window::new("UI").show(egui_context.get_mut(), |ui| {
|
||||
ScrollArea::vertical().show(ui, |ui| {
|
||||
bevy_inspector_egui::bevy_inspector::ui_for_world(world, ui);
|
||||
});
|
||||
});
|
||||
}
|
||||
117
src/dev_tools/ui/maze_controls.rs
Normal file
117
src/dev_tools/ui/maze_controls.rs
Normal file
@ -0,0 +1,117 @@
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use bevy::{prelude::*, window::PrimaryWindow};
|
||||
use hexx::Hex;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use crate::maze::{events::RecreateMazeEvent, MazeConfig, MazePluginLoaded};
|
||||
use bevy_egui::{
|
||||
egui::{self, emath::Numeric, DragValue, TextEdit, Ui},
|
||||
EguiContext,
|
||||
};
|
||||
|
||||
pub(crate) fn maze_controls_ui(world: &mut World) {
|
||||
if world.get_resource::<MazePluginLoaded>().is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let Ok(egui_context) = world
|
||||
.query_filtered::<&mut EguiContext, With<PrimaryWindow>>()
|
||||
.get_single(world)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut egui_context = egui_context.clone();
|
||||
|
||||
egui::Window::new("Maze Controls").show(egui_context.get_mut(), |ui| {
|
||||
if let Some(mut maze_config) = world.get_resource_mut::<MazeConfig>() {
|
||||
let mut changed = false;
|
||||
ui.heading("Maze Configuration");
|
||||
|
||||
changed |= add_seed_control(ui, &mut maze_config.seed);
|
||||
|
||||
changed |= add_drag_value_control(ui, "Radius:", &mut maze_config.radius, 1.0, 1..=100);
|
||||
changed |=
|
||||
add_drag_value_control(ui, "Height:", &mut maze_config.height, 0.5, 1.0..=50.0);
|
||||
|
||||
changed |= add_position_control(ui, "Start Position:", &mut maze_config.start_pos);
|
||||
changed |= add_position_control(ui, "End Position:", &mut maze_config.end_pos);
|
||||
|
||||
// Trigger recreation if any value changed
|
||||
if changed {
|
||||
if let Some(mut event_writer) =
|
||||
world.get_resource_mut::<Events<RecreateMazeEvent>>()
|
||||
{
|
||||
event_writer.send(RecreateMazeEvent { floor: 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn add_drag_value_control<T: Numeric>(
|
||||
ui: &mut egui::Ui,
|
||||
label: &str,
|
||||
value: &mut T,
|
||||
speed: f64,
|
||||
range: RangeInclusive<T>,
|
||||
) -> bool {
|
||||
let mut changed = false;
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(label);
|
||||
let response = ui.add(DragValue::new(value).speed(speed).range(range));
|
||||
changed = response.changed();
|
||||
});
|
||||
changed
|
||||
}
|
||||
|
||||
fn add_position_control(ui: &mut Ui, label: &str, pos: &mut Hex) -> bool {
|
||||
let mut changed = false;
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(label);
|
||||
let response_x = ui.add(DragValue::new(&mut pos.x).speed(1).prefix("x: "));
|
||||
let response_y = ui.add(DragValue::new(&mut pos.y).speed(1).prefix("y: "));
|
||||
changed = response_x.changed() || response_y.changed();
|
||||
});
|
||||
changed
|
||||
}
|
||||
|
||||
fn add_seed_control(ui: &mut Ui, seed: &mut u64) -> bool {
|
||||
let mut changed = false;
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Seed:");
|
||||
|
||||
let mut seed_text = seed.to_string();
|
||||
|
||||
let response = ui.add(
|
||||
TextEdit::singleline(&mut seed_text)
|
||||
.desired_width(150.0)
|
||||
.hint_text("Enter seed"),
|
||||
);
|
||||
|
||||
// Parse text input when changed
|
||||
if response.changed() {
|
||||
if let Ok(new_seed) = seed_text.parse::<u64>() {
|
||||
*seed = new_seed;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// New random seed button
|
||||
if ui.button("🎲").clicked() {
|
||||
*seed = thread_rng().gen();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Copy button
|
||||
if ui.button("📋").clicked() {
|
||||
ui.output_mut(|o| o.copied_text = seed.to_string());
|
||||
}
|
||||
});
|
||||
|
||||
changed
|
||||
}
|
||||
5
src/dev_tools/ui/mod.rs
Normal file
5
src/dev_tools/ui/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
mod inspector;
|
||||
mod maze_controls;
|
||||
|
||||
pub(crate) use inspector::inspector_ui;
|
||||
pub(crate) use maze_controls::maze_controls_ui;
|
||||
@ -70,7 +70,7 @@ impl Plugin for AppPlugin {
|
||||
|
||||
// Enable dev tools for dev builds.
|
||||
#[cfg(feature = "dev")]
|
||||
app.add_plugins(dev_tools::plugin);
|
||||
app.add_plugins(dev_tools::DevToolsPlugin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,8 +7,8 @@ pub mod plugin;
|
||||
mod resources;
|
||||
mod systems;
|
||||
|
||||
pub use resources::MazeConfig;
|
||||
pub use resources::{MazeConfig, MazePluginLoaded};
|
||||
|
||||
pub fn spawn_grid(world: &mut World) {
|
||||
pub fn spawn_maze(world: &mut World) {
|
||||
MazePlugin.apply(world);
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ use super::{
|
||||
events::RecreateMazeEvent,
|
||||
resources::Layout,
|
||||
systems::{self, recreation::handle_maze_recreation_event},
|
||||
MazeConfig,
|
||||
MazeConfig, MazePluginLoaded,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
@ -24,6 +24,7 @@ impl Plugin for MazePlugin {
|
||||
|
||||
impl Command for MazePlugin {
|
||||
fn apply(self, world: &mut World) {
|
||||
world.insert_resource(MazePluginLoaded);
|
||||
world.run_system_once(systems::setup::setup);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,10 @@ use hexx::{Hex, HexLayout, HexOrientation};
|
||||
use rand::{rngs::StdRng, thread_rng, Rng, SeedableRng};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Default, Reflect, Resource)]
|
||||
#[reflect(Resource)]
|
||||
pub struct MazePluginLoaded;
|
||||
|
||||
pub(crate) const WALL_SIZE: f32 = 1.0;
|
||||
#[derive(Debug, Error)]
|
||||
pub enum MazeConfigError {
|
||||
|
||||
@ -5,7 +5,7 @@ use bevy::{input::common_conditions::input_just_pressed, prelude::*};
|
||||
#[cfg(feature = "demo")]
|
||||
use crate::demo::level::spawn_level as spawn_level_command;
|
||||
#[cfg(not(feature = "demo"))]
|
||||
use crate::maze::spawn_grid as spawn_level_command;
|
||||
use crate::maze::spawn_maze as spawn_level_command;
|
||||
use crate::{asset_tracking::LoadResource, audio::Music, screens::Screen};
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user