bQUARKz be684ab0f9
All checks were successful
Intrepid/Prometeu/Runtime/pipeline/head This commit looks good
Intrepid/Prometeu/Runtime/pipeline/pr-master This commit looks good
add process and task managers
2026-05-14 17:39:55 +01:00

181 lines
5.1 KiB
Rust

use crate::process::{Process, ProcessId, ProcessKind, ProcessState};
use std::collections::HashMap;
#[derive(Debug, Default)]
pub struct ProcessManager {
next_id: u32,
processes: HashMap<ProcessId, Process>,
}
impl ProcessManager {
pub fn new() -> Self {
Self { next_id: 1, processes: HashMap::new() }
}
pub fn spawn_vm_game(&mut self, app_id: u32, title: impl Into<String>) -> ProcessId {
self.spawn(app_id, title, ProcessKind::VmGame)
}
pub fn spawn_vm_shell(&mut self, app_id: u32, title: impl Into<String>) -> ProcessId {
self.spawn(app_id, title, ProcessKind::VmShell)
}
pub fn spawn_native_shell(&mut self, app_id: u32, title: impl Into<String>) -> ProcessId {
self.spawn(app_id, title, ProcessKind::NativeShell)
}
fn spawn(&mut self, app_id: u32, title: impl Into<String>, kind: ProcessKind) -> ProcessId {
let id = ProcessId(self.next_id);
self.next_id += 1;
let mut process = Process::new(id, app_id, title, kind);
process.mark_running();
self.processes.insert(id, process);
id
}
pub fn get(&self, id: ProcessId) -> Option<&Process> {
self.processes.get(&id)
}
pub fn get_mut(&mut self, id: ProcessId) -> Option<&mut Process> {
self.processes.get_mut(&id)
}
pub fn contains(&self, id: ProcessId) -> bool {
self.processes.contains_key(&id)
}
pub fn all(&self) -> impl Iterator<Item = &Process> {
self.processes.values()
}
pub fn mark_running(&mut self, id: ProcessId) -> bool {
self.transition(id, ProcessState::Running)
}
pub fn mark_suspended(&mut self, id: ProcessId) -> bool {
self.transition(id, ProcessState::Suspended)
}
pub fn mark_stopped(&mut self, id: ProcessId) -> bool {
self.transition(id, ProcessState::Stopped)
}
pub fn mark_crashed(&mut self, id: ProcessId) -> bool {
self.transition(id, ProcessState::Crashed)
}
pub fn remove_stopped(&mut self) {
self.processes.retain(|_, process| process.state != ProcessState::Stopped);
}
fn transition(&mut self, id: ProcessId, state: ProcessState) -> bool {
let Some(process) = self.get_mut(id) else {
return false;
};
process.state = state;
true
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn spawn_vm_game_creates_running_process() {
let mut manager = ProcessManager::new();
let id = manager.spawn_vm_game(42, "Amazing Game");
let process = manager.get(id).expect("process should exist");
assert_eq!(process.id, id);
assert_eq!(process.app_id, 42);
assert_eq!(process.title, "Amazing Game");
assert_eq!(process.kind, ProcessKind::VmGame);
assert_eq!(process.state, ProcessState::Running);
}
#[test]
fn spawn_vm_shell_creates_running_process() {
let mut manager = ProcessManager::new();
let id = manager.spawn_vm_shell(42, "Amazing Shell");
let process = manager.get(id).expect("process should exist");
assert_eq!(process.id, id);
assert_eq!(process.app_id, 42);
assert_eq!(process.title, "Amazing Shell");
assert_eq!(process.kind, ProcessKind::VmShell);
assert_eq!(process.state, ProcessState::Running);
}
#[test]
fn spawn_native_shell_creates_running_process() {
let mut manager = ProcessManager::new();
let id = manager.spawn_native_shell(42, "Amazing Shell");
let process = manager.get(id).expect("process should exist");
assert_eq!(process.id, id);
assert_eq!(process.app_id, 42);
assert_eq!(process.title, "Amazing Shell");
assert_eq!(process.kind, ProcessKind::NativeShell);
assert_eq!(process.state, ProcessState::Running);
}
#[test]
fn mark_suspended_updates_process_state() {
let mut manager = ProcessManager::new();
let id = manager.spawn_vm_game(42, "Amazing Game");
assert!(manager.mark_suspended(id));
let process = manager.get(id).expect("process should exist");
assert_eq!(process.state, ProcessState::Suspended);
}
#[test]
fn mark_stopped_updates_process_state() {
let mut manager = ProcessManager::new();
let id = manager.spawn_vm_game(42, "Amazing Game");
assert!(manager.mark_stopped(id));
let process = manager.get(id).expect("process should exist");
assert_eq!(process.state, ProcessState::Stopped);
}
#[test]
fn unknown_process_transition_returns_false() {
let mut manager = ProcessManager::new();
assert!(!manager.mark_stopped(ProcessId(999)));
}
#[test]
fn remove_stopped_keeps_running_processes() {
let mut manager = ProcessManager::new();
let running = manager.spawn_vm_game(1, "Running");
let stopped = manager.spawn_vm_game(2, "Stopped");
manager.mark_stopped(stopped);
manager.remove_stopped();
assert!(manager.get(running).is_some());
assert!(manager.get(stopped).is_none());
}
}