|
|
|
|
@ -1,3 +1,6 @@
|
|
|
|
|
use bevy::input_focus::tab_navigation::TabGroup;
|
|
|
|
|
use engine::theme::ThemedText;
|
|
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
/// Debug UI for Tetris
|
|
|
|
|
@ -14,34 +17,76 @@ pub struct DebugPlugin;
|
|
|
|
|
impl Plugin for DebugPlugin {
|
|
|
|
|
fn build(&self, app: &mut App) {
|
|
|
|
|
app
|
|
|
|
|
.init_state::<Debugger>()
|
|
|
|
|
.init_state::<DebugState>()
|
|
|
|
|
.add_systems(Startup, setup_ui)
|
|
|
|
|
.add_systems(Update,
|
|
|
|
|
// Logging state transitions
|
|
|
|
|
(
|
|
|
|
|
log_transition::<Debugger>.run_if(state_changed::<Debugger>),
|
|
|
|
|
log_transition::<DebugState>.run_if(state_changed::<DebugState>),
|
|
|
|
|
log_transition::<Loading>.run_if(state_changed::<Loading>),
|
|
|
|
|
log_transition::<GameState>.run_if(state_changed::<GameState>),
|
|
|
|
|
))
|
|
|
|
|
.add_systems(Update, toggle_debug.run_if(input_just_pressed(KeyCode::F12)));
|
|
|
|
|
.add_systems(Update, toggle_debug.run_if(input_just_pressed(KeyCode::F12)))
|
|
|
|
|
.add_systems(Update,
|
|
|
|
|
(
|
|
|
|
|
toggle_state_visibility::<DebugState>,
|
|
|
|
|
sync_state_to_ui::<DebugState>,
|
|
|
|
|
).run_if(state_changed::<DebugState>)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Tracks if the game is in debug mode
|
|
|
|
|
#[derive(States, Default, Clone, Eq, Debug, PartialEq, Hash)]
|
|
|
|
|
pub enum Debugger {
|
|
|
|
|
#[default]
|
|
|
|
|
Off,
|
|
|
|
|
On,
|
|
|
|
|
#[derive(States, Default, Clone, Eq, Debug, PartialEq, Hash, Component)]
|
|
|
|
|
pub struct DebugState(bool);
|
|
|
|
|
|
|
|
|
|
impl From<bool> for DebugState {
|
|
|
|
|
fn from(b: bool) -> Self {
|
|
|
|
|
DebugState(b)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Display for DebugState {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
write!(f, "DebugState {}", self.0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Setup the debugger UI
|
|
|
|
|
fn setup_ui(
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
) {
|
|
|
|
|
commands.spawn(
|
|
|
|
|
(toggle_switch((),), observe(checkbox_self_update)),
|
|
|
|
|
);
|
|
|
|
|
commands.spawn((
|
|
|
|
|
Node {
|
|
|
|
|
display: Display::Flex,
|
|
|
|
|
flex_direction: FlexDirection::Row,
|
|
|
|
|
align_items: AlignItems::Center,
|
|
|
|
|
justify_content: JustifyContent::Start,
|
|
|
|
|
column_gap: px(8),
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
TabGroup::default(),
|
|
|
|
|
children![
|
|
|
|
|
(Text::new("debugger:"), ThemedText),
|
|
|
|
|
(toggle_switch((),), observe(checkbox_self_update), observe(debug_toggle)),
|
|
|
|
|
],
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
commands.spawn((
|
|
|
|
|
Node {
|
|
|
|
|
bottom: px(0.0),
|
|
|
|
|
left: px(0.0),
|
|
|
|
|
position_type: PositionType::Absolute,
|
|
|
|
|
flex_direction: FlexDirection::Column,
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
DebugState(true),
|
|
|
|
|
children![
|
|
|
|
|
(Text::new("DebugState State"), SyncState::<DebugState>::default()),
|
|
|
|
|
(Text::new("Loading State"), SyncState::<Loading>::default()),
|
|
|
|
|
(Text::new("Game State"), SyncState::<GameState>::default()),
|
|
|
|
|
]
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Logs all state transitions for state T
|
|
|
|
|
@ -58,13 +103,13 @@ fn log_transition<T: States + PartialEq + Clone>(
|
|
|
|
|
|
|
|
|
|
/// Toggle the debug state when a key is pressed
|
|
|
|
|
fn toggle_debug(
|
|
|
|
|
curr: Res<State<Debugger>>,
|
|
|
|
|
mut next: ResMut<NextState<Debugger>>,
|
|
|
|
|
curr: Res<State<DebugState>>,
|
|
|
|
|
mut next: ResMut<NextState<DebugState>>,
|
|
|
|
|
) {
|
|
|
|
|
next.set(
|
|
|
|
|
match curr.get() {
|
|
|
|
|
Debugger::On => Debugger::Off,
|
|
|
|
|
Debugger::Off => Debugger::On,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
next.set(DebugState(!curr.get().0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn debug_toggle(event: On<ValueChange<bool>>, mut next_state: ResMut<NextState<DebugState>>) {
|
|
|
|
|
info!("Debug State Toggled: {:?}", event.event().value);
|
|
|
|
|
next_state.set(event.event().value.into());
|
|
|
|
|
}
|
|
|
|
|
|