use std::sync::Arc; use std::{ path::Path, sync::mpsc::{Receiver, Sender}, thread, }; use dsa_rs::emulator::misc::rpc::{RpcClient, get_rpc_client_or_none}; use dsa_rs::emulator::{ config::Config, system::{ emulator::run_emulator, memory::MainStore, model::{Command, State}, processor::Processor, }, ui::{ control_unit::ControlPanel, display::Display, editor::Editor, interface::EmulatorUI, memory_inspector::MemoryInspector, stack_inspector::StackInspector, }, }; #[cfg(target_os = "android")] use winit::platform::android::activity::AndroidApp; #[cfg(target_os = "android")] #[no_mangle] fn android_main(app: AndroidApp) { main(app); } fn main( #[cfg(target_os = "android")] app: AndroidApp, ) -> Result<(), Box> { // Initialize channels and read in configuration. let (cmd_sender, cmd_receiver) = std::sync::mpsc::channel(); let (state_sender, state_reciever) = std::sync::mpsc::channel(); let config = Config::load(Path::new(".dsa.emulator.toml"))?; // Setup RPC if enabled. let (rpc_sender, rpc_reciever) = std::sync::mpsc::channel(); let rpc_client = get_rpc_client_or_none(&config, rpc_sender, rpc_reciever)?.map(Arc::new); setup_emulator(cmd_receiver, state_sender, rpc_client); let ui = setup_ui(cmd_sender, state_reciever); // Run UI. #[allow(unused_variables)] let options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default().with_inner_size([800.0, 600.0]), event_loop_builder: Some(Box::new(move |builder| { #[cfg(target_os = "android")] builder.with_android_app(app); })), ..Default::default() }; eframe::run_native( "DSA Simulator (Damn Simple Architecture 🔥)", options, Box::new(move |cc| { cc.egui_ctx.set_visuals(egui::Visuals::default()); Ok(Box::new(ui)) }), )?; Ok(()) } fn setup_emulator( cmd_receiver: Receiver, state_sender: Sender, rpc_client: Option>, ) { let main_store = MainStore::new(); let processor = Processor::new(Box::new(main_store), vec![]); thread::spawn(move || { run_emulator(&cmd_receiver, &state_sender, processor, rpc_client.as_ref()); }); } /// Creates the [`EmulatorUI`]. fn setup_ui(cmd_sender: Sender, state_reciever: Receiver) -> EmulatorUI { let mut ui = EmulatorUI::new(cmd_sender.clone(), state_reciever); // Create UI modules. let control_unit = ControlPanel::new(cmd_sender.clone()); ui.add_component(Box::new(control_unit)); let mem_inspector = MemoryInspector::new(cmd_sender.clone()); ui.add_component(Box::new(mem_inspector)); let stack_inspector = StackInspector::new(); ui.add_component(Box::new(stack_inspector)); let editor = Editor::new(cmd_sender.clone()); ui.add_component(Box::new(editor)); let display = Display::new(); ui.add_component(Box::new(display)); let history = dsa_rs::emulator::ui::history::History::new(); ui.add_component(Box::new(history)); ui }