133 lines
3.5 KiB
Rust
133 lines
3.5 KiB
Rust
#![deny(
|
|
clippy::unwrap_used,
|
|
clippy::nursery,
|
|
clippy::perf,
|
|
clippy::pedantic,
|
|
clippy::complexity
|
|
)]
|
|
#![allow(
|
|
clippy::cast_possible_truncation,
|
|
clippy::missing_panics_doc,
|
|
clippy::missing_errors_doc,
|
|
clippy::match_wildcard_for_single_variants
|
|
)]
|
|
|
|
pub mod emulator;
|
|
|
|
use std::{
|
|
sync::{
|
|
Arc,
|
|
mpsc::{Receiver, Sender},
|
|
},
|
|
thread,
|
|
};
|
|
|
|
#[cfg(target_os = "android")]
|
|
use winit::platform::android::{EventLoopBuilderExtAndroid, activity::AndroidApp};
|
|
|
|
use crate::emulator::{
|
|
misc::rpc::RpcClient,
|
|
system::{
|
|
emulator::run_emulator,
|
|
memory::MainStore,
|
|
model::{Command, StateUpdate},
|
|
processor::Processor,
|
|
},
|
|
ui::{
|
|
control_unit::ControlPanel, display::Display, editor::Editor,
|
|
interface::EmulatorUI, memory_inspector::MemoryInspector,
|
|
stack_inspector::StackInspector,
|
|
},
|
|
};
|
|
|
|
#[cfg(target_os = "android")]
|
|
#[unsafe(no_mangle)]
|
|
pub fn android_main(app: AndroidApp) -> Result<(), Box<dyn std::error::Error>> {
|
|
use crate::emulator::{config::Config, misc::rpc::get_rpc_client_or_none};
|
|
use std::path::Path;
|
|
|
|
// 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(())
|
|
}
|
|
|
|
pub fn setup_emulator(
|
|
cmd_receiver: Receiver<Command>,
|
|
state_sender: Sender<StateUpdate>,
|
|
rpc_client: Option<Arc<RpcClient>>,
|
|
) {
|
|
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`].
|
|
#[must_use]
|
|
pub fn setup_ui(
|
|
cmd_sender: Sender<Command>,
|
|
state_reciever: Receiver<StateUpdate>,
|
|
) -> EmulatorUI {
|
|
let mut ui = EmulatorUI::new(cmd_sender, state_reciever);
|
|
|
|
// Create UI modules.
|
|
let control_unit = ControlPanel::new();
|
|
|
|
ui.add_component(Box::new(control_unit));
|
|
|
|
let mem_inspector = MemoryInspector::new();
|
|
ui.add_component(Box::new(mem_inspector));
|
|
|
|
let stack_inspector = StackInspector::new();
|
|
ui.add_component(Box::new(stack_inspector));
|
|
|
|
let editor = Editor::new();
|
|
ui.add_component(Box::new(editor));
|
|
|
|
let display = Display::new();
|
|
ui.add_component(Box::new(display));
|
|
|
|
let history = emulator::ui::history::History::new();
|
|
ui.add_component(Box::new(history));
|
|
|
|
let loader = emulator::ui::loader::Loader::new();
|
|
ui.add_component(Box::new(loader));
|
|
|
|
ui
|
|
}
|