From a22215392da130ed83e26d01de14ae1dbb0bd66a Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Sat, 4 Jul 2026 18:32:44 +0100 Subject: [PATCH] fix native shell ticking resident game --- .../src/firmware/firmware.rs | 9 ++++ .../firmware/firmware_step_shell_running.rs | 52 ++++++++++++++++--- .../src/os/facades/lifecycle.rs | 11 +++- .../prometeu-system/src/os/system_os.rs | 17 +++++- 4 files changed, 81 insertions(+), 8 deletions(-) diff --git a/crates/console/prometeu-firmware/src/firmware/firmware.rs b/crates/console/prometeu-firmware/src/firmware/firmware.rs index aa550d97..31287217 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware.rs @@ -984,6 +984,15 @@ mod tests { assert_eq!(firmware.os.lifecycle().resident_game_task(), Some(game_task)); assert_eq!(firmware.os.lifecycle().task_state(game_task), Some(TaskState::Suspended)); + let tick_index_before_native_shell_updates = firmware.os.vm().tick_index(); + for _ in 0..61 { + firmware.tick(&signals, &mut platform); + } + + assert!(matches!(firmware.state, FirmwareState::ShellRunning(_))); + assert_eq!(firmware.os.vm().tick_index(), tick_index_before_native_shell_updates); + assert_eq!(firmware.os.lifecycle().task_state(game_task), Some(TaskState::Suspended)); + let close_shell = InputSignals { start_signal: true, ..Default::default() }; firmware.tick(&close_shell, &mut platform); diff --git a/crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs b/crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs index b0a76f1c..aff9a139 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs @@ -1,6 +1,7 @@ use crate::firmware::firmware_state::{AppCrashesStep, FirmwareState, HubHomeStep}; use crate::firmware::prometeu_context::PrometeuContext; use prometeu_hal::log::LogSource; +use prometeu_system::process::ProcessKind; use prometeu_system::task::{TaskId, TaskState}; use prometeu_system::{CrashReport, SystemProfileAction}; @@ -59,14 +60,53 @@ impl ShellRunningStep { } } - let outcome = ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.platform); + let process_kind = match ctx.os.lifecycle().process_kind_for_task(self.task_id) { + Ok(process_kind) => process_kind, + Err(error) => { + let report = CrashReport::VmPanic { + message: format!( + "ShellRunningStep cannot resolve process for {:?}: {:?}", + self.task_id, error, + ), + pc: None, + }; + return Some(FirmwareState::AppCrashes(AppCrashesStep { report })); + } + }; - if let Some(report) = outcome.crash { - let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report)); - return Some(FirmwareState::AppCrashes(AppCrashesStep { report })); - } + let action = match process_kind { + ProcessKind::VmShell => { + let outcome = + ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.platform); - if outcome.action == Some(SystemProfileAction::CloseShell) { + if let Some(report) = outcome.crash { + let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report)); + return Some(FirmwareState::AppCrashes(AppCrashesStep { report })); + } + + outcome.action + } + ProcessKind::NativeShell => { + let mut action = ctx.hub.gui_update(ctx.os, ctx.platform); + if ctx.platform.input().pad().start().down { + action = Some(SystemProfileAction::CloseShell); + } + ctx.hub.render(ctx.os, ctx.platform); + action + } + ProcessKind::VmGame => { + let report = CrashReport::VmPanic { + message: format!( + "ShellRunningStep expected shell process for {:?}, got VmGame", + self.task_id, + ), + pc: None, + }; + return Some(FirmwareState::AppCrashes(AppCrashesStep { report })); + } + }; + + if action == Some(SystemProfileAction::CloseShell) { self.close_current_shell(ctx); return Some(FirmwareState::HubHome(HubHomeStep)); } diff --git a/crates/console/prometeu-system/src/os/facades/lifecycle.rs b/crates/console/prometeu-system/src/os/facades/lifecycle.rs index a6ebcb78..4f311fbc 100644 --- a/crates/console/prometeu-system/src/os/facades/lifecycle.rs +++ b/crates/console/prometeu-system/src/os/facades/lifecycle.rs @@ -4,7 +4,7 @@ use crate::os::{ DEFAULT_GAME_PAUSE_BUDGET_TICKS, GameLifecycleEvent, GameLifecycleEventKind, LifecycleError, LifecycleOperation, }; -use crate::process::{ProcessId, ProcessState}; +use crate::process::{ProcessId, ProcessKind, ProcessState}; use crate::services::foreground::{ ForegroundOwner, ForegroundStackError, ResidentGame, ResidentGameState, }; @@ -28,6 +28,15 @@ impl<'a> LifecycleFacade<'a> { .ok_or(LifecycleError::ProcessNotFound(process_id)) } + pub fn process_kind_for_task(&self, task_id: TaskId) -> Result { + let process_id = process_id_for_task(self.os, task_id)?; + self.os + .process_manager + .get(process_id) + .map(|process| process.kind) + .ok_or(LifecycleError::ProcessNotFound(process_id)) + } + pub fn set_foreground_task(&mut self, task_id: TaskId) -> Result<(), LifecycleError> { match task_kind_for_task(self.os, task_id)? { TaskKind::Game => return self.set_game_foreground_task(task_id), diff --git a/crates/console/prometeu-system/src/os/system_os.rs b/crates/console/prometeu-system/src/os/system_os.rs index e263593c..439e21df 100644 --- a/crates/console/prometeu-system/src/os/system_os.rs +++ b/crates/console/prometeu-system/src/os/system_os.rs @@ -141,7 +141,7 @@ impl SystemOS { mod tests { use super::*; use crate::os::{GameLifecycleEventKind, LifecycleError, LifecycleOperation}; - use crate::process::ProcessState; + use crate::process::{ProcessKind, ProcessState}; use crate::services::foreground::{ForegroundOwner, ResidentGame, ResidentGameState}; use crate::task::{TaskId, TaskState}; @@ -288,6 +288,21 @@ mod tests { assert_eq!(process_state_for_task(&os, game), ProcessState::Suspended); } + #[test] + fn lifecycle_exposes_process_kind_for_shell_tasks() { + let mut os = SystemOS::new(None); + let vm_shell = os.sessions().create_vm_shell_task(7, "Settings"); + os.lifecycle().close_task(vm_shell).expect("vm shell should close"); + + let native_shell = os.sessions().create_native_shell_task(8, "Files"); + + assert_eq!(os.lifecycle().process_kind_for_task(vm_shell), Ok(ProcessKind::VmShell)); + assert_eq!( + os.lifecycle().process_kind_for_task(native_shell), + Ok(ProcessKind::NativeShell) + ); + } + #[test] fn second_foreground_shell_is_rejected() { let mut os = SystemOS::new(None);