mirror of https://codeberg.org/topola/topola.git
egui: step through every band routing step, once per frame
At last! We finally have that implemented without concurrency.
This commit is contained in:
parent
6cadcd3b41
commit
ee6eeac6d8
|
|
@ -50,10 +50,13 @@ use crate::{
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct App {
|
pub struct App {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
overlay: Option<Overlay>,
|
maybe_overlay: Option<Overlay>,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
||||||
|
|
||||||
|
#[serde(skip)]
|
||||||
|
maybe_execute: Option<Execute>,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
text_channel: (Sender<String>, Receiver<String>),
|
text_channel: (Sender<String>, Receiver<String>),
|
||||||
|
|
@ -68,19 +71,20 @@ pub struct App {
|
||||||
bottom: Bottom,
|
bottom: Bottom,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
layers: Option<Layers>,
|
maybe_layers: Option<Layers>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for App {
|
impl Default for App {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
overlay: None,
|
maybe_overlay: None,
|
||||||
invoker: Arc::new(Mutex::new(None)),
|
arc_mutex_maybe_invoker: Arc::new(Mutex::new(None)),
|
||||||
|
maybe_execute: None,
|
||||||
text_channel: channel(),
|
text_channel: channel(),
|
||||||
viewport: Viewport::new(),
|
viewport: Viewport::new(),
|
||||||
top: Top::new(),
|
top: Top::new(),
|
||||||
bottom: Bottom::new(),
|
bottom: Bottom::new(),
|
||||||
layers: None,
|
maybe_layers: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -95,6 +99,44 @@ impl App {
|
||||||
|
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_state(&mut self) {
|
||||||
|
if cfg!(target_arch = "wasm32") {
|
||||||
|
if let Ok(file_contents) = self.text_channel.1.try_recv() {
|
||||||
|
let design = SpecctraDesign::load_from_string(file_contents).unwrap();
|
||||||
|
let board = design.make_board();
|
||||||
|
self.maybe_overlay = Some(Overlay::new(&board).unwrap());
|
||||||
|
self.maybe_layers = Some(Layers::new(&board));
|
||||||
|
self.arc_mutex_maybe_invoker = Arc::new(Mutex::new(Some(Invoker::new(
|
||||||
|
Autorouter::new(board).unwrap(),
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let Ok(path) = self.text_channel.1.try_recv() {
|
||||||
|
let design = SpecctraDesign::load_from_file(&path).unwrap();
|
||||||
|
let board = design.make_board();
|
||||||
|
self.maybe_overlay = Some(Overlay::new(&board).unwrap());
|
||||||
|
self.maybe_layers = Some(Layers::new(&board));
|
||||||
|
self.arc_mutex_maybe_invoker = Arc::new(Mutex::new(Some(Invoker::new(
|
||||||
|
Autorouter::new(board).unwrap(),
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(invoker) = self.arc_mutex_maybe_invoker.lock().unwrap().as_mut() {
|
||||||
|
if let Some(ref mut execute) = self.maybe_execute {
|
||||||
|
let status = match execute.step(invoker) {
|
||||||
|
Ok(status) => status,
|
||||||
|
Err(err) => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let InvokerStatus::Finished = status {
|
||||||
|
self.maybe_execute = None;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl eframe::App for App {
|
impl eframe::App for App {
|
||||||
|
|
@ -105,37 +147,18 @@ impl eframe::App for App {
|
||||||
|
|
||||||
/// Called each time the UI has to be repainted.
|
/// Called each time the UI has to be repainted.
|
||||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||||
if cfg!(target_arch = "wasm32") {
|
self.update_state();
|
||||||
if let Ok(file_contents) = self.text_channel.1.try_recv() {
|
|
||||||
let design = SpecctraDesign::load_from_string(file_contents).unwrap();
|
|
||||||
let board = design.make_board();
|
|
||||||
self.overlay = Some(Overlay::new(&board).unwrap());
|
|
||||||
self.layers = Some(Layers::new(&board));
|
|
||||||
self.invoker = Arc::new(Mutex::new(Some(Invoker::new(
|
|
||||||
Autorouter::new(board).unwrap(),
|
|
||||||
))));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let Ok(path) = self.text_channel.1.try_recv() {
|
|
||||||
let design = SpecctraDesign::load_from_file(&path).unwrap();
|
|
||||||
let board = design.make_board();
|
|
||||||
self.overlay = Some(Overlay::new(&board).unwrap());
|
|
||||||
self.layers = Some(Layers::new(&board));
|
|
||||||
self.invoker = Arc::new(Mutex::new(Some(Invoker::new(
|
|
||||||
Autorouter::new(board).unwrap(),
|
|
||||||
))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.top.update(
|
self.top.update(
|
||||||
ctx,
|
ctx,
|
||||||
self.text_channel.0.clone(),
|
self.text_channel.0.clone(),
|
||||||
self.invoker.clone(),
|
self.arc_mutex_maybe_invoker.clone(),
|
||||||
&mut self.overlay,
|
&mut self.maybe_execute,
|
||||||
|
&mut self.maybe_overlay,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(ref mut layers) = self.layers {
|
if let Some(ref mut layers) = self.maybe_layers {
|
||||||
if let Some(invoker) = self.invoker.lock().unwrap().as_ref() {
|
if let Some(invoker) = self.arc_mutex_maybe_invoker.lock().unwrap().as_ref() {
|
||||||
layers.update(ctx, invoker.autorouter().board());
|
layers.update(ctx, invoker.autorouter().board());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -143,9 +166,9 @@ impl eframe::App for App {
|
||||||
let viewport_rect = self.viewport.update(
|
let viewport_rect = self.viewport.update(
|
||||||
ctx,
|
ctx,
|
||||||
&self.top,
|
&self.top,
|
||||||
&mut self.invoker.lock().unwrap(),
|
&mut self.arc_mutex_maybe_invoker.lock().unwrap(),
|
||||||
&mut self.overlay,
|
&mut self.maybe_overlay,
|
||||||
&self.layers,
|
&self.maybe_layers,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.bottom.update(ctx, &self.viewport, viewport_rect);
|
self.bottom.update(ctx, &self.viewport, viewport_rect);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ impl Top {
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &egui::Context,
|
ctx: &egui::Context,
|
||||||
sender: Sender<String>,
|
sender: Sender<String>,
|
||||||
maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
||||||
|
maybe_execute: &mut Option<Execute>,
|
||||||
maybe_overlay: &Option<Overlay>,
|
maybe_overlay: &Option<Overlay>,
|
||||||
) {
|
) {
|
||||||
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
||||||
|
|
@ -55,7 +56,7 @@ impl Top {
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
if ui.button("Load history").clicked() {
|
if ui.button("Load history").clicked() {
|
||||||
let invoker_arc_mutex = maybe_invoker.clone();
|
let invoker_arc_mutex = arc_mutex_maybe_invoker.clone();
|
||||||
let ctx = ui.ctx().clone();
|
let ctx = ui.ctx().clone();
|
||||||
let task = rfd::AsyncFileDialog::new().pick_file();
|
let task = rfd::AsyncFileDialog::new().pick_file();
|
||||||
|
|
||||||
|
|
@ -79,7 +80,7 @@ impl Top {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ui.button("Save history").clicked() {
|
if ui.button("Save history").clicked() {
|
||||||
let invoker_arc_mutex = maybe_invoker.clone();
|
let invoker_arc_mutex = arc_mutex_maybe_invoker.clone();
|
||||||
let ctx = ui.ctx().clone();
|
let ctx = ui.ctx().clone();
|
||||||
let task = rfd::AsyncFileDialog::new().save_file();
|
let task = rfd::AsyncFileDialog::new().save_file();
|
||||||
|
|
||||||
|
|
@ -115,39 +116,15 @@ impl Top {
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
if ui.button("Autoroute").clicked() {
|
if ui.button("Autoroute").clicked() {
|
||||||
if let (Some(invoker), Some(ref overlay)) =
|
if maybe_execute.is_none() {
|
||||||
(maybe_invoker.lock().unwrap().as_mut(), maybe_overlay)
|
if let (Some(invoker), Some(ref overlay)) = (
|
||||||
{
|
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||||
let selection = overlay.selection().clone();
|
maybe_overlay,
|
||||||
let mut execute = invoker.execute_walk(Command::Autoroute(selection));
|
) {
|
||||||
|
let selection = overlay.selection().clone();
|
||||||
if let Execute::Autoroute(ref mut autoroute) = execute {
|
maybe_execute
|
||||||
let from = autoroute.navmesh().as_ref().unwrap().source();
|
.insert(invoker.execute_walk(Command::Autoroute(selection)));
|
||||||
let to = autoroute.navmesh().as_ref().unwrap().target();
|
|
||||||
|
|
||||||
/*{
|
|
||||||
let mut shared_data = shared_data_arc_mutex.lock().unwrap();
|
|
||||||
shared_data.from = Some(from);
|
|
||||||
shared_data.to = Some(to);
|
|
||||||
shared_data.navmesh = autoroute.navmesh().cloned();
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = loop {
|
|
||||||
let status = match execute.step(invoker) {
|
|
||||||
Ok(status) => status,
|
|
||||||
Err(err) => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let InvokerStatus::Finished = status {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if let Execute::Autoroute(ref mut autoroute) = execute {
|
|
||||||
shared_data_arc_mutex.lock().unwrap().navmesh =
|
|
||||||
autoroute.navmesh().cloned();
|
|
||||||
}*/
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,7 +135,7 @@ impl Top {
|
||||||
if ui.button("Undo").clicked()
|
if ui.button("Undo").clicked()
|
||||||
|| ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Z))
|
|| ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Z))
|
||||||
{
|
{
|
||||||
if let Some(invoker) = maybe_invoker.lock().unwrap().as_mut() {
|
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() {
|
||||||
invoker.undo();
|
invoker.undo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,7 +143,8 @@ impl Top {
|
||||||
if ui.button("Redo").clicked()
|
if ui.button("Redo").clicked()
|
||||||
|| ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Y))
|
|| ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Y))
|
||||||
{
|
{
|
||||||
if let Some(ref mut invoker) = maybe_invoker.lock().unwrap().as_mut() {
|
if let Some(ref mut invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut()
|
||||||
|
{
|
||||||
invoker.redo();
|
invoker.redo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue