implements PLN-0047 firmware profile dispatch

This commit is contained in:
bQUARKz 2026-05-14 13:25:24 +01:00
parent da908ffcb4
commit bea3f76aa7
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
7 changed files with 48 additions and 8 deletions

View File

@ -108,6 +108,7 @@ impl Firmware {
FirmwareState::HubHome(s) => s.on_enter(&mut req), FirmwareState::HubHome(s) => s.on_enter(&mut req),
FirmwareState::LoadCartridge(s) => s.on_enter(&mut req), FirmwareState::LoadCartridge(s) => s.on_enter(&mut req),
FirmwareState::GameRunning(s) => s.on_enter(&mut req), FirmwareState::GameRunning(s) => s.on_enter(&mut req),
FirmwareState::SystemRunning(s) => s.on_enter(&mut req),
FirmwareState::AppCrashes(s) => s.on_enter(&mut req), FirmwareState::AppCrashes(s) => s.on_enter(&mut req),
} }
} }
@ -134,6 +135,7 @@ impl Firmware {
FirmwareState::HubHome(s) => s.on_update(&mut req), FirmwareState::HubHome(s) => s.on_update(&mut req),
FirmwareState::LoadCartridge(s) => s.on_update(&mut req), FirmwareState::LoadCartridge(s) => s.on_update(&mut req),
FirmwareState::GameRunning(s) => s.on_update(&mut req), FirmwareState::GameRunning(s) => s.on_update(&mut req),
FirmwareState::SystemRunning(s) => s.on_update(&mut req),
FirmwareState::AppCrashes(s) => s.on_update(&mut req), FirmwareState::AppCrashes(s) => s.on_update(&mut req),
} }
} }
@ -155,6 +157,7 @@ impl Firmware {
FirmwareState::HubHome(s) => s.on_exit(&mut req), FirmwareState::HubHome(s) => s.on_exit(&mut req),
FirmwareState::LoadCartridge(s) => s.on_exit(&mut req), FirmwareState::LoadCartridge(s) => s.on_exit(&mut req),
FirmwareState::GameRunning(s) => s.on_exit(&mut req), FirmwareState::GameRunning(s) => s.on_exit(&mut req),
FirmwareState::SystemRunning(s) => s.on_exit(&mut req),
FirmwareState::AppCrashes(s) => s.on_exit(&mut req), FirmwareState::AppCrashes(s) => s.on_exit(&mut req),
} }
} }
@ -327,7 +330,7 @@ mod tests {
} }
#[test] #[test]
fn load_cartridge_routes_system_apps_back_to_hub_home() { fn load_cartridge_routes_system_apps_to_system_running() {
let mut firmware = Firmware::new(None); let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new(); let mut hardware = Hardware::new();
let signals = InputSignals::default(); let signals = InputSignals::default();
@ -335,7 +338,9 @@ mod tests {
firmware.load_cartridge(valid_cartridge(AppMode::System)); firmware.load_cartridge(valid_cartridge(AppMode::System));
firmware.tick(&signals, &mut hardware); firmware.tick(&signals, &mut hardware);
assert!(matches!(firmware.state, FirmwareState::HubHome(_))); assert!(matches!(firmware.state, FirmwareState::SystemRunning(_)));
assert!(firmware.hub.window_manager.focused.is_some());
assert_eq!(firmware.hub.window_manager.windows.len(), 1);
} }
#[test] #[test]

View File

@ -5,6 +5,7 @@ pub use crate::firmware::firmware_step_launch_hub::LaunchHubStep;
pub use crate::firmware::firmware_step_load_cartridge::LoadCartridgeStep; pub use crate::firmware::firmware_step_load_cartridge::LoadCartridgeStep;
pub use crate::firmware::firmware_step_reset::ResetStep; pub use crate::firmware::firmware_step_reset::ResetStep;
pub use crate::firmware::firmware_step_splash_screen::SplashScreenStep; pub use crate::firmware::firmware_step_splash_screen::SplashScreenStep;
pub use crate::firmware::firmware_step_system_running::SystemRunningStep;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum FirmwareState { pub enum FirmwareState {
@ -14,5 +15,6 @@ pub enum FirmwareState {
HubHome(HubHomeStep), HubHome(HubHomeStep),
LoadCartridge(LoadCartridgeStep), LoadCartridge(LoadCartridgeStep),
GameRunning(GameRunningStep), GameRunning(GameRunningStep),
SystemRunning(SystemRunningStep),
AppCrashes(AppCrashesStep), AppCrashes(AppCrashesStep),
} }

View File

@ -1,5 +1,5 @@
use crate::firmware::firmware_state::{ use crate::firmware::firmware_state::{
AppCrashesStep, FirmwareState, GameRunningStep, HubHomeStep, AppCrashesStep, FirmwareState, GameRunningStep, SystemRunningStep,
}; };
use crate::firmware::prometeu_context::PrometeuContext; use crate::firmware::prometeu_context::PrometeuContext;
use prometeu_hal::cartridge::{AppMode, Cartridge}; use prometeu_hal::cartridge::{AppMode, Cartridge};
@ -50,9 +50,7 @@ impl LoadCartridgeStep {
); );
ctx.hub.window_manager.set_focus(id); ctx.hub.window_manager.set_focus(id);
// System apps do not change the firmware state to GameRunning. return Some(FirmwareState::SystemRunning(SystemRunningStep));
// They run in the background or via windows in the Hub.
return Some(FirmwareState::HubHome(HubHomeStep));
} }
Some(FirmwareState::GameRunning(GameRunningStep)) Some(FirmwareState::GameRunning(GameRunningStep))

