mirror of https://codeberg.org/topola/topola.git
egui: s/ExecuteWithStatus/ActivityWithStatus, move it to own file
This commit is contained in:
parent
a700bd8c20
commit
c8a40860af
|
|
@ -1,10 +1,28 @@
|
|||
use enum_dispatch::enum_dispatch;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{board::mesadata::AccessMesadata, drawing::graph::PrimitiveIndex, geometry::primitive::PrimitiveShape, layout::via::ViaWeight, router::{navmesh::Navmesh, trace::Trace}, step::Step};
|
||||
|
||||
use super::{autoroute::{Autoroute, AutorouteStatus}, compare_detours::{CompareDetours, CompareDetoursStatus}, invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker, InvokerError, InvokerStatus}, measure_length::MeasureLength, place_via::PlaceVia, remove_bands::RemoveBands, selection::{BandSelection, PinSelection}, AutorouterOptions};
|
||||
use crate::{
|
||||
board::mesadata::AccessMesadata,
|
||||
drawing::graph::PrimitiveIndex,
|
||||
geometry::primitive::PrimitiveShape,
|
||||
layout::via::ViaWeight,
|
||||
router::{navmesh::Navmesh, trace::Trace},
|
||||
step::Step,
|
||||
};
|
||||
|
||||
use super::{
|
||||
autoroute::{Autoroute, AutorouteStatus},
|
||||
compare_detours::{CompareDetours, CompareDetoursStatus},
|
||||
invoker::{
|
||||
GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker, InvokerError,
|
||||
InvokerStatus,
|
||||
},
|
||||
measure_length::MeasureLength,
|
||||
place_via::PlaceVia,
|
||||
remove_bands::RemoveBands,
|
||||
selection::{BandSelection, PinSelection},
|
||||
AutorouterOptions,
|
||||
};
|
||||
|
||||
type Type = PinSelection;
|
||||
|
||||
|
|
@ -91,54 +109,3 @@ impl<M: AccessMesadata> Step<Invoker<M>, InvokerStatus, InvokerError, ()> for Ex
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExecuteWithStatus {
|
||||
execute: Execute,
|
||||
maybe_status: Option<InvokerStatus>,
|
||||
}
|
||||
|
||||
impl ExecuteWithStatus {
|
||||
pub fn new(execute: Execute) -> ExecuteWithStatus {
|
||||
Self {
|
||||
execute,
|
||||
maybe_status: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step<M: AccessMesadata>(
|
||||
&mut self,
|
||||
invoker: &mut Invoker<M>,
|
||||
) -> Result<InvokerStatus, InvokerError> {
|
||||
let status = self.execute.step(invoker)?;
|
||||
self.maybe_status = Some(status.clone());
|
||||
Ok(status)
|
||||
}
|
||||
|
||||
pub fn maybe_status(&self) -> Option<InvokerStatus> {
|
||||
self.maybe_status.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetMaybeNavmesh for ExecuteWithStatus {
|
||||
fn maybe_navmesh(&self) -> Option<&Navmesh> {
|
||||
self.execute.maybe_navmesh()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetMaybeTrace for ExecuteWithStatus {
|
||||
fn maybe_trace(&self) -> Option<&Trace> {
|
||||
self.execute.maybe_trace()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetGhosts for ExecuteWithStatus {
|
||||
fn ghosts(&self) -> &[PrimitiveShape] {
|
||||
self.execute.ghosts()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetObstacles for ExecuteWithStatus {
|
||||
fn obstacles(&self) -> &[PrimitiveIndex] {
|
||||
self.execute.obstacles()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
use topola::{
|
||||
autorouter::{
|
||||
execute::Execute,
|
||||
invoker::{
|
||||
GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker, InvokerError,
|
||||
InvokerStatus,
|
||||
},
|
||||
},
|
||||
board::mesadata::AccessMesadata,
|
||||
drawing::graph::PrimitiveIndex,
|
||||
geometry::primitive::PrimitiveShape,
|
||||
router::{navmesh::Navmesh, trace::Trace},
|
||||
step::Step,
|
||||
};
|
||||
|
||||
pub struct ActivityWithStatus {
|
||||
execute: Execute,
|
||||
maybe_status: Option<InvokerStatus>,
|
||||
}
|
||||
|
||||
impl ActivityWithStatus {
|
||||
pub fn new_execute(execute: Execute) -> ActivityWithStatus {
|
||||
Self {
|
||||
execute,
|
||||
maybe_status: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step<M: AccessMesadata>(
|
||||
&mut self,
|
||||
invoker: &mut Invoker<M>,
|
||||
) -> Result<InvokerStatus, InvokerError> {
|
||||
let status = self.execute.step(invoker)?;
|
||||
self.maybe_status = Some(status.clone());
|
||||
Ok(status)
|
||||
}
|
||||
|
||||
pub fn maybe_status(&self) -> Option<InvokerStatus> {
|
||||
self.maybe_status.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetMaybeNavmesh for ActivityWithStatus {
|
||||
fn maybe_navmesh(&self) -> Option<&Navmesh> {
|
||||
self.execute.maybe_navmesh()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetMaybeTrace for ActivityWithStatus {
|
||||
fn maybe_trace(&self) -> Option<&Trace> {
|
||||
self.execute.maybe_trace()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetGhosts for ActivityWithStatus {
|
||||
fn ghosts(&self) -> &[PrimitiveShape] {
|
||||
self.execute.ghosts()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetObstacles for ActivityWithStatus {
|
||||
fn obstacles(&self) -> &[PrimitiveIndex] {
|
||||
self.execute.obstacles()
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@ use unic_langid::{langid, LanguageIdentifier};
|
|||
|
||||
use topola::{
|
||||
autorouter::{
|
||||
execute::ExecuteWithStatus,
|
||||
invoker::{Invoker, InvokerStatus},
|
||||
Autorouter,
|
||||
},
|
||||
|
|
@ -43,8 +42,8 @@ use topola::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
bottom::Bottom, file_receiver::FileReceiver, layers::Layers, overlay::Overlay,
|
||||
painter::Painter, top::Top, translator::Translator, viewport::Viewport,
|
||||
activity::ActivityWithStatus, bottom::Bottom, file_receiver::FileReceiver, layers::Layers,
|
||||
overlay::Overlay, painter::Painter, top::Top, translator::Translator, viewport::Viewport,
|
||||
};
|
||||
|
||||
/// Deserialize/Serialize is needed to persist app state between restarts.
|
||||
|
|
@ -60,7 +59,7 @@ pub struct App {
|
|||
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
||||
|
||||
#[serde(skip)]
|
||||
maybe_execute: Option<ExecuteWithStatus>,
|
||||
maybe_activity: Option<ActivityWithStatus>,
|
||||
|
||||
#[serde(skip)]
|
||||
content_channel: (Sender<String>, Receiver<String>),
|
||||
|
|
@ -93,7 +92,7 @@ impl Default for App {
|
|||
translator: Translator::new(langid!("en-US")),
|
||||
maybe_overlay: None,
|
||||
arc_mutex_maybe_invoker: Arc::new(Mutex::new(None)),
|
||||
maybe_execute: None,
|
||||
maybe_activity: None,
|
||||
content_channel: channel(),
|
||||
history_channel: channel(),
|
||||
viewport: Viewport::new(),
|
||||
|
|
@ -158,8 +157,8 @@ impl App {
|
|||
invoker.replay(serde_json::from_reader(bufread).unwrap())
|
||||
}
|
||||
|
||||
if let Some(ref mut execute) = self.maybe_execute {
|
||||
match execute.step(invoker) {
|
||||
if let Some(ref mut activity) = self.maybe_activity {
|
||||
match activity.step(invoker) {
|
||||
Ok(InvokerStatus::Running) => return true,
|
||||
Ok(InvokerStatus::Finished(..)) => return false,
|
||||
Err(err) => return false,
|
||||
|
|
@ -185,7 +184,7 @@ impl eframe::App for App {
|
|||
self.content_channel.0.clone(),
|
||||
self.history_channel.0.clone(),
|
||||
self.arc_mutex_maybe_invoker.clone(),
|
||||
&mut self.maybe_execute,
|
||||
&mut self.maybe_activity,
|
||||
&mut self.viewport,
|
||||
&mut self.maybe_overlay,
|
||||
&self.maybe_design,
|
||||
|
|
@ -194,7 +193,7 @@ impl eframe::App for App {
|
|||
self.advance_state_by_dt(ctx.input(|i| i.stable_dt));
|
||||
|
||||
self.bottom
|
||||
.update(ctx, &self.translator, &self.viewport, &self.maybe_execute);
|
||||
.update(ctx, &self.translator, &self.viewport, &self.maybe_activity);
|
||||
|
||||
if self.top.show_layer_manager {
|
||||
if let Some(ref mut layers) = self.maybe_layers {
|
||||
|
|
@ -208,7 +207,7 @@ impl eframe::App for App {
|
|||
ctx,
|
||||
&self.top,
|
||||
&mut self.arc_mutex_maybe_invoker.lock().unwrap(),
|
||||
&mut self.maybe_execute,
|
||||
&mut self.maybe_activity,
|
||||
&mut self.maybe_overlay,
|
||||
&self.maybe_layers,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use topola::autorouter::{execute::ExecuteWithStatus, invoker::InvokerStatus};
|
||||
use topola::autorouter::invoker::InvokerStatus;
|
||||
|
||||
use crate::{translator::Translator, viewport::Viewport};
|
||||
use crate::{activity::ActivityWithStatus, translator::Translator, viewport::Viewport};
|
||||
|
||||
pub struct Bottom {}
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ impl Bottom {
|
|||
ctx: &egui::Context,
|
||||
tr: &Translator,
|
||||
viewport: &Viewport,
|
||||
maybe_execute: &Option<ExecuteWithStatus>,
|
||||
maybe_activity: &Option<ActivityWithStatus>,
|
||||
) {
|
||||
egui::TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| {
|
||||
let latest_pos = viewport.transform.inverse()
|
||||
|
|
@ -22,8 +22,8 @@ impl Bottom {
|
|||
|
||||
let mut message = String::from("");
|
||||
|
||||
if let Some(execute) = maybe_execute {
|
||||
if let Some(InvokerStatus::Finished(msg)) = execute.maybe_status() {
|
||||
if let Some(activity) = maybe_activity {
|
||||
if let Some(InvokerStatus::Finished(msg)) = activity.maybe_status() {
|
||||
message = msg;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
|
||||
|
||||
mod action;
|
||||
mod activity;
|
||||
mod app;
|
||||
mod bottom;
|
||||
mod file_receiver;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use std::{
|
|||
|
||||
use topola::{
|
||||
autorouter::{
|
||||
execute::{Command, ExecuteWithStatus},
|
||||
execute::Command,
|
||||
invoker::{Invoker, InvokerError, InvokerStatus},
|
||||
AutorouterOptions,
|
||||
},
|
||||
|
|
@ -16,6 +16,7 @@ use topola::{
|
|||
|
||||
use crate::{
|
||||
action::{Action, Switch, Trigger},
|
||||
activity::ActivityWithStatus,
|
||||
app::execute,
|
||||
file_sender::FileSender,
|
||||
overlay::Overlay,
|
||||
|
|
@ -61,7 +62,7 @@ impl Top {
|
|||
content_sender: Sender<String>,
|
||||
history_sender: Sender<String>,
|
||||
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
||||
maybe_execute: &mut Option<ExecuteWithStatus>,
|
||||
maybe_activity: &mut Option<ActivityWithStatus>,
|
||||
viewport: &mut Viewport,
|
||||
maybe_overlay: &mut Option<Overlay>,
|
||||
maybe_design: &Option<SpecctraDesign>,
|
||||
|
|
@ -233,9 +234,7 @@ impl Top {
|
|||
});
|
||||
} else if export_session.consume_key_triggered(ctx, ui) {
|
||||
if let Some(design) = maybe_design {
|
||||
if let Some(invoker) =
|
||||
arc_mutex_maybe_invoker.lock().unwrap().as_ref()
|
||||
{
|
||||
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_ref() {
|
||||
let ctx = ui.ctx().clone();
|
||||
let board = invoker.autorouter().board();
|
||||
|
||||
|
|
@ -274,8 +273,7 @@ impl Top {
|
|||
}
|
||||
});
|
||||
} else if export_history.consume_key_triggered(ctx, ui) {
|
||||
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_ref()
|
||||
{
|
||||
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_ref() {
|
||||
let ctx = ctx.clone();
|
||||
let task = rfd::AsyncFileDialog::new().save_file();
|
||||
|
||||
|
|
@ -293,8 +291,8 @@ impl Top {
|
|||
} else if quit.consume_key_triggered(ctx, ui) {
|
||||
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
||||
} else if autoroute.consume_key_triggered(ctx, ui) {
|
||||
if maybe_execute.as_mut().map_or(true, |execute| {
|
||||
matches!(execute.maybe_status(), Some(InvokerStatus::Finished(..)))
|
||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
|
||||
}) {
|
||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||
|
|
@ -302,18 +300,18 @@ impl Top {
|
|||
) {
|
||||
let selection = overlay.selection().clone();
|
||||
overlay.clear_selection();
|
||||
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
|
||||
Command::Autoroute(
|
||||
maybe_activity.insert(ActivityWithStatus::new_execute(
|
||||
invoker.execute_stepper(Command::Autoroute(
|
||||
selection.pin_selection,
|
||||
self.autorouter_options,
|
||||
),
|
||||
)?));
|
||||
))?,
|
||||
));
|
||||
}
|
||||
}
|
||||
} else if place_via.consume_key_enabled(ctx, ui, &mut self.is_placing_via) {
|
||||
} else if remove_bands.consume_key_triggered(ctx, ui) {
|
||||
if maybe_execute.as_mut().map_or(true, |execute| {
|
||||
matches!(execute.maybe_status(), Some(InvokerStatus::Finished(..)))
|
||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
|
||||
}) {
|
||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||
|
|
@ -321,14 +319,16 @@ impl Top {
|
|||
) {
|
||||
let selection = overlay.selection().clone();
|
||||
overlay.clear_selection();
|
||||
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
|
||||
Command::RemoveBands(selection.band_selection),
|
||||
)?));
|
||||
maybe_activity.insert(ActivityWithStatus::new_execute(
|
||||
invoker.execute_stepper(Command::RemoveBands(
|
||||
selection.band_selection,
|
||||
))?,
|
||||
));
|
||||
}
|
||||
}
|
||||
} else if measure_length.consume_key_triggered(ctx, ui) {
|
||||
if maybe_execute.as_mut().map_or(true, |execute| {
|
||||
matches!(execute.maybe_status(), Some(InvokerStatus::Finished(..)))
|
||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
|
||||
}) {
|
||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||
|
|
@ -336,9 +336,11 @@ impl Top {
|
|||
) {
|
||||
let selection = overlay.selection().clone();
|
||||
overlay.clear_selection();
|
||||
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
|
||||
Command::MeasureLength(selection.band_selection),
|
||||
)?));
|
||||
maybe_activity.insert(ActivityWithStatus::new_execute(
|
||||
invoker.execute_stepper(Command::MeasureLength(
|
||||
selection.band_selection,
|
||||
))?,
|
||||
));
|
||||
}
|
||||
}
|
||||
} else if undo.consume_key_triggered(ctx, ui) {
|
||||
|
|
@ -350,8 +352,8 @@ impl Top {
|
|||
invoker.redo();
|
||||
}
|
||||
} else if compare_detours.consume_key_triggered(ctx, ui) {
|
||||
if maybe_execute.as_mut().map_or(true, |execute| {
|
||||
matches!(execute.maybe_status(), Some(InvokerStatus::Finished(..)))
|
||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
|
||||
}) {
|
||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||
|
|
@ -359,12 +361,12 @@ impl Top {
|
|||
) {
|
||||
let selection = overlay.selection().clone();
|
||||
overlay.clear_selection();
|
||||
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
|
||||
Command::CompareDetours(
|
||||
maybe_activity.insert(ActivityWithStatus::new_execute(
|
||||
invoker.execute_stepper(Command::CompareDetours(
|
||||
selection.pin_selection,
|
||||
self.autorouter_options,
|
||||
),
|
||||
)?));
|
||||
))?,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use petgraph::{
|
|||
use rstar::{Envelope, AABB};
|
||||
use topola::{
|
||||
autorouter::{
|
||||
execute::{Command, ExecuteWithStatus},
|
||||
execute::Command,
|
||||
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker},
|
||||
},
|
||||
board::mesadata::AccessMesadata,
|
||||
|
|
@ -20,7 +20,10 @@ use topola::{
|
|||
specctra::mesadata::SpecctraMesadata,
|
||||
};
|
||||
|
||||
use crate::{app::execute, layers::Layers, overlay::Overlay, painter::Painter, top::Top};
|
||||
use crate::{
|
||||
activity::ActivityWithStatus, app::execute, layers::Layers, overlay::Overlay, painter::Painter,
|
||||
top::Top,
|
||||
};
|
||||
|
||||
pub struct Viewport {
|
||||
pub transform: egui::emath::TSTransform,
|
||||
|
|
@ -40,7 +43,7 @@ impl Viewport {
|
|||
ctx: &egui::Context,
|
||||
top: &Top,
|
||||
maybe_invoker: &mut Option<Invoker<SpecctraMesadata>>,
|
||||
maybe_execute: &mut Option<ExecuteWithStatus>,
|
||||
maybe_activity: &mut Option<ActivityWithStatus>,
|
||||
maybe_overlay: &mut Option<Overlay>,
|
||||
maybe_layers: &Option<Layers>,
|
||||
) -> egui::Rect {
|
||||
|
|
@ -48,7 +51,7 @@ impl Viewport {
|
|||
ctx,
|
||||
top,
|
||||
maybe_invoker,
|
||||
maybe_execute,
|
||||
maybe_activity,
|
||||
maybe_overlay,
|
||||
maybe_layers,
|
||||
);
|
||||
|
|
@ -65,7 +68,7 @@ impl Viewport {
|
|||
ctx: &egui::Context,
|
||||
top: &Top,
|
||||
maybe_invoker: &mut Option<Invoker<SpecctraMesadata>>,
|
||||
maybe_execute: &mut Option<ExecuteWithStatus>,
|
||||
maybe_activity: &mut Option<ActivityWithStatus>,
|
||||
maybe_overlay: &mut Option<Overlay>,
|
||||
maybe_layers: &Option<Layers>,
|
||||
) -> egui::Rect {
|
||||
|
|
@ -124,8 +127,8 @@ impl Viewport {
|
|||
{
|
||||
layers.highlight_colors[i]
|
||||
} else {
|
||||
if let Some(execute) = maybe_execute {
|
||||
if execute.obstacles().contains(&primitive) {
|
||||
if let Some(activity) = maybe_activity {
|
||||
if activity.obstacles().contains(&primitive) {
|
||||
layers.highlight_colors[i]
|
||||
} else {
|
||||
layers.colors[i]
|
||||
|
|
@ -178,8 +181,8 @@ impl Viewport {
|
|||
}
|
||||
|
||||
if top.show_navmesh {
|
||||
if let Some(execute) = maybe_execute {
|
||||
if let Some(navmesh) = execute.maybe_navmesh() {
|
||||
if let Some(activity) = maybe_activity {
|
||||
if let Some(navmesh) = activity.maybe_navmesh() {
|
||||
for edge in navmesh.edge_references() {
|
||||
let mut from = PrimitiveIndex::from(navmesh.node_weight(edge.source()).unwrap().node)
|
||||
.primitive(board.layout().drawing())
|
||||
|
|
@ -208,11 +211,11 @@ impl Viewport {
|
|||
|
||||
let stroke = 'blk: {
|
||||
if let (Some(source_pos), Some(target_pos)) = (
|
||||
execute.maybe_trace().map(|trace|
|
||||
activity.maybe_trace().map(|trace|
|
||||
trace.path
|
||||
.iter()
|
||||
.position(|node| *node == edge.source())).flatten(),
|
||||
execute.maybe_trace().map(|trace|
|
||||
activity.maybe_trace().map(|trace|
|
||||
trace.path
|
||||
.iter()
|
||||
.position(|node| *node == edge.target())).flatten(),
|
||||
|
|
@ -243,12 +246,12 @@ impl Viewport {
|
|||
painter.paint_bbox(root_bbox);
|
||||
}
|
||||
|
||||
if let Some(execute) = maybe_execute {
|
||||
for ghost in execute.ghosts().iter() {
|
||||
if let Some(activity) = maybe_activity {
|
||||
for ghost in activity.ghosts().iter() {
|
||||
painter.paint_primitive(&ghost, egui::Color32::from_rgb(75, 75, 150));
|
||||
}
|
||||
|
||||
if let Some(navmesh) = execute.maybe_navmesh() {
|
||||
if let Some(navmesh) = activity.maybe_navmesh() {
|
||||
if top.show_origin_destination {
|
||||
if let (origin, destination) = (navmesh.origin(), navmesh.destination()) {
|
||||
painter.paint_dot(
|
||||
|
|
|
|||
Loading…
Reference in New Issue