fix native shell ticking resident game
This commit is contained in:
parent
e19409a2ef
commit
a22215392d
@ -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);
|
||||
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
@ -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<ProcessKind, LifecycleError> {
|
||||
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),
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user