2026-07-04 19:40:05 +01:00

74 lines
2.8 KiB
Rust

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<FirmwareState> {
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) {}
}