feat: migrate to parking_lot mutex and add system control architecture
This commit is contained in:
parent
14060e15e5
commit
54144d10e9
29 changed files with 2387 additions and 1130 deletions
296
plans/observer_pattern_and_ui_layout.md
Normal file
296
plans/observer_pattern_and_ui_layout.md
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
# Observer Pattern and UI Layout Configuration Implementation Plan
|
||||
|
||||
## Overview
|
||||
|
||||
This plan implements two key improvements to the rusty_emu project:
|
||||
|
||||
1. **Observer Pattern**: Replace inefficient polling with event-driven state updates
|
||||
2. **UI Layout Configuration**: Enable configurable GUI layouts from JSON config files
|
||||
|
||||
## Current Issues
|
||||
|
||||
### Performance Issues
|
||||
- Console polls system state at 100ms intervals (inefficient)
|
||||
- GUI uses `try_lock()` but still has potential contention
|
||||
- No way to configure GUI layout from JSON config
|
||||
|
||||
### Architecture Limitations
|
||||
- Tight coupling between components and UI
|
||||
- No standardized way to notify UI of state changes
|
||||
- Hardcoded UI layouts
|
||||
|
||||
## Solution Architecture
|
||||
|
||||
### Observer Pattern Implementation
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[SystemObserver Trait] --> B[CPU Observer]
|
||||
A --> C[RAM Observer]
|
||||
A --> D[ROM Observer]
|
||||
|
||||
B --> E[ConfigurableSystem]
|
||||
C --> E
|
||||
D --> E
|
||||
|
||||
E --> F[Console UI]
|
||||
E --> G[GUI Interface]
|
||||
|
||||
F --> H[Event-driven Updates]
|
||||
G --> H
|
||||
```
|
||||
|
||||
### UI Layout Configuration
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[SystemConfig JSON] --> B[UI Layout Section]
|
||||
B --> C[Component Positions]
|
||||
B --> D[Component Sizes]
|
||||
B --> E[Display Options]
|
||||
|
||||
C --> F[GUI Renderer]
|
||||
D --> F
|
||||
E --> F
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### 1. SystemObserver Trait (Fine-grained with Filtering)
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ObserverFilter {
|
||||
All,
|
||||
CpuOnly,
|
||||
MemoryOnly,
|
||||
StateChangesOnly,
|
||||
RegisterChangesOnly,
|
||||
}
|
||||
|
||||
pub trait SystemObserver: Send + Sync {
|
||||
fn get_filter(&self) -> ObserverFilter { return ObserverFilter::All; }
|
||||
|
||||
fn on_state_change(&self, component: &str, old_state: ComponentState, new_state: ComponentState);
|
||||
fn on_ram_change(&self, chip: &str, bank: usize, address: u8, old_value: u8, new_value: u8);
|
||||
fn on_rom_change(&self, chip: &str, address: u16, old_value: u8, new_value: u8);
|
||||
fn on_cpu_register_change(&self, cpu: &str, register: &str, old_value: u8, new_value: u8);
|
||||
fn on_cpu_pc_change(&self, cpu: &str, old_pc: u16, new_pc: u16);
|
||||
fn on_cpu_instruction_executed(&self, cpu: &str, instruction: u8, pc: u16);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Enhanced SystemConfig
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SystemConfig {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub version: String,
|
||||
pub metadata: HashMap<String, serde_json::Value>,
|
||||
pub components: HashMap<String, ComponentConfig>,
|
||||
pub connections: HashMap<String, ConnectionConfig>,
|
||||
pub layout: Option<LayoutConfig>,
|
||||
// NEW: UI Layout configuration
|
||||
pub ui_layout: Option<UiLayoutConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UiLayoutConfig {
|
||||
pub console: Option<ConsoleLayoutConfig>,
|
||||
pub gui: Option<GuiLayoutConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct GuiLayoutConfig {
|
||||
pub components: HashMap<String, ComponentLayoutConfig>,
|
||||
pub grid_size: Option<[usize; 2]>,
|
||||
pub refresh_rate_ms: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ComponentLayoutConfig {
|
||||
pub position: [usize; 2],
|
||||
pub size: [usize; 2],
|
||||
pub visible: Option<bool>,
|
||||
pub display_format: Option<String>,
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Observer Registration in ConfigurableSystem
|
||||
|
||||
```rust
|
||||
pub struct ConfigurableSystem {
|
||||
config: SystemConfig,
|
||||
components: HashMap<String, Arc<Mutex<Box<dyn Component>>>>,
|
||||
is_running: Arc<Mutex<bool>>,
|
||||
component_handles: Arc<Mutex<Option<ComponentHandles>>>,
|
||||
// NEW: Observer registry
|
||||
observers: Arc<Mutex<Vec<Box<dyn SystemObserver>>>>,
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Component Integration
|
||||
|
||||
Each component will notify observers of state changes:
|
||||
|
||||
- **Intel4004 CPU**: Register changes, PC changes, instruction execution
|
||||
- **Intel4001 ROM**: Memory reads, address changes
|
||||
- **Intel4002 RAM**: Memory reads/writes, I/O changes
|
||||
|
||||
### 5. UI Updates
|
||||
|
||||
#### Console Updates (Performance Target: 50% CPU reduction, sub-10ms responsiveness)
|
||||
- Replace 100ms polling with event-driven updates using observer pattern
|
||||
- Observer receives notifications and updates display immediately
|
||||
- Implement filtering to reduce unnecessary UI updates
|
||||
- Target: Reduce CPU usage by 50% compared to current polling
|
||||
- Target: Update responsiveness to under 10ms for state changes
|
||||
|
||||
#### GUI Updates
|
||||
- Use layout configuration from JSON for component positioning/sizing
|
||||
- Position components according to config (basic implementation)
|
||||
- Show/hide components based on config visibility settings
|
||||
- Use observer pattern for real-time updates
|
||||
- Support configurable refresh rates from UI layout config
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
### Enhanced JSON Config
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "IntelMcs4",
|
||||
"description": "Basic MCS-4 System with CPU, Clock, 2 ROMs, and 1 RAM",
|
||||
"version": "1.0",
|
||||
"metadata": {
|
||||
"author": "RustyEmu",
|
||||
"created": "2024-01-01",
|
||||
"cpu_speed": 750000,
|
||||
"architecture": "mcs4",
|
||||
"rom_count": 2,
|
||||
"ram_count": 1
|
||||
},
|
||||
"components": {
|
||||
"CPU_4004": {
|
||||
"single": {
|
||||
"component_type": "intel_4004",
|
||||
"name": "CPU_4004",
|
||||
"properties": {
|
||||
"clock_speed": 750000
|
||||
}
|
||||
}
|
||||
}
|
||||
// ... other components
|
||||
},
|
||||
"connections": {
|
||||
// ... existing connections
|
||||
},
|
||||
"layout": {
|
||||
"grid_size": [10, 10],
|
||||
"positions": {
|
||||
"cpu": [1, 1],
|
||||
"clock": [0, 0],
|
||||
"rom1": [2, 0],
|
||||
"rom2": [3, 0],
|
||||
"ram": [2, 2]
|
||||
}
|
||||
},
|
||||
"ui_layout": {
|
||||
"console": {
|
||||
"refresh_rate_ms": 50,
|
||||
"show_ram": true,
|
||||
"show_registers": true,
|
||||
"show_system_info": true
|
||||
},
|
||||
"gui": {
|
||||
"grid_size": [20, 20],
|
||||
"components": {
|
||||
"CPU_4004": {
|
||||
"position": [1, 1],
|
||||
"size": [20, 10],
|
||||
"visible": true,
|
||||
"display_format": "hex"
|
||||
},
|
||||
"RAM_4002": {
|
||||
"position": [3, 2],
|
||||
"size": [25, 15],
|
||||
"visible": true,
|
||||
"display_format": "hex"
|
||||
},
|
||||
"ROM_4001_1": {
|
||||
"position": [2, 0],
|
||||
"size": [20, 8],
|
||||
"visible": true,
|
||||
"display_format": "hex"
|
||||
}
|
||||
},
|
||||
"refresh_rate_ms": 60
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
### Performance Improvements
|
||||
- **Reduced CPU usage**: Event-driven vs polling
|
||||
- **Better responsiveness**: Immediate updates vs 100ms delays
|
||||
- **Less contention**: Observer pattern reduces lock contention
|
||||
|
||||
### User Experience
|
||||
- **Configurable layouts**: Users can customize UI arrangement
|
||||
- **Persistent settings**: Layouts saved in config files
|
||||
- **Flexible display options**: Show/hide components, change formats
|
||||
|
||||
### Architecture Benefits
|
||||
- **Loose coupling**: Components don't depend on UI
|
||||
- **Extensibility**: Easy to add new observers
|
||||
- **Maintainability**: Clear separation of concerns
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
1. **Add SystemObserver trait** to `system_config.rs`
|
||||
2. **Extend SystemConfig** with UI layout configuration
|
||||
3. **Add observer registration** to `ConfigurableSystem`
|
||||
4. **Implement observer notifications** in Intel4004 CPU
|
||||
5. **Implement observer notifications** in Intel4001 ROM
|
||||
6. **Implement observer notifications** in Intel4002 RAM
|
||||
7. **Update console.rs** to use observer pattern
|
||||
8. **Update GUI** to use observer pattern and layout configuration
|
||||
9. **Add UI layout configuration** to existing JSON configs
|
||||
10. **Test** the observer pattern and UI layout system
|
||||
11. **Update documentation** with new features
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
- Test observer registration and notification
|
||||
- Test UI layout configuration parsing
|
||||
- Test component state change notifications
|
||||
|
||||
### Integration Tests
|
||||
- Test console with observer pattern
|
||||
- Test GUI with layout configuration
|
||||
- Test end-to-end state change propagation
|
||||
|
||||
### Performance Tests
|
||||
- Measure CPU usage reduction
|
||||
- Test responsiveness improvements
|
||||
- Validate lock contention reduction
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
- Existing configs without `ui_layout` section will use defaults (console: 100ms, current GUI layout)
|
||||
- Observer pattern is additive - doesn't break existing code, components work without observers
|
||||
- ConfigurableSystem will handle missing `ui_layout` gracefully with sensible defaults
|
||||
- Gradual migration path: existing configs continue to work, new configs get enhanced features
|
||||
- No breaking changes to existing JSON configs - only additive new section
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- **Multiple observer types**: Different observers for different concerns
|
||||
- **Layout templates**: Predefined layouts for different use cases
|
||||
- **Dynamic layout editing**: Runtime layout modification
|
||||
- **Observer filtering**: Selective notification based on component types
|
||||
Loading…
Add table
Add a link
Reference in a new issue