mirror of https://codeberg.org/topola/topola.git
refactor(router/navcord): Make it clear that navcord is not a stepper
Rename `NavcordStepper<...>` to `Navcord<...>. Since the navcord is not actually considered a true stepper, having the word "stepper" in its identifier would confuse anyone new to source-diving Topola's code. Rename Navcord's `.step(...)` to `.step_to(...)` to make it clear that this is not just a step like in a stepper, but a step to a some specified position.
This commit is contained in:
parent
e448f86374
commit
47371fdf3f
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
geometry::primitive::PrimitiveShape,
|
geometry::primitive::PrimitiveShape,
|
||||||
layout::LayoutEdit,
|
layout::LayoutEdit,
|
||||||
router::{
|
router::{
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navmesh::{Navmesh, NavvertexIndex},
|
navmesh::{Navmesh, NavvertexIndex},
|
||||||
RouteStepper, Router,
|
RouteStepper, Router,
|
||||||
},
|
},
|
||||||
|
|
@ -169,7 +169,7 @@ impl GetMaybeNavmesh for AutorouteExecutionStepper {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeNavcord for AutorouteExecutionStepper {
|
impl GetMaybeNavcord for AutorouteExecutionStepper {
|
||||||
fn maybe_navcord(&self) -> Option<&NavcordStepper> {
|
fn maybe_navcord(&self) -> Option<&Navcord> {
|
||||||
self.route.as_ref().map(|route| route.navcord())
|
self.route.as_ref().map(|route| route.navcord())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
geometry::{primitive::PrimitiveShape, shape::MeasureLength},
|
geometry::{primitive::PrimitiveShape, shape::MeasureLength},
|
||||||
graph::MakeRef,
|
graph::MakeRef,
|
||||||
router::{
|
router::{
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navmesh::{Navmesh, NavvertexIndex},
|
navmesh::{Navmesh, NavvertexIndex},
|
||||||
},
|
},
|
||||||
stepper::Step,
|
stepper::Step,
|
||||||
|
|
@ -110,7 +110,7 @@ impl GetMaybeNavmesh for CompareDetoursExecutionStepper {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeNavcord for CompareDetoursExecutionStepper {
|
impl GetMaybeNavcord for CompareDetoursExecutionStepper {
|
||||||
fn maybe_navcord(&self) -> Option<&NavcordStepper> {
|
fn maybe_navcord(&self) -> Option<&Navcord> {
|
||||||
self.autoroute.maybe_navcord()
|
self.autoroute.maybe_navcord()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use crate::{
|
||||||
drawing::graph::PrimitiveIndex,
|
drawing::graph::PrimitiveIndex,
|
||||||
geometry::{edit::ApplyGeometryEdit, primitive::PrimitiveShape},
|
geometry::{edit::ApplyGeometryEdit, primitive::PrimitiveShape},
|
||||||
router::{
|
router::{
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navmesh::{Navmesh, NavvertexIndex},
|
navmesh::{Navmesh, NavvertexIndex},
|
||||||
},
|
},
|
||||||
stepper::Step,
|
stepper::Step,
|
||||||
|
|
@ -42,7 +42,7 @@ pub trait GetMaybeNavmesh {
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
/// Trait for getting the navcord to display it on the debug overlay.
|
/// Trait for getting the navcord to display it on the debug overlay.
|
||||||
pub trait GetMaybeNavcord {
|
pub trait GetMaybeNavcord {
|
||||||
fn maybe_navcord(&self) -> Option<&NavcordStepper>;
|
fn maybe_navcord(&self) -> Option<&Navcord>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
geometry::{primitive::PrimitiveShape, shape::MeasureLength as MeasureLengthTrait},
|
geometry::{primitive::PrimitiveShape, shape::MeasureLength as MeasureLengthTrait},
|
||||||
graph::MakeRef,
|
graph::MakeRef,
|
||||||
router::{
|
router::{
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navmesh::{Navmesh, NavvertexIndex},
|
navmesh::{Navmesh, NavvertexIndex},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -65,7 +65,7 @@ impl GetMaybeNavmesh for MeasureLengthExecutionStepper {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeNavcord for MeasureLengthExecutionStepper {
|
impl GetMaybeNavcord for MeasureLengthExecutionStepper {
|
||||||
fn maybe_navcord(&self) -> Option<&NavcordStepper> {
|
fn maybe_navcord(&self) -> Option<&Navcord> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
geometry::primitive::PrimitiveShape,
|
geometry::primitive::PrimitiveShape,
|
||||||
layout::{via::ViaWeight, LayoutEdit},
|
layout::{via::ViaWeight, LayoutEdit},
|
||||||
router::{
|
router::{
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navmesh::{Navmesh, NavvertexIndex},
|
navmesh::{Navmesh, NavvertexIndex},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -62,7 +62,7 @@ impl GetMaybeNavmesh for PlaceViaExecutionStepper {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeNavcord for PlaceViaExecutionStepper {
|
impl GetMaybeNavcord for PlaceViaExecutionStepper {
|
||||||
fn maybe_navcord(&self) -> Option<&NavcordStepper> {
|
fn maybe_navcord(&self) -> Option<&Navcord> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
geometry::primitive::PrimitiveShape,
|
geometry::primitive::PrimitiveShape,
|
||||||
layout::LayoutEdit,
|
layout::LayoutEdit,
|
||||||
router::{
|
router::{
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navmesh::{Navmesh, NavvertexIndex},
|
navmesh::{Navmesh, NavvertexIndex},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -61,7 +61,7 @@ impl GetMaybeNavmesh for RemoveBandsExecutionStepper {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeNavcord for RemoveBandsExecutionStepper {
|
impl GetMaybeNavcord for RemoveBandsExecutionStepper {
|
||||||
fn maybe_navcord(&self) -> Option<&NavcordStepper> {
|
fn maybe_navcord(&self) -> Option<&Navcord> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ use crate::{
|
||||||
geometry::primitive::PrimitiveShape,
|
geometry::primitive::PrimitiveShape,
|
||||||
interactor::interaction::{InteractionError, InteractionStepper},
|
interactor::interaction::{InteractionError, InteractionStepper},
|
||||||
router::{
|
router::{
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navmesh::{Navmesh, NavvertexIndex},
|
navmesh::{Navmesh, NavvertexIndex},
|
||||||
},
|
},
|
||||||
stepper::{Abort, Step},
|
stepper::{Abort, Step},
|
||||||
|
|
@ -131,7 +131,7 @@ impl GetMaybeNavmesh for ActivityStepperWithStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeNavcord for ActivityStepperWithStatus {
|
impl GetMaybeNavcord for ActivityStepperWithStatus {
|
||||||
fn maybe_navcord(&self) -> Option<&NavcordStepper> {
|
fn maybe_navcord(&self) -> Option<&Navcord> {
|
||||||
self.activity.maybe_navcord()
|
self.activity.maybe_navcord()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
drawing::graph::PrimitiveIndex,
|
drawing::graph::PrimitiveIndex,
|
||||||
geometry::primitive::PrimitiveShape,
|
geometry::primitive::PrimitiveShape,
|
||||||
router::{
|
router::{
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navmesh::{Navmesh, NavvertexIndex},
|
navmesh::{Navmesh, NavvertexIndex},
|
||||||
},
|
},
|
||||||
stepper::{Abort, Step},
|
stepper::{Abort, Step},
|
||||||
|
|
@ -59,7 +59,7 @@ impl GetMaybeNavmesh for InteractionStepper {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeNavcord for InteractionStepper {
|
impl GetMaybeNavcord for InteractionStepper {
|
||||||
fn maybe_navcord(&self) -> Option<&NavcordStepper> {
|
fn maybe_navcord(&self) -> Option<&Navcord> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,30 +20,30 @@ use super::{
|
||||||
navmesh::{BinavvertexNodeIndex, Navmesh, NavvertexIndex},
|
navmesh::{BinavvertexNodeIndex, Navmesh, NavvertexIndex},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The navcord (stepper) is a structure that holds the movable non-borrowing
|
/// The navcord is a structure that holds the movable non-borrowing
|
||||||
/// data of the currently running routing process.
|
/// data of the currently running routing process.
|
||||||
///
|
///
|
||||||
/// The name "navcord" is a shortening of "navigation cord", by analogy to
|
/// The name "navcord" is a shortening of "navigation cord", by analogy to
|
||||||
/// "navmesh" being a shortening of "navigation mesh".
|
/// "navmesh" being a shortening of "navigation mesh".
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NavcordStepper {
|
pub struct Navcord {
|
||||||
pub recorder: LayoutEdit,
|
pub recorder: LayoutEdit,
|
||||||
/// The currently attempted path.
|
/// The currently attempted path.
|
||||||
pub path: Vec<NavvertexIndex>,
|
pub path: Vec<NavvertexIndex>,
|
||||||
/// The head of the routed band.
|
/// The head of the currently routed band.
|
||||||
pub head: Head,
|
pub head: Head,
|
||||||
/// The width of the routed band.
|
/// The width of the currently routed band.
|
||||||
pub width: f64,
|
pub width: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NavcordStepper {
|
impl Navcord {
|
||||||
/// Creates a new navcord.
|
/// Creates a new navcord.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
recorder: LayoutEdit,
|
recorder: LayoutEdit,
|
||||||
source: FixedDotIndex,
|
source: FixedDotIndex,
|
||||||
source_navvertex: NavvertexIndex,
|
source_navvertex: NavvertexIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> NavcordStepper {
|
) -> Navcord {
|
||||||
Self {
|
Self {
|
||||||
recorder,
|
recorder,
|
||||||
path: vec![source_navvertex],
|
path: vec![source_navvertex],
|
||||||
|
|
@ -89,7 +89,7 @@ impl NavcordStepper {
|
||||||
#[debug_ensures(ret.is_ok() -> matches!(self.head, Head::Cane(..)))]
|
#[debug_ensures(ret.is_ok() -> matches!(self.head, Head::Cane(..)))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.path.len() == old(self.path.len() + 1))]
|
#[debug_ensures(ret.is_ok() -> self.path.len() == old(self.path.len() + 1))]
|
||||||
#[debug_ensures(ret.is_err() -> self.path.len() == old(self.path.len()))]
|
#[debug_ensures(ret.is_err() -> self.path.len() == old(self.path.len()))]
|
||||||
pub fn step<R: AccessRules>(
|
pub fn step_to<R: AccessRules>(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout: &mut Layout<R>,
|
layout: &mut Layout<R>,
|
||||||
navmesh: &Navmesh,
|
navmesh: &Navmesh,
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
draw::{Draw, DrawException},
|
draw::{Draw, DrawException},
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navmesh::{Navmesh, NavvertexIndex},
|
navmesh::{Navmesh, NavvertexIndex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -31,30 +31,30 @@ pub trait Navcorder {
|
||||||
source: FixedDotIndex,
|
source: FixedDotIndex,
|
||||||
source_navvertex: NavvertexIndex,
|
source_navvertex: NavvertexIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> NavcordStepper;
|
) -> Navcord;
|
||||||
|
|
||||||
fn finish(
|
fn finish(
|
||||||
&mut self,
|
&mut self,
|
||||||
_navmesh: &Navmesh,
|
_navmesh: &Navmesh,
|
||||||
navcord: &mut NavcordStepper,
|
navcord: &mut Navcord,
|
||||||
target: FixedDotIndex,
|
target: FixedDotIndex,
|
||||||
) -> Result<BandTermsegIndex, NavcorderException>;
|
) -> Result<BandTermsegIndex, NavcorderException>;
|
||||||
|
|
||||||
fn rework_path(
|
fn rework_path(
|
||||||
&mut self,
|
&mut self,
|
||||||
navmesh: &Navmesh,
|
navmesh: &Navmesh,
|
||||||
navcord: &mut NavcordStepper,
|
navcord: &mut Navcord,
|
||||||
path: &[NavvertexIndex],
|
path: &[NavvertexIndex],
|
||||||
) -> Result<(), NavcorderException>;
|
) -> Result<(), NavcorderException>;
|
||||||
|
|
||||||
fn path(
|
fn path(
|
||||||
&mut self,
|
&mut self,
|
||||||
navmesh: &Navmesh,
|
navmesh: &Navmesh,
|
||||||
navcord: &mut NavcordStepper,
|
navcord: &mut Navcord,
|
||||||
path: &[NavvertexIndex],
|
path: &[NavvertexIndex],
|
||||||
) -> Result<(), NavcorderException>;
|
) -> Result<(), NavcorderException>;
|
||||||
|
|
||||||
fn undo_path(&mut self, navcord: &mut NavcordStepper, step_count: usize);
|
fn undo_path(&mut self, navcord: &mut Navcord, step_count: usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: AccessRules> Navcorder for Layout<R> {
|
impl<R: AccessRules> Navcorder for Layout<R> {
|
||||||
|
|
@ -64,14 +64,14 @@ impl<R: AccessRules> Navcorder for Layout<R> {
|
||||||
source: FixedDotIndex,
|
source: FixedDotIndex,
|
||||||
source_navvertex: NavvertexIndex,
|
source_navvertex: NavvertexIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> NavcordStepper {
|
) -> Navcord {
|
||||||
NavcordStepper::new(recorder, source, source_navvertex, width)
|
Navcord::new(recorder, source, source_navvertex, width)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(
|
fn finish(
|
||||||
&mut self,
|
&mut self,
|
||||||
_navmesh: &Navmesh,
|
_navmesh: &Navmesh,
|
||||||
navcord: &mut NavcordStepper,
|
navcord: &mut Navcord,
|
||||||
target: FixedDotIndex,
|
target: FixedDotIndex,
|
||||||
) -> Result<BandTermsegIndex, NavcorderException> {
|
) -> Result<BandTermsegIndex, NavcorderException> {
|
||||||
Ok(self.finish_in_dot(&mut navcord.recorder, navcord.head, target, navcord.width)?)
|
Ok(self.finish_in_dot(&mut navcord.recorder, navcord.head, target, navcord.width)?)
|
||||||
|
|
@ -82,7 +82,7 @@ impl<R: AccessRules> Navcorder for Layout<R> {
|
||||||
fn rework_path(
|
fn rework_path(
|
||||||
&mut self,
|
&mut self,
|
||||||
navmesh: &Navmesh,
|
navmesh: &Navmesh,
|
||||||
navcord: &mut NavcordStepper,
|
navcord: &mut Navcord,
|
||||||
path: &[NavvertexIndex],
|
path: &[NavvertexIndex],
|
||||||
) -> Result<(), NavcorderException> {
|
) -> Result<(), NavcorderException> {
|
||||||
let prefix_length = navcord
|
let prefix_length = navcord
|
||||||
|
|
@ -101,11 +101,11 @@ impl<R: AccessRules> Navcorder for Layout<R> {
|
||||||
fn path(
|
fn path(
|
||||||
&mut self,
|
&mut self,
|
||||||
navmesh: &Navmesh,
|
navmesh: &Navmesh,
|
||||||
navcord: &mut NavcordStepper,
|
navcord: &mut Navcord,
|
||||||
path: &[NavvertexIndex],
|
path: &[NavvertexIndex],
|
||||||
) -> Result<(), NavcorderException> {
|
) -> Result<(), NavcorderException> {
|
||||||
for (i, vertex) in path.iter().enumerate() {
|
for (i, vertex) in path.iter().enumerate() {
|
||||||
if let Err(err) = navcord.step(self, navmesh, *vertex) {
|
if let Err(err) = navcord.step_to(self, navmesh, *vertex) {
|
||||||
self.undo_path(navcord, i);
|
self.undo_path(navcord, i);
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +115,7 @@ impl<R: AccessRules> Navcorder for Layout<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(navcord.path.len() == old(navcord.path.len() - step_count))]
|
#[debug_ensures(navcord.path.len() == old(navcord.path.len() - step_count))]
|
||||||
fn undo_path(&mut self, navcord: &mut NavcordStepper, step_count: usize) {
|
fn undo_path(&mut self, navcord: &mut Navcord, step_count: usize) {
|
||||||
for _ in 0..step_count {
|
for _ in 0..step_count {
|
||||||
let _ = navcord.step_back(self);
|
let _ = navcord.step_back(self);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
layout::LayoutEdit,
|
layout::LayoutEdit,
|
||||||
router::{
|
router::{
|
||||||
astar::{Astar, AstarError},
|
astar::{Astar, AstarError},
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navcorder::Navcorder,
|
navcorder::Navcorder,
|
||||||
navmesh::{Navmesh, NavmeshError},
|
navmesh::{Navmesh, NavmeshError},
|
||||||
Router, RouterAstarStrategy,
|
Router, RouterAstarStrategy,
|
||||||
|
|
@ -26,7 +26,7 @@ use crate::{
|
||||||
pub struct RouteStepper {
|
pub struct RouteStepper {
|
||||||
#[getter(skip)]
|
#[getter(skip)]
|
||||||
astar: Astar<Navmesh, f64>,
|
astar: Astar<Navmesh, f64>,
|
||||||
navcord: NavcordStepper,
|
navcord: Navcord,
|
||||||
ghosts: Vec<PrimitiveShape>,
|
ghosts: Vec<PrimitiveShape>,
|
||||||
obstacles: Vec<PrimitiveIndex>,
|
obstacles: Vec<PrimitiveIndex>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ use crate::{
|
||||||
use super::{
|
use super::{
|
||||||
astar::{AstarStrategy, PathTracker},
|
astar::{AstarStrategy, PathTracker},
|
||||||
draw::DrawException,
|
draw::DrawException,
|
||||||
navcord::NavcordStepper,
|
navcord::Navcord,
|
||||||
navcorder::{Navcorder, NavcorderException},
|
navcorder::{Navcorder, NavcorderException},
|
||||||
navmesh::{Navmesh, NavmeshEdgeReference, NavmeshError, NavvertexIndex},
|
navmesh::{Navmesh, NavmeshEdgeReference, NavmeshError, NavvertexIndex},
|
||||||
route::RouteStepper,
|
route::RouteStepper,
|
||||||
|
|
@ -44,18 +44,14 @@ pub struct RouterOptions {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RouterAstarStrategy<'a, R> {
|
pub struct RouterAstarStrategy<'a, R> {
|
||||||
pub layout: &'a mut Layout<R>,
|
pub layout: &'a mut Layout<R>,
|
||||||
pub navcord: &'a mut NavcordStepper,
|
pub navcord: &'a mut Navcord,
|
||||||
pub target: FixedDotIndex,
|
pub target: FixedDotIndex,
|
||||||
pub probe_ghosts: Vec<PrimitiveShape>,
|
pub probe_ghosts: Vec<PrimitiveShape>,
|
||||||
pub probe_obstacles: Vec<PrimitiveIndex>,
|
pub probe_obstacles: Vec<PrimitiveIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R> RouterAstarStrategy<'a, R> {
|
impl<'a, R> RouterAstarStrategy<'a, R> {
|
||||||
pub fn new(
|
pub fn new(layout: &'a mut Layout<R>, navcord: &'a mut Navcord, target: FixedDotIndex) -> Self {
|
||||||
layout: &'a mut Layout<R>,
|
|
||||||
navcord: &'a mut NavcordStepper,
|
|
||||||
target: FixedDotIndex,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
layout,
|
layout,
|
||||||
navcord,
|
navcord,
|
||||||
|
|
@ -103,7 +99,7 @@ impl<R: AccessRules> AstarStrategy<Navmesh, f64, BandTermsegIndex> for RouterAst
|
||||||
}
|
}
|
||||||
|
|
||||||
let prev_bihead_length = self.bihead_length();
|
let prev_bihead_length = self.bihead_length();
|
||||||
let result = self.navcord.step(self.layout, navmesh, edge.target());
|
let result = self.navcord.step_to(self.layout, navmesh, edge.target());
|
||||||
let probe_length = self.bihead_length() - prev_bihead_length;
|
let probe_length = self.bihead_length() - prev_bihead_length;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue