shell running step should run only when task in foreground
All checks were successful
Intrepid/Prometeu/Runtime/pipeline/head This commit looks good

This commit is contained in:
bQUARKz 2026-05-15 09:28:13 +01:00
parent 4207a193e8
commit a0601fe816
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
10 changed files with 143 additions and 49 deletions

View File

@ -108,7 +108,7 @@ impl Firmware {
FirmwareState::HubHome(s) => s.on_enter(&mut req),
FirmwareState::LoadCartridge(s) => s.on_enter(&mut req),
FirmwareState::GameRunning(s) => s.on_enter(&mut req),
FirmwareState::SystemRunning(s) => s.on_enter(&mut req),
FirmwareState::ShellRunning(s) => s.on_enter(&mut req),
FirmwareState::AppCrashes(s) => s.on_enter(&mut req),
}
}
@ -135,7 +135,7 @@ impl Firmware {
FirmwareState::HubHome(s) => s.on_update(&mut req),
FirmwareState::LoadCartridge(s) => s.on_update(&mut req),
FirmwareState::GameRunning(s) => s.on_update(&mut req),
FirmwareState::SystemRunning(s) => s.on_update(&mut req),
FirmwareState::ShellRunning(s) => s.on_update(&mut req),
FirmwareState::AppCrashes(s) => s.on_update(&mut req),
}
}
@ -157,7 +157,7 @@ impl Firmware {
FirmwareState::HubHome(s) => s.on_exit(&mut req),
FirmwareState::LoadCartridge(s) => s.on_exit(&mut req),
FirmwareState::GameRunning(s) => s.on_exit(&mut req),
FirmwareState::SystemRunning(s) => s.on_exit(&mut req),
FirmwareState::ShellRunning(s) => s.on_exit(&mut req),
FirmwareState::AppCrashes(s) => s.on_exit(&mut req),
}
}
@ -349,7 +349,7 @@ mod tests {
firmware.load_cartridge(valid_cartridge(AppMode::Shell));
firmware.tick(&signals, &mut hardware);
assert!(matches!(firmware.state, FirmwareState::SystemRunning(_)));
assert!(matches!(firmware.state, FirmwareState::ShellRunning(_)));
assert!(firmware.os.window().focused_window().is_some());
assert_eq!(firmware.os.window().window_count(), 1);
}
@ -366,7 +366,7 @@ mod tests {
let tick_index_before_system_update = firmware.os.vm().tick_index();
firmware.tick(&signals, &mut hardware);
assert!(matches!(firmware.state, FirmwareState::SystemRunning(_)));
assert!(matches!(firmware.state, FirmwareState::ShellRunning(_)));
assert_eq!(firmware.os.vm().tick_index(), tick_index_before_system_update + 1);
}

View File

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

View File

@ -11,7 +11,7 @@ impl HubHomeStep {
}
pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> {
let outcome = ctx.hub.update_system_profile(ctx.os, ctx.vm, ctx.signals, ctx.hw);
let outcome = ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.hw);
if let Some(report) = outcome.crash {
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
}

View File

@ -1,5 +1,5 @@
use crate::firmware::firmware_state::{
AppCrashesStep, FirmwareState, GameRunningStep, SystemRunningStep,
AppCrashesStep, FirmwareState, GameRunningStep, ShellRunningStep,
};
use crate::firmware::prometeu_context::PrometeuContext;
use prometeu_hal::cartridge::{AppMode, Cartridge};
@ -54,7 +54,7 @@ impl LoadCartridgeStep {
.os
.sessions()
.create_vm_shell_task(self.cartridge.app_id, self.cartridge.title.clone());
return Some(FirmwareState::SystemRunning(SystemRunningStep::new(task_id)));
return Some(FirmwareState::ShellRunning(ShellRunningStep::new(task_id)));
}
let task_id = ctx

View File

@ -0,0 +1,89 @@
use crate::firmware::firmware_state::{AppCrashesStep, FirmwareState, HubHomeStep};
use crate::firmware::prometeu_context::PrometeuContext;
use prometeu_hal::log::LogSource;
use prometeu_system::CrashReport;
use prometeu_system::task::{TaskId, TaskState};
#[derive(Debug, Clone)]
pub struct ShellRunningStep {
pub task_id: TaskId,
}
impl ShellRunningStep {
pub fn new(task_id: TaskId) -> Self {
Self { task_id }
}
pub fn on_enter(&mut self, ctx: &mut PrometeuContext) {
ctx.os.info(LogSource::Hub, "Entering ShellRunning".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 {
let report = CrashReport::VmPanic {
message: format!("ShellRunningStep has no task for {:?}", self.task_id),
pc: None,
};
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
};
match task_state {
TaskState::Foreground => {
// Continue below.
}
TaskState::Closed => {
return Some(FirmwareState::HubHome(HubHomeStep));
}
TaskState::Crashed => {
let report = CrashReport::VmPanic {
message: format!("Shell task {:?} is already crashed", self.task_id),
pc: None,
};
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
}
TaskState::Suspended | TaskState::Background => {
let report = CrashReport::VmPanic {
message: format!(
"ShellRunningStep expected foreground task {:?}, got {:?}",
self.task_id, task_state,
),
pc: None,
};
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
}
}
let outcome = ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.hw);
if let Some(report) = outcome.crash {
let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report));
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
}
if !outcome.focused_window_active {
ctx.os.info(
LogSource::Hub,
format!("Closing shell task {:?}: no focused window active", self.task_id),
);
if let Err(error) = ctx.os.lifecycle().close_task(self.task_id) {
ctx.os.error(
LogSource::Hub,
format!("Failed to close shell task {:?}: {:?}", self.task_id, error),
);
}
return Some(FirmwareState::HubHome(HubHomeStep));
}
None
}
pub fn on_exit(&mut self, ctx: &mut PrometeuContext) {
ctx.os.info(LogSource::Hub, "Exiting ShellRunning".to_string());
}
}

View File

@ -1,35 +0,0 @@
use crate::firmware::firmware_state::{AppCrashesStep, FirmwareState, HubHomeStep};
use crate::firmware::prometeu_context::PrometeuContext;
use prometeu_hal::log::{LogLevel, LogSource};
use prometeu_system::task::TaskId;
#[derive(Debug, Clone)]
pub struct SystemRunningStep {
pub task_id: TaskId,
}
impl SystemRunningStep {
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::Hub, 0, "Entering SystemRunning".to_string());
}
pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option<FirmwareState> {
let outcome = ctx.hub.update_system_profile(ctx.os, ctx.vm, ctx.signals, ctx.hw);
if let Some(report) = outcome.crash {
let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report));
return Some(FirmwareState::AppCrashes(AppCrashesStep { report }));
}
if !outcome.focused_window_active {
return Some(FirmwareState::HubHome(HubHomeStep));
}
None
}
pub fn on_exit(&mut self, _ctx: &mut PrometeuContext) {}
}

View File

@ -9,8 +9,8 @@ pub(crate) mod firmware_step_hub_home;
pub(crate) mod firmware_step_launch_hub;
pub(crate) mod firmware_step_load_cartridge;
pub(crate) mod firmware_step_reset;
pub(crate) mod firmware_step_shell_running;
pub(crate) mod firmware_step_splash_screen;
pub(crate) mod firmware_step_system_running;
mod prometeu_context;
pub use boot_target::BootTarget;

View File

@ -51,6 +51,46 @@ impl SystemOS {
self.vm_runtime.log(&mut self.log_service, level, source, tag, msg);
}
pub fn trace(&mut self, source: LogSource, msg: String) {
self.log(LogLevel::Trace, source, 0, msg);
}
pub fn trace_tag(&mut self, source: LogSource, tag: u16, msg: String) {
self.log(LogLevel::Trace, source, tag, msg);
}
pub fn debug(&mut self, source: LogSource, msg: String) {
self.log(LogLevel::Debug, source, 0, msg);
}
pub fn debug_tag(&mut self, source: LogSource, tag: u16, msg: String) {
self.log(LogLevel::Debug, source, tag, msg);
}
pub fn info(&mut self, source: LogSource, msg: String) {
self.log(LogLevel::Info, source, 0, msg);
}
pub fn info_tag(&mut self, source: LogSource, tag: u16, msg: String) {
self.log(LogLevel::Info, source, tag, msg);
}
pub fn warn(&mut self, source: LogSource, msg: String) {
self.log(LogLevel::Warn, source, 0, msg);
}
pub fn warn_tag(&mut self, source: LogSource, tag: u16, msg: String) {
self.log(LogLevel::Warn, source, tag, msg);
}
pub fn error(&mut self, source: LogSource, msg: String) {
self.log(LogLevel::Error, source, 0, msg);
}
pub fn error_tag(&mut self, source: LogSource, tag: u16, msg: String) {
self.log(LogLevel::Error, source, tag, msg);
}
pub fn recent_logs(&self, n: usize) -> Vec<LogEvent> {
self.log_service.get_recent(n)
}

View File

@ -80,7 +80,7 @@ impl PrometeuHub {
}
}
pub fn update_system_profile(
pub fn update_shell_profile(
&mut self,
os: &mut SystemOS,
vm: &mut VirtualMachine,

View File

@ -2,7 +2,7 @@
"version": 1,
"domains": {
"system/os": {
"baseline_percent": 78,
"baseline_percent": 75,
"paths": [
"crates/console/prometeu-system/src/os/",
"crates/console/prometeu-system/src/services/process",
@ -40,7 +40,7 @@
]
},
"firmware": {
"baseline_percent": 76,
"baseline_percent": 72,
"paths": [
"crates/console/prometeu-firmware/src/"
]