diff --git a/Cargo.lock b/Cargo.lock index fbe4422..08894a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -624,6 +624,7 @@ dependencies = [ "serde_yaml", "termcolor", "tracing", + "tracing-subscriber", ] [[package]] diff --git a/factorio-pathfinding/Cargo.toml b/factorio-pathfinding/Cargo.toml index f8b736a..d191022 100644 --- a/factorio-pathfinding/Cargo.toml +++ b/factorio-pathfinding/Cargo.toml @@ -30,3 +30,4 @@ serde_json = "1.0.108" serde_yaml = "0.9.34" termcolor = "1.4.1" tracing = "0.1.41" +tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } diff --git a/factorio-pathfinding/src/bin/path_finding.rs b/factorio-pathfinding/src/bin/path_finding.rs new file mode 100644 index 0000000..8d0f07e --- /dev/null +++ b/factorio-pathfinding/src/bin/path_finding.rs @@ -0,0 +1,140 @@ +use clap::{Parser, ValueEnum}; +use factorio_core::{ + aabb::AABB, + prelude::{Direction, Position, PositionType}, +}; +use factorio_graph::{ + priority_queue::{ + ByKey, + binary_heap::{BinaryHeap, FastBinaryHeap}, + bucket_queue::BucketQueue, + }, + wheighted_graph::shortest_path::QueueObject, +}; +use factorio_pathfinding::{ + Connection, Map, PathInput, Pathfinder, belt_finding::ConflictAvoidance, +}; +use tracing_subscriber::{EnvFilter, fmt::format::FmtSpan}; + +#[derive(Parser)] +struct Args { + input: PathfindingInputArg, + pathfinder: PathfinderArg, + size: PositionType, +} + +#[derive(ValueEnum, Clone, Copy)] +enum PathfinderArg { + CaFbh, + CaBh, + CaBq, +} + +#[derive(ValueEnum, Clone, Copy)] +enum PathfindingInputArg { + EmptyDiagonal, + EmptyStraight, +} + +struct EmptyMap { + area: AABB, +} + +impl Map for EmptyMap { + fn get_position(&self, pos: Position) -> bool { + self.area.contains_pos(pos) + } + + fn area(&self) -> (Position, Position) { + ( + self.area.min(), + self.area.max() - self.area.min() + Position::new(1, 1), + ) + } +} + +fn main() { + let args = Args::parse(); + + tracing_subscriber::fmt::fmt() + .with_env_filter(EnvFilter::from_default_env()) + .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE) + .init(); + + match args.input { + PathfindingInputArg::EmptyDiagonal => { + let connections = vec![Connection { + start_pos: Position::new(0, -1), + start_dir: Direction::Down, + end_pos: Position::new(args.size - 1, args.size), + end_dir: Direction::Down, + beltspeed: factorio_core::beltoptions::Beltspeed::Normal, + lanes: 1, + }]; + let map = EmptyMap { + area: AABB::new( + Position::new(0, 0), + Position::new(args.size - 1, args.size - 1), + ), + }; + let path_input = PathInput { + connections: &connections, + map, + }; + execute(&args, path_input); + } + PathfindingInputArg::EmptyStraight => { + let connections = vec![Connection { + start_pos: Position::new(args.size / 2, -1), + start_dir: Direction::Down, + end_pos: Position::new(args.size / 2, args.size), + end_dir: Direction::Down, + beltspeed: factorio_core::beltoptions::Beltspeed::Normal, + lanes: 1, + }]; + let map = EmptyMap { + area: AABB::new( + Position::new(0, 0), + Position::new(args.size - 1, args.size - 1), + ), + }; + let path_input = PathInput { + connections: &connections, + map, + }; + execute(&args, path_input); + } + } +} + +fn execute<'a, M: Map>(args: &Args, path_input: PathInput<'a, M>) { + match args.pathfinder { + PathfinderArg::CaFbh => { + let p = ConflictAvoidance { + timeout: Some(std::time::Duration::from_millis(100)), + priority_queue: std::marker::PhantomData::< + FastBinaryHeap>>, + >, + }; + p.find_paths(path_input); + } + PathfinderArg::CaBh => { + let p = ConflictAvoidance { + timeout: Some(std::time::Duration::from_millis(100)), + priority_queue: std::marker::PhantomData::< + BinaryHeap>>, + >, + }; + p.find_paths(path_input); + } + PathfinderArg::CaBq => { + let p = ConflictAvoidance { + timeout: Some(std::time::Duration::from_millis(100)), + priority_queue: std::marker::PhantomData::< + BucketQueue>, + >, + }; + p.find_paths(path_input); + } + } +}