View File

@ -0,0 +1,34 @@
use crate::firmware::firmware_state::{AppCrashesStep, FirmwareState, HubHomeStep};
use crate::firmware::prometeu_context::PrometeuContext;
use prometeu_hal::log::{LogLevel, LogSource};
#[derive(Debug, Clone)]
pub struct SystemRunningStep;
impl SystemRunningStep {
pub fn on_enter(&mut self, ctx: &mut PrometeuContext) {
ctx.os.log(LogLevel::Info, LogSource::Hub, 0, "Entering SystemRunning".to_string());
}
pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> {
let mut error = None;
ctx.hub.gui_update(ctx.os, ctx.hw);
if let Some(focused_id) = ctx.hub.window_manager.focused {
if ctx.hw.pad().start().down {
ctx.hub.window_manager.remove_window(focused_id);
return Some(FirmwareState::HubHome(HubHomeStep));
}
error = ctx.os.tick(ctx.vm, ctx.signals, ctx.hw);
}
ctx.hub.render(ctx.os, ctx.hw);
ctx.hw.gfx_mut().present();
error.map(|report| FirmwareState::AppCrashes(AppCrashesStep { report }))
}
pub fn on_exit(&mut self, _ctx: &mut PrometeuContext) {}
}

View File

@ -10,6 +10,7 @@ pub(crate) mod firmware_step_launch_hub;
pub(crate) mod firmware_step_load_cartridge; pub(crate) mod firmware_step_load_cartridge;
pub(crate) mod firmware_step_reset; pub(crate) mod firmware_step_reset;
pub(crate) mod firmware_step_splash_screen; pub(crate) mod firmware_step_splash_screen;
pub(crate) mod firmware_step_system_running;
mod prometeu_context; mod prometeu_context;
pub use boot_target::BootTarget; pub use boot_target::BootTarget;

View File

