162 lines
4.7 KiB
Rust
162 lines
4.7 KiB
Rust
use crate::features::savegame::messages::SavegameDumpMessage;
|
|
use crate::prelude::*;
|
|
use components::{SessionTracker, TimerSettings};
|
|
use messages::*;
|
|
|
|
pub mod components;
|
|
pub mod messages;
|
|
pub mod utils;
|
|
|
|
pub struct PhasePlugin;
|
|
|
|
impl Plugin for PhasePlugin {
|
|
fn build(&self, app: &mut App) {
|
|
app.init_resource::<TimerSettings>();
|
|
app.init_resource::<SessionTracker>();
|
|
app.insert_resource(CurrentPhase(Phase::Focus {
|
|
duration: 25.0 * 60.0,
|
|
}));
|
|
|
|
app.add_message::<PhaseTimerFinishedMessage>();
|
|
|
|
app.add_systems(OnEnter(AppState::GameScreen), load_rules);
|
|
app.add_systems(
|
|
Update,
|
|
(tick_timer, handle_pause, handle_continue).run_if(in_state(AppState::GameScreen)),
|
|
);
|
|
|
|
#[cfg(debug_assertions)]
|
|
app.add_systems(Update, debug_short_phase_duration);
|
|
}
|
|
}
|
|
|
|
#[cfg(debug_assertions)]
|
|
fn debug_short_phase_duration(
|
|
mut phase_res: ResMut<CurrentPhase>,
|
|
keys: Res<ButtonInput<KeyCode>>,
|
|
) {
|
|
if keys.any_pressed([KeyCode::ShiftLeft, KeyCode::ShiftRight])
|
|
&& keys.just_pressed(KeyCode::Enter)
|
|
{
|
|
let phase = &mut phase_res.0;
|
|
match phase {
|
|
Phase::Focus { duration } | Phase::Break { duration } => {
|
|
*duration = 3.0;
|
|
println!("Debug: Phase duration set to 3 seconds!");
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn load_rules(mut phase_res: ResMut<CurrentPhase>, settings: Res<TimerSettings>) {
|
|
let phase = &mut phase_res.0;
|
|
|
|
let new_phase = match phase {
|
|
Phase::Focus { .. } => Some(Phase::Focus {
|
|
duration: settings.focus_duration,
|
|
}),
|
|
Phase::Break { .. } => Some(Phase::Break { duration: 0.0 }),
|
|
_ => None,
|
|
};
|
|
|
|
if let Some(p) = new_phase {
|
|
*phase = p;
|
|
}
|
|
}
|
|
|
|
fn tick_timer(
|
|
time: Res<Time>,
|
|
mut phase_res: ResMut<CurrentPhase>,
|
|
mut finish_writer: MessageWriter<PhaseTimerFinishedMessage>,
|
|
mut savegame_messages: MessageWriter<SavegameDumpMessage>,
|
|
) {
|
|
let delta = time.delta_secs();
|
|
let phase = &mut phase_res.0;
|
|
|
|
match phase {
|
|
Phase::Focus { duration } | Phase::Break { duration } => {
|
|
*duration -= delta;
|
|
|
|
if *duration <= 0.0 {
|
|
finish_writer.write(PhaseTimerFinishedMessage {
|
|
phase: phase.clone(),
|
|
});
|
|
let completed = phase.clone();
|
|
*phase = Phase::Finished {
|
|
completed_phase: Box::new(completed),
|
|
};
|
|
|
|
println!("phase ended");
|
|
savegame_messages.write(SavegameDumpMessage);
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn handle_pause(
|
|
mut messages: MessageReader<PhaseTimerPauseMessage>,
|
|
mut phase_res: ResMut<CurrentPhase>,
|
|
) {
|
|
for _ in messages.read() {
|
|
let phase = &mut phase_res.0;
|
|
|
|
match phase {
|
|
Phase::Focus { .. } | Phase::Break { .. } => {
|
|
let current_state = phase.clone();
|
|
*phase = Phase::Paused {
|
|
previous_phase: Box::new(current_state),
|
|
};
|
|
println!("Phase paused");
|
|
}
|
|
Phase::Paused { previous_phase } => {
|
|
*phase = *previous_phase.clone();
|
|
println!("Phase resumed");
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn handle_continue(
|
|
mut messages: MessageReader<NextPhaseMessage>,
|
|
mut phase_res: ResMut<CurrentPhase>,
|
|
mut session_tracker: ResMut<SessionTracker>,
|
|
settings: Res<TimerSettings>,
|
|
) {
|
|
for _ in messages.read() {
|
|
let phase = &mut phase_res.0;
|
|
|
|
if let Phase::Finished { completed_phase } = phase {
|
|
match **completed_phase {
|
|
Phase::Focus { .. } => {
|
|
session_tracker.completed_focus_phases += 1;
|
|
|
|
// TODO: add berry grant logic
|
|
|
|
let is_long_break = session_tracker.completed_focus_phases > 0
|
|
&& session_tracker.completed_focus_phases % settings.long_break_interval
|
|
== 0;
|
|
|
|
if is_long_break {
|
|
*phase = Phase::Break {
|
|
duration: settings.long_break_duration,
|
|
};
|
|
} else {
|
|
*phase = Phase::Break {
|
|
duration: settings.short_break_duration,
|
|
};
|
|
}
|
|
}
|
|
Phase::Break { .. } => {
|
|
*phase = Phase::Focus {
|
|
duration: 25.0 * 60.0,
|
|
};
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
}
|