feat: migrate to parking_lot mutex and add system control architecture

This commit is contained in:
Jan-Peter von Hunnius 2026-02-28 18:27:27 +01:00
parent 14060e15e5
commit 54144d10e9
29 changed files with 2387 additions and 1130 deletions

View file

@ -48,7 +48,10 @@
//! - Recovery options are provided where applicable
use super::state::GuiState;
use crate::system_config::{ConfigurableSystem, SystemController};
use eframe::egui;
use parking_lot::Mutex;
use std::sync::Arc;
/// Container for all GUI components
///
@ -120,8 +123,14 @@ impl GuiComponents {
/// # Arguments
/// * `ui` - egui UI context for rendering
/// * `state` - Mutable reference to GUI state for control operations
pub fn render_control_panel(&mut self, ui: &mut egui::Ui, state: &mut GuiState) {
self.control_panel.render(ui, state);
/// * `system` - Optional reference to the emulator system for actual control
pub fn render_control_panel(
&mut self,
ui: &mut egui::Ui,
state: &mut GuiState,
system: Option<&Arc<Mutex<ConfigurableSystem>>>,
) {
self.control_panel.render(ui, state, system);
}
/// Render the memory viewer component
@ -233,7 +242,12 @@ impl ControlPanel {
/// │ [Load ROM] [Start System] [Stop] [Reset] [Close] │
/// └─────────────────────────────────────────────────┘
/// ```
pub fn render(&mut self, ui: &mut egui::Ui, state: &mut GuiState) {
pub fn render(
&mut self,
ui: &mut egui::Ui,
state: &mut GuiState,
system: Option<&Arc<Mutex<ConfigurableSystem>>>,
) {
ui.horizontal(|ui| {
// Section header
ui.heading("System Control");
@ -247,22 +261,28 @@ impl ControlPanel {
// Start/Stop system button (context-sensitive)
if ui.button(&self.start_button_text).clicked() {
if !state.system_running {
self.start_system(state);
self.start_system(state, system);
}
}
// Stop system button (only enabled when running)
if ui.button("Stop System").clicked() && state.system_running {
self.stop_system(state);
self.stop_system(state, system);
}
// Reset system button
if ui.button("Reset System").clicked() {
self.reset_system(state);
self.reset_system(state, system);
}
// Application close button
if ui.button("Close").clicked() {
// Stop the system before closing if available
if let Some(sys) = system {
let mut sys_guard = sys.lock();
// Use the SystemController trait method explicitly
let _ = SystemController::stop(&mut *sys_guard);
}
// Close application - handled by eframe
ui.ctx().send_viewport_cmd(egui::ViewportCommand::Close);
}
@ -278,12 +298,37 @@ impl ControlPanel {
///
/// # Arguments
/// * `state` - Mutable reference to GUI state
fn start_system(&mut self, state: &mut GuiState) {
state.system_running = true;
self.start_button_text = "System Running...".to_string();
self.stop_button_enabled = true;
self.reset_button_enabled = true;
state.clear_error();
/// * `system` - Optional reference to the emulator system
fn start_system(
&mut self,
state: &mut GuiState,
system: Option<&Arc<Mutex<ConfigurableSystem>>>,
) {
// Actually start the system if available
if let Some(sys) = system {
let mut sys_guard = sys.lock();
// Use the SystemController trait method explicitly
let result = SystemController::start(&mut *sys_guard);
match result {
Ok(()) => {
state.system_running = true;
self.start_button_text = "System Running...".to_string();
self.stop_button_enabled = true;
self.reset_button_enabled = true;
state.clear_error();
}
Err(e) => {
state.set_error(format!("Failed to start system: {}", e));
}
}
} else {
// No system available - just update UI state
state.system_running = true;
self.start_button_text = "System Running...".to_string();
self.stop_button_enabled = true;
self.reset_button_enabled = true;
state.clear_error();
}
}
/// Stop the emulator system
@ -293,11 +338,35 @@ impl ControlPanel {
///
/// # Arguments
/// * `state` - Mutable reference to GUI state
fn stop_system(&mut self, state: &mut GuiState) {
state.system_running = false;
self.start_button_text = "Start System".to_string();
self.stop_button_enabled = false;
state.clear_error();
/// * `system` - Optional reference to the emulator system
fn stop_system(
&mut self,
state: &mut GuiState,
system: Option<&Arc<Mutex<ConfigurableSystem>>>,
) {
// Actually stop the system if available
if let Some(sys) = system {
let mut sys_guard = sys.lock();
// Use the SystemController trait method explicitly
let result = SystemController::stop(&mut *sys_guard);
match result {
Ok(()) => {
state.system_running = false;
self.start_button_text = "Start System".to_string();
self.stop_button_enabled = false;
state.clear_error();
}
Err(e) => {
state.set_error(format!("Failed to stop system: {}", e));
}
}
} else {
// No system available - just update UI state
state.system_running = false;
self.start_button_text = "Start System".to_string();
self.stop_button_enabled = false;
state.clear_error();
}
}
/// Reset the emulator system
@ -307,7 +376,19 @@ impl ControlPanel {
///
/// # Arguments
/// * `state` - Mutable reference to GUI state
fn reset_system(&mut self, state: &mut GuiState) {
/// * `system` - Optional reference to the emulator system
fn reset_system(
&mut self,
state: &mut GuiState,
system: Option<&Arc<Mutex<ConfigurableSystem>>>,
) {
// Stop the system first if available
if let Some(sys) = system {
let mut sys_guard = sys.lock();
// Use the SystemController trait method explicitly
let _ = SystemController::stop(&mut *sys_guard);
}
// Reset UI state
state.system_running = false;
state.cycle_count = 0;
self.start_button_text = "Start System".to_string();
@ -785,7 +866,7 @@ impl RomLoader {
}
// Display currently selected file
if let Some(ref file) = self.selected_file.clone() {
if let Some(ref file) = self.selected_file {
ui.label(format!("Selected: {}", file));
}