@ -29,4 +29,4 @@
{"type":"discussion","id":"DSC-0018","status":"done","ticket":"asset-load-asset-id-int-contract","title":"Asset Load Asset ID Int Contract","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["asset","runtime","abi"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0019","file":"discussion/lessons/DSC-0018-asset-load-asset-id-int-contract/LSN-0019-asset-load-id-abi-convergence.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]} {"type":"discussion","id":"DSC-0018","status":"done","ticket":"asset-load-asset-id-int-contract","title":"Asset Load Asset ID Int Contract","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["asset","runtime","abi"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0019","file":"discussion/lessons/DSC-0018-asset-load-asset-id-int-contract/LSN-0019-asset-load-id-abi-convergence.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]}
{"type":"discussion","id":"DSC-0019","status":"done","ticket":"jenkinsfile-correction","title":"Jenkinsfile Correction and Relocation","created_at":"2026-04-07","updated_at":"2026-04-07","tags":["ci","jenkins"],"agendas":[{"id":"AGD-0017","file":"AGD-0017-jenkinsfile-correction.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"decisions":[{"id":"DEC-0002","file":"DEC-0002-jenkinsfile-strategy.md","status":"accepted","created_at":"2026-04-07","updated_at":"2026-04-07"}],"plans":[{"id":"PLN-0002","file":"PLN-0002-jenkinsfile-execution.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"lessons":[{"id":"LSN-0020","file":"discussion/lessons/DSC-0019-jenkins-ci-standardization/LSN-0020-jenkins-standard-relocation.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}]} {"type":"discussion","id":"DSC-0019","status":"done","ticket":"jenkinsfile-correction","title":"Jenkinsfile Correction and Relocation","created_at":"2026-04-07","updated_at":"2026-04-07","tags":["ci","jenkins"],"agendas":[{"id":"AGD-0017","file":"AGD-0017-jenkinsfile-correction.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"decisions":[{"id":"DEC-0002","file":"DEC-0002-jenkinsfile-strategy.md","status":"accepted","created_at":"2026-04-07","updated_at":"2026-04-07"}],"plans":[{"id":"PLN-0002","file":"PLN-0002-jenkinsfile-execution.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"lessons":[{"id":"LSN-0020","file":"discussion/lessons/DSC-0019-jenkins-ci-standardization/LSN-0020-jenkins-standard-relocation.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}]}
{"type":"discussion","id":"DSC-0030","status":"done","ticket":"internal-viewport-270p","title":"Agenda - Internal Viewport 270p (480x270)","created_at":"2026-04-27","updated_at":"2026-04-28","tags":["gfx","runtime","viewport","resolution","frame-composer","host"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0039","file":"discussion/lessons/DSC-0030-internal-viewport-270p/LSN-0039-resolution-baseline-changes-are-runtime-wide-contracts.md","status":"done","created_at":"2026-04-28","updated_at":"2026-04-28"}]} {"type":"discussion","id":"DSC-0030","status":"done","ticket":"internal-viewport-270p","title":"Agenda - Internal Viewport 270p (480x270)","created_at":"2026-04-27","updated_at":"2026-04-28","tags":["gfx","runtime","viewport","resolution","frame-composer","host"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0039","file":"discussion/lessons/DSC-0030-internal-viewport-270p/LSN-0039-resolution-baseline-changes-are-runtime-wide-contracts.md","status":"done","created_at":"2026-04-28","updated_at":"2026-04-28"}]}
{"type":"discussion","id":"DSC-0031","status":"in_progress","ticket":"runtime-mode-separation-game-system","title":"Agenda - Runtime Mode Separation: Game and System","created_at":"2026-05-11","updated_at":"2026-05-14","tags":["runtime","firmware","hub","system-apps","game-mode","scheduler"],"agendas":[{"id":"AGD-0031","file":"AGD-0031-runtime-mode-separation-game-system.md","status":"accepted","created_at":"2026-05-11","updated_at":"2026-05-14"}],"decisions":[{"id":"DEC-0023","file":"DEC-0023-system-pipeline-separation.md","status":"accepted","created_at":"2026-05-14","updated_at":"2026-05-14"}],"plans":[{"id":"PLN-0046","file":"PLN-0046-profile-separation-specification.md","status":"done","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0047","file":"PLN-0047-firmware-runtime-profile-dispatch.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0048","file":"PLN-0048-minimal-system-hub-pipeline.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0049","file":"PLN-0049-system-profile-abi-gates.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0050","file":"PLN-0050-system-pipeline-evidence-and-learning.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]}],"lessons":[]} {"type":"discussion","id":"DSC-0031","status":"in_progress","ticket":"runtime-mode-separation-game-system","title":"Agenda - Runtime Mode Separation: Game and System","created_at":"2026-05-11","updated_at":"2026-05-14","tags":["runtime","firmware","hub","system-apps","game-mode","scheduler"],"agendas":[{"id":"AGD-0031","file":"AGD-0031-runtime-mode-separation-game-system.md","status":"accepted","created_at":"2026-05-11","updated_at":"2026-05-14"}],"decisions":[{"id":"DEC-0023","file":"DEC-0023-system-pipeline-separation.md","status":"accepted","created_at":"2026-05-14","updated_at":"2026-05-14"}],"plans":[{"id":"PLN-0046","file":"PLN-0046-profile-separation-specification.md","status":"done","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0047","file":"PLN-0047-firmware-runtime-profile-dispatch.md","status":"done","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0048","file":"PLN-0048-minimal-system-hub-pipeline.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0049","file":"PLN-0049-system-profile-abi-gates.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]},{"id":"PLN-0050","file":"PLN-0050-system-pipeline-evidence-and-learning.md","status":"open","created_at":"2026-05-14","updated_at":"2026-05-14","ref_decisions":["DEC-0023"]}],"lessons":[]}

View File

@ -2,7 +2,7 @@
id: PLN-0047 id: PLN-0047
ticket: runtime-mode-separation-game-system ticket: runtime-mode-separation-game-system
title: Firmware Runtime Profile Dispatch title: Firmware Runtime Profile Dispatch
status: open status: done
created: 2026-05-14 created: 2026-05-14
completed: completed:
ref_decisions: [DEC-0023] ref_decisions: [DEC-0023]