use crate::firmware::firmware_state::{AppCrashesStep, FirmwareState, HubHomeStep}; use crate::firmware::prometeu_context::PrometeuContext; use prometeu_hal::app_mode::AppMode; use prometeu_hal::log::{LogLevel, LogSource}; use prometeu_system::task::{TaskId, TaskState}; use prometeu_system::{CrashReport, ResidentGameState}; #[derive(Debug, Clone)] pub struct GameRunningStep { pub task_id: TaskId, } impl GameRunningStep { pub fn new(task_id: TaskId) -> Self { Self { task_id } } pub fn on_enter(&mut self, ctx: &mut PrometeuContext) { ctx.os.log(LogLevel::Info, LogSource::Pos, 0, "Entering GameRunning".to_string()); } pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option { let Some(task_state) = ctx.os.lifecycle().task_state(self.task_id) else { // TODO: is it panic? let report = CrashReport::VmPanic { message: "task is gone, panic!".to_string(), pc: None }; return Some(FirmwareState::AppCrashes(AppCrashesStep { report })); }; if task_state != TaskState::Foreground { // TODO: is it panic? let report = CrashReport::VmPanic { message: "should be running as foreground, panic!".to_string(), pc: None, }; let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report)); return Some(FirmwareState::AppCrashes(AppCrashesStep { report })); } let pause_requested = matches!( ctx.os.lifecycle().resident_game().map(|game| game.state), Some(ResidentGameState::PauseRequested { .. }) ); let result = ctx.os.vm().tick_session(self.task_id, ctx.signals, ctx.platform); if let Some(report) = result { let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report)); return Some(FirmwareState::AppCrashes(AppCrashesStep { report })); } if pause_requested { match ctx.os.lifecycle().advance_game_pause_budget(self.task_id) { Ok(true) => { ctx.os.vm().transition_render_owner(AppMode::Shell, 0); return Some(FirmwareState::HubHome(HubHomeStep)); } Ok(false) => {} Err(_) => { let report = CrashReport::VmPanic { message: "failed to advance game pause budget".to_string(), pc: None, }; let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report)); return Some(FirmwareState::AppCrashes(AppCrashesStep { report })); } } } None } pub fn on_exit(&mut self, _ctx: &mut PrometeuContext) {} }