Skip to main content

condor/
lib.rs

1#![forbid(unsafe_code)]
2//! # Condor
3//!
4//! Condor is a pathfinding library with explicit public entrypoints for grids,
5//! polygonal scenes, repeated polygonal queries, navmesh routing, and
6//! replanning lanes.
7//!
8//! The published package is `condor-for-games`; the Rust library name is
9//! `condor` (`cargo add condor-for-games --rename condor`). This crate is the
10//! **public facade**: it curates feature-gated re-exports from owner crates
11//! (`core`, `geometry`, `grid`, `navmesh`) and owns a small set of root contracts
12//! ([`solver_portfolio`], polygonal pack adapters, artifact error types).
13//! Application code should depend on `condor`, not on implementation crates
14//! directly.
15//!
16//! Start with [`SolverPortfolio`] if you want the current recommended surface
17//! for a problem model, then move to the concrete solver or workflow type for
18//! that model. Project support catalogs, capture reports, and readiness
19//! checklists live outside this curated import surface.
20//!
21//! # Problem models
22//!
23//! | Model | Build and query with | How it relates to the other lanes |
24//! | --- | --- | --- |
25//! | Discrete grid | [`Grid`], [`SearchRequest`], [`Pathfinder`] | Cell-based static, any-angle, prepared, replanning, and MAPF work |
26//! | Continuous free space | [`PolygonScene`], [`PolygonSearchRequest`], [`PolygonPathfinder`] | Uses world-coordinate [`Point2`] values and Euclidean polyline paths |
27//! | Navmesh | [`Navmesh`], [`NavmeshPathfinder`], [`PreparedNavmeshBuilder`] | Reuses the continuous `Point2` / polygon-path vocabulary over convex cells and portals |
28//! | Shared outcome | [`SearchOutcome`] | Each lane distinguishes invalid requests (`Err`) from computed found/no-path outcomes with stats |
29//! | Search budget | [`SearchBudget`] on each request/query | Optional `max_expansions` / `max_duration`; default unlimited; exhaustion is `Err`, not no-path |
30//!
31//! The grid and continuous/navmesh lanes deliberately use their own request and
32//! path types. Choose the model that matches the caller's world representation;
33//! [`SolverPortfolio`] maps that choice to the endorsed public entrypoint.
34//!
35//! # Features
36//!
37//! | Feature | Surface |
38//! | --- | --- |
39//! | `grid` | Grids, static search, any-angle, preprocessed grids, MAPF, replanning |
40//! | `polygonal` | Continuous polygon scenes, visibility / SPM / TFS solvers, artifact errors |
41//! | `navmesh` | Navmesh substrate and routing (implies `polygonal`) |
42//! | `polyanya` | Optional Polyanya router (implies `navmesh`) |
43//! | `full` | All of the above (**default**) |
44//!
45//! # Add Condor to an application
46//!
47//! Give the dependency the library name so application code can use
48//! `condor::{AStar, Grid, ...}` directly:
49//!
50//! ```bash
51//! cargo add condor-for-games --rename condor
52//! ```
53//!
54//! ```toml
55//! [dependencies]
56//! condor = { package = "condor-for-games", version = "0.4.0", default-features = false, features = ["grid"] }
57//! ```
58//!
59//! Omit the feature settings when you want Condor's complete curated surface;
60//! `full` is the default.
61//!
62//! # Examples
63//!
64//! Choose an endorsed surface for a problem model:
65//!
66//! ```
67//! use condor::{SolverPortfolio, SolverUseCase};
68//!
69//! let recommendation = SolverPortfolio::recommend(SolverUseCase::ExactNavmeshRouting);
70//! assert_eq!(recommendation.solver(), "TRAStarBuilder");
71//! assert_eq!(recommendation.integration_surface(), "PreparedNavmeshBuilder");
72//! ```
73//!
74//! Run a grid-only A* search:
75//!
76//! ```
77//! use condor::{AStar, Cell, Grid, Pathfinder, Point, SearchRequest};
78//!
79//! let mut grid = Grid::new(5, 5).expect("grid dimensions are valid");
80//! grid.set_cell(Point::new(2, 2), Cell::Blocked)
81//!     .expect("point is in bounds");
82//!
83//! let result = AStar.search(
84//!     &grid,
85//!     SearchRequest::new(Point::new(0, 0), Point::new(4, 4)),
86//! ).expect("request is valid");
87//!
88//! assert!(result.is_found());
89//! ```
90//!
91//! Cap expansions or wall-clock time on any online search request:
92//!
93//! ```
94//! use condor::{AStar, Grid, Pathfinder, Point, SearchBudget, SearchRequest};
95//!
96//! let grid = Grid::new(20, 20).expect("grid dimensions are valid");
97//! let request = SearchRequest::new(Point::new(0, 0), Point::new(19, 19))
98//!     .with_budget(SearchBudget::max_expansions(4));
99//! let error = AStar.search(&grid, request).expect_err("budget should stop a long path");
100//! assert!(matches!(error, condor::GridSearchError::BudgetExhausted(_)));
101//! ```
102
103/// Shared search-budget types used across problem models (owner: core).
104pub use condor_core::{BudgetExhausted, BudgetWatch, SearchBudget};
105
106/// Algorithm taxonomy re-exports grouped by search contract (owner crates hold bodies).
107#[cfg(any(feature = "grid", feature = "navmesh"))]
108pub mod algorithms;
109/// Any-angle grid pathfinder trait and continuous-on-grid request surface (owner: grid).
110#[cfg(feature = "grid")]
111pub mod any_angle;
112/// Continuous free-space geometry substrate and walkability primitives (owner: geometry).
113#[cfg(feature = "polygonal")]
114pub use condor_geometry::continuous;
115/// Artifact and pack-boundary error types owned by the facade.
116#[cfg(feature = "polygonal")]
117pub mod error;
118/// Multi-agent same-goal flow-field amortization (owner: grid).
119#[cfg(feature = "grid")]
120pub use condor_grid::flow_field;
121/// Discrete grid storage and cell model (owner: grid).
122#[cfg(feature = "grid")]
123pub use condor_grid::grid;
124/// Hierarchical abstract-grid layers for multi-level search (owner: grid).
125#[cfg(feature = "grid")]
126pub use condor_grid::hierarchical;
127/// Multi-agent pathfinding starter surface (owner: grid).
128#[cfg(feature = "grid")]
129pub mod mapf;
130/// Navmesh substrate and pathfinder re-exports (owner: navmesh).
131#[cfg(feature = "navmesh")]
132pub mod navmesh;
133/// Grid path reconstruction and cost types (owner: grid).
134#[cfg(feature = "grid")]
135pub use condor_grid::path;
136/// Integer grid coordinates (owner: grid).
137#[cfg(feature = "grid")]
138pub use condor_grid::point;
139/// Optional Polyanya-backed navmesh pathfinder (owner: navmesh, feature-gated).
140#[cfg(feature = "polyanya")]
141pub mod polyanya;
142/// Continuous polygonal pack adapters and scene pathfinder surface (owner: geometry + facade packs).
143#[cfg(feature = "polygonal")]
144pub mod polygonal;
145/// Prepared any-angle visibility graphs over grids (owner: grid).
146#[cfg(feature = "grid")]
147pub use condor_grid::prepared_any_angle;
148/// Preprocessed static grid search substrates (owner: grid).
149#[cfg(feature = "grid")]
150pub use condor_grid::preprocessed_grid;
151/// Incremental and interpolated grid replanning contracts (owner: grid).
152#[cfg(feature = "grid")]
153pub mod replanning;
154/// Continuous shortest-path maps for fixed-source polygonal queries (owner: geometry).
155#[cfg(feature = "polygonal")]
156pub use condor_geometry::shortest_path_map;
157/// Online grid search traits and request/result contracts (owner: grid).
158#[cfg(feature = "grid")]
159pub use condor_grid::search;
160/// Endorsed solver recommendations keyed by problem model / use case.
161pub mod solver_portfolio;
162/// Topological fracture search for continuous free space (owner: geometry).
163#[cfg(feature = "polygonal")]
164pub use condor_geometry::topological_fracture_search;
165/// Visibility-graph exact polygonal shortest paths (owner: geometry).
166#[cfg(feature = "polygonal")]
167pub use condor_geometry::visibility_graph;
168
169#[cfg(feature = "grid")]
170pub use algorithms::anya::{Anya, AnyaDiagnostics, AnyaInspection};
171#[cfg(feature = "grid")]
172pub use algorithms::astar::AStar;
173#[cfg(feature = "grid")]
174pub use algorithms::bfs::Bfs;
175#[cfg(feature = "grid")]
176pub use algorithms::bidirectional_bfs::BidirectionalBfs;
177#[cfg(feature = "navmesh")]
178pub use algorithms::channel_search::ChannelSearch;
179#[cfg(feature = "grid")]
180pub use algorithms::d_star_lite::DStarLite;
181#[cfg(feature = "grid")]
182pub use algorithms::dijkstra::Dijkstra;
183#[cfg(feature = "grid")]
184pub use algorithms::field_d_star::FieldDStar;
185#[cfg(feature = "grid")]
186pub use algorithms::hpastar::{HPAStarBuilder, PreparedHPAStar};
187#[cfg(feature = "grid")]
188pub use algorithms::jps_plus::{JpsPlusBuilder, PreparedJpsPlus};
189#[cfg(feature = "grid")]
190pub use algorithms::jump_point_search::JumpPointSearch;
191#[cfg(feature = "grid")]
192pub use algorithms::lazy_theta_star::LazyThetaStar;
193#[cfg(feature = "grid")]
194pub use algorithms::lifelong_planning_astar::LifelongPlanningAStar;
195#[cfg(feature = "grid")]
196pub use algorithms::rectangular_symmetry_reduction::RectangularSymmetryReduction;
197#[cfg(feature = "grid")]
198pub use algorithms::subgoal_graph::{PreparedSubgoalGraph, SubgoalGraphBuilder};
199#[cfg(feature = "navmesh")]
200pub use algorithms::ta_star::TAStar;
201#[cfg(feature = "grid")]
202pub use algorithms::theta_star::ThetaStar;
203#[cfg(feature = "navmesh")]
204pub use algorithms::tra_star::{
205    PreparedTRAStar, PreparedTRAStarPortalTransitionCache,
206    PreparedTRAStarWaypointDatabaseAdaptiveLru, PreparedTRAStarWaypointDatabaseCostAwareEviction,
207    PreparedTRAStarWaypointDatabaseFixedAdmissionThreshold,
208    PreparedTRAStarWaypointDatabaseFixedDemotionRule,
209    PreparedTRAStarWaypointDatabaseFixedPromotionRule, PreparedTRAStarWaypointDatabaseLazyQuery,
210    PreparedTRAStarWaypointDatabasePolicyProfile, PreparedTRAStarWaypointDatabaseStatic,
211    PreparedTRAStarWaypointDatabaseTwoTierLru, TRAStarBuilder, TRAStarPortalTransitionCacheBuilder,
212    TRAStarWaypointDatabaseAdaptiveLruBuilder, TRAStarWaypointDatabaseCostAwareEvictionBuilder,
213    TRAStarWaypointDatabaseFixedAdmissionThresholdBuilder,
214    TRAStarWaypointDatabaseFixedDemotionRuleBuilder,
215    TRAStarWaypointDatabaseFixedPromotionRuleBuilder, TRAStarWaypointDatabaseLazyQueryBuilder,
216    TRAStarWaypointDatabasePolicyProfile, TRAStarWaypointDatabasePolicyProfileBuilder,
217    TRAStarWaypointDatabaseStaticBuilder, TRAStarWaypointDatabaseTwoTierLruBuilder,
218};
219#[cfg(feature = "grid")]
220pub use any_angle::{
221    AnyAnglePath, AnyAnglePathBuildError, AnyAnglePathfinder, AnyAngleSearchError,
222    AnyAngleSearchRequest, AnyAngleSearchResult, AnyAngleSearchStats,
223};
224#[cfg(feature = "grid")]
225pub use condor_grid::flow_field::{
226    FlowDirection, FlowFieldBuildError, FlowFieldBuilder, PreparedFlowField,
227};
228#[cfg(feature = "grid")]
229pub use condor_grid::mapf::*;
230#[cfg(feature = "grid")]
231pub use condor_grid::replanning::*;
232#[cfg(feature = "polygonal")]
233pub use continuous::{
234    PolygonPath, PolygonPathBuildError, PolygonPathfinder, PolygonSearchError, PolygonSearchResult,
235    PolygonSearchStats,
236};
237#[cfg(feature = "polygonal")]
238pub use error::{
239    ArtifactContractError, ArtifactContractKind, ArtifactContractLocation, ArtifactDataError,
240    ArtifactLoadError,
241};
242#[cfg(feature = "grid")]
243pub use grid::{Cell, Grid, GridBuildError, GridBuilder, GridEditError, GridStorage};
244#[cfg(feature = "grid")]
245pub use hierarchical::{
246    HierarchicalGridBuildError, HierarchicalGridBuilder, PreparedHierarchicalGrid,
247};
248#[cfg(feature = "navmesh")]
249pub use navmesh::{
250    DynamicNavmeshPortalKey, DynamicNavmeshState, DynamicNavmeshUpdate,
251    DynamicPreparedNavmeshQuery, DynamicPreparedNavmeshQueryMetadata,
252    DynamicPreparedNavmeshQueryResult, DynamicPreparedNavmeshRebuildStatus, Navmesh, NavmeshCell,
253    NavmeshPath, NavmeshPathfinder, NavmeshPortal, NavmeshQuery, NavmeshQueryResult,
254    NavmeshSearchError, NavmeshSearchResult, NavmeshSearchStats, PreparedNavmesh,
255    PreparedNavmeshBuildError, PreparedNavmeshBuilder, StaticPreparedNavmesh,
256    StaticPreparedNavmeshBuilder,
257};
258#[cfg(feature = "grid")]
259pub use path::{Path, PathBuildError};
260#[cfg(feature = "grid")]
261pub use point::Point;
262#[cfg(feature = "polyanya")]
263pub use polyanya::Polyanya;
264#[cfg(feature = "polygonal")]
265pub use polygonal::{
266    NoPathProof, Point2, Polygon, PolygonEndpoint, PolygonScene, PolygonScenePack,
267    PolygonScenePackKind, PolygonSearchRequest, PolygonValidationError, SeparationAxis,
268    WorldBounds, load_polygon_scene_pack, load_polygon_scene_stress_pack,
269};
270#[cfg(feature = "grid")]
271pub use prepared_any_angle::{
272    PREPARED_ANY_ANGLE_CSR_U32_INDEX_LIMIT, PREPARED_ANY_ANGLE_DEFAULT_BENCHMARK_NODE_BUDGET,
273    PREPARED_ANY_ANGLE_DIRECTED_EDGE_BUDGET, PREPARED_ANY_ANGLE_NODE_BUDGET,
274    PREPARED_ANY_ANGLE_RETAINED_BYTES_BUDGET, PreparedAnyAngleBenchmarkAdmission,
275    PreparedAnyAngleBuildDiagnostics, PreparedAnyAngleGrid, PreparedAnyAngleGridBuildError,
276    PreparedAnyAngleGridBuilder, PreparedAnyAngleQueryDiagnostics,
277};
278#[cfg(feature = "grid")]
279pub use preprocessed_grid::{
280    PreparedGridSearch, PreprocessedGridBuildError, PreprocessedGridBuilder,
281    PreprocessedGridMetadata, StaticPreparedGrid, StaticPreparedGridBuilder,
282};
283#[cfg(feature = "grid")]
284pub use search::{
285    GridSearchError, Pathfinder, SearchOutcome, SearchPathCost, SearchRequest, SearchResult,
286    SearchStats, SearchVisitStats,
287};
288// SearchBudget / BudgetExhausted / BudgetWatch are re-exported unconditionally above.
289#[cfg(feature = "polygonal")]
290pub use shortest_path_map::{
291    ContinuousShortestPathMap, PolygonShortestPathMap, PolygonShortestPathMapBuildError,
292    PolygonShortestPathMapBuilder, PreparedContinuousShortestPathMap,
293};
294#[doc(inline)]
295pub use solver_portfolio::{
296    SolverPortfolio, SolverPortfolioRecommendation, SolverRecommendationStatus, SolverSurface,
297    SolverUseCase,
298};
299#[cfg(feature = "polygonal")]
300pub use topological_fracture_search::{TfsDiagnostics, TfsInspection, TopologicalFractureSearch};
301#[cfg(feature = "polygonal")]
302pub use visibility_graph::VisibilityGraph;