142 lines
4.9 KiB
Rust
142 lines
4.9 KiB
Rust
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};
|
|
|
|
#[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 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 }));
|
|
}
|
|
};
|
|
|
|
let action = match process_kind {
|
|
ProcessKind::VmShell => {
|
|
let outcome =
|
|
ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.platform);
|
|
|
|
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));
|
|
}
|
|
|
|
if !ctx.os.windows().focused_window_belongs_to_task(self.task_id) {
|
|
ctx.os.info(
|
|
LogSource::Hub,
|
|
format!(
|
|
"Closing shell task {:?}: focused window does not belong to task",
|
|
self.task_id,
|
|
),
|
|
);
|
|
self.close_current_shell(ctx);
|
|
return Some(FirmwareState::HubHome(HubHomeStep));
|
|
}
|
|
|
|
None
|
|
}
|
|
|
|
fn close_current_shell(&mut self, ctx: &mut PrometeuContext) {
|
|
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),
|
|
);
|
|
}
|
|
}
|
|
|
|
pub fn on_exit(&mut self, ctx: &mut PrometeuContext) {
|
|
ctx.os.info(LogSource::Hub, "Exiting ShellRunning".to_string());
|
|
}
|
|
}
|