tess
0.4.0
Performance-first tile and path simulation substrate
Toggle main menu visibility
Loading...
Searching...
No Matches
precheck.h
1
#pragma once
2
3
#include <tess/topology/topology.h>
4
5
#include <cstdint>
6
7
namespace
tess {
8
9
// Outcome of a topology precheck: a cheap region-graph reachability query run
10
// before A* so a definitively unreachable goal is rejected without expanding
11
// the grid. Only `Unreachable` licenses skipping A* -- every other value is
12
// "inconclusive, run A*" -- so the precheck can never turn a solvable query
13
// into a wrong failure (see precheck_rules_out_path).
15
enum class
PrecheckStatus : std::uint8_t {
16
// The graph admits a region path from start to goal; run A* to realize it.
17
Reachable,
18
// The graph definitively rules out any route within known topology. This is
19
// the ONLY status that lets the caller skip A*.
20
Unreachable,
21
// The search reached the edge of the resident set (a boundary exit into a
22
// non-resident chunk): a route through the unloaded region cannot be ruled
23
// out, so run A*. Sparse worlds only.
24
MissingChunk,
25
// Start not resolvable in the graph; run A* (it is authoritative on the
26
// start tile's validity/passability).
27
InvalidStart,
28
// Goal not resolvable in the graph; run A*.
29
InvalidGoal,
30
// The graph no longer matches the world (a topology edit or residency change
31
// since it was built); run A* rather than trust a stale snapshot.
32
GraphStale,
33
// No built graph was supplied; run A*.
34
NoGraph,
35
};
36
37
// True iff the precheck definitively established that no path exists, so the
38
// caller may skip A* entirely. Every other status means "run A*".
40
[[nodiscard]]
constexpr
bool
precheck_rules_out_path(
41
PrecheckStatus status)
noexcept
{
42
return
status == PrecheckStatus::Unreachable;
43
}
44
45
// Cheap pre-A* topology gate. Consults `graph` (built over `world`) for whether
46
// `start` can reach `goal` through region connectivity, WITHOUT expanding the
47
// grid. Staleness is resolved first and conservatively: an empty graph is
48
// NoGraph and a graph that no longer matches the world is GraphStale -- both
49
// BEFORE calling reachable(), because a stale graph can otherwise return a
50
// definitive but wrong Unreachable from an outdated snapshot. `scratch` is
51
// caller-owned and reused across queries (allocation-free once warm); it must
52
// not be shared across concurrent queries.
53
//
54
// `ClassOrTag` (explicit first template argument; `World` stays deduced) is
55
// the movement class the SEARCH uses -- a raw passable tag normalizes to its
56
// WalkableField identity, exactly as in astar_path. The historical
57
// precondition that the graph be built over the same passability is now
58
// ENFORCED through the graph's class stamp: a graph built for a different
59
// movement class (or predating any stamp) reports GraphStale via
60
// is_region_graph_fresh_for, so it degrades to running A* rather than letting
61
// `Unreachable` prune a route the search's own class could walk. Cost
62
// weighting remains irrelevant (weights only order passable tiles).
67
template
<
typename
ClassOrTag,
typename
World>
68
[[nodiscard]]
auto
precheck_path(
69
const
RegionGraphT<typename World::residency_type>
& graph,
70
const
World
& world,
Coord3
start,
Coord3
goal,
RegionGraphScratch
& scratch)
71
-> PrecheckStatus {
72
if
(graph.local_topologies().empty()) {
73
return
PrecheckStatus::NoGraph;
74
}
75
if
(!is_region_graph_fresh_for<ClassOrTag>(world, graph)) {
76
return
PrecheckStatus::GraphStale;
77
}
78
const
auto
result =
79
reachable<typename World::shape_type>(graph, start, goal, scratch);
80
switch
(result.status) {
81
case
ReachabilityStatus::Reachable:
82
return
PrecheckStatus::Reachable;
83
case
ReachabilityStatus::Unreachable:
84
return
PrecheckStatus::Unreachable;
85
case
ReachabilityStatus::Indeterminate:
86
return
PrecheckStatus::MissingChunk;
87
case
ReachabilityStatus::InvalidStart:
88
return
PrecheckStatus::InvalidStart;
89
case
ReachabilityStatus::InvalidGoal:
90
return
PrecheckStatus::InvalidGoal;
91
}
92
return
PrecheckStatus::NoGraph;
// unreachable: all statuses handled above
93
}
94
95
}
// namespace tess
tess::RegionGraphScratch
Reusable frontier and visitation storage for graph reachability queries.
Definition
topology.h:161
tess::RegionGraphT
Region graph storage specialized by dense or sparse residency policy.
Definition
topology.h:309
tess::World
Definition
world.h:22
tess::Coord3
Definition
shape.h:30
include
tess
path
precheck.h
Generated by
1.17.0