3#include <tess/sim/path_agent.h>
4#include <tess/sim/time.h>
22 bool pathing_dirty =
true;
30 std::size_t max_steps = 1;
42 std::uint32_t max_blocked_retries = 8;
47 std::uint64_t tick = 0;
48 bool processed_paths =
false;
51 std::size_t repaths_requested = 0;
52 std::size_t repath_exhausted = 0;
57 state.pathing_dirty =
true;
66inline void set_path_agent_goal(PathAgentTickState& state,
67 PathAgentState& agent, Coord3 goal)
noexcept {
68 static_cast<void>(state);
69 set_path_agent_goal(agent, goal);
78inline auto prepare_path_agent_processing(std::span<PathAgentState> agents,
82 bool needs_processing =
false;
83 for (
auto& agent : agents) {
84 if (!agent.has_goal) {
87 if (agent.phase == PathAgentPhase::NeedsPath) {
88 needs_processing =
true;
91 if (agent.phase != PathAgentPhase::Blocked) {
94 if (agent.blocked_retries < options.max_blocked_retries) {
95 ++agent.blocked_retries;
96 ++stats.repaths_requested;
97 needs_processing =
true;
99 agent.phase = PathAgentPhase::Unreachable;
100 agent.status = PathStatus::NoPath;
101 ++stats.repath_exhausted;
104 return needs_processing;
108template <
typename World,
typename ClassOrTag>
109[[nodiscard]]
auto tick_unit_path_agents(
116 stats.tick = advance_sim_tick(state.clock);
118 const bool repath_needed =
119 prepare_path_agent_processing(agents, options, stats);
120 state.routes.ensure_size(agents.size());
121 if (state.pathing_dirty || repath_needed) {
123 state.pathing_dirty ? PathSubmitScope::All : PathSubmitScope::NeedsOnly;
124 stats.pathing = process_unit_path_agents<World, ClassOrTag>(
125 world, agents, runtime, options.cache_policy, graph, scope,
127 stats.processed_paths =
true;
128 state.pathing_dirty =
false;
131 stats.movement = advance_path_agents(agents, state.routes, options.max_steps);
135template <
typename World,
typename ClassOrTag,
typename OccupancyTag,
136 typename ReservationTag>
138[[nodiscard]]
auto tick_unit_path_agents_with_movement(
141 std::uint32_t movement_dirty_mask = 0,
145 stats.tick = advance_sim_tick(state.clock);
147 const bool repath_needed =
148 prepare_path_agent_processing(agents, options, stats);
149 state.routes.ensure_size(agents.size());
150 if (state.pathing_dirty || repath_needed) {
152 state.pathing_dirty ? PathSubmitScope::All : PathSubmitScope::NeedsOnly;
153 stats.pathing = process_unit_path_agents<World, ClassOrTag>(
154 world, agents, runtime, options.cache_policy, graph, scope,
156 stats.processed_paths =
true;
157 state.pathing_dirty =
false;
161 advance_path_agents_with_movement<
World, ClassOrTag, OccupancyTag,
163 world, agents, state.routes, options.max_steps, movement_dirty_mask);
170template <
typename World,
typename Class, std::u
int32_t MaxCost>
171[[nodiscard]]
auto tick_weighted_path_agents(
178 stats.tick = advance_sim_tick(state.clock);
180 const bool repath_needed =
181 prepare_path_agent_processing(agents, options, stats);
182 state.routes.ensure_size(agents.size());
183 if (state.pathing_dirty || repath_needed) {
185 state.pathing_dirty ? PathSubmitScope::All : PathSubmitScope::NeedsOnly;
186 stats.pathing = process_weighted_path_agents<World, Class, MaxCost>(
187 world, agents, runtime, options.cache_policy, graph, scope,
189 stats.processed_paths =
true;
190 state.pathing_dirty =
false;
193 stats.movement = advance_path_agents(agents, state.routes, options.max_steps);
197template <
typename World,
typename Class, std::uint32_t MaxCost,
198 typename OccupancyTag,
typename ReservationTag>
200[[nodiscard]]
auto tick_weighted_path_agents_with_movement(
203 std::uint32_t movement_dirty_mask = 0,
207 stats.tick = advance_sim_tick(state.clock);
209 const bool repath_needed =
210 prepare_path_agent_processing(agents, options, stats);
211 state.routes.ensure_size(agents.size());
212 if (state.pathing_dirty || repath_needed) {
214 state.pathing_dirty ? PathSubmitScope::All : PathSubmitScope::NeedsOnly;
215 stats.pathing = process_weighted_path_agents<World, Class, MaxCost>(
216 world, agents, runtime, options.cache_policy, graph, scope,
218 stats.processed_paths =
true;
219 state.pathing_dirty =
false;
222 stats.movement = advance_path_agents_with_movement<
World, Class, OccupancyTag,
224 world, agents, state.routes, options.max_steps, movement_dirty_mask);
228template <
typename World,
typename PassableTag,
typename CostTag,
229 std::uint32_t MaxCost>
231[[nodiscard]]
auto tick_weighted_path_agents(
238 stats.tick = advance_sim_tick(state.clock);
240 const bool repath_needed =
241 prepare_path_agent_processing(agents, options, stats);
242 state.routes.ensure_size(agents.size());
243 if (state.pathing_dirty || repath_needed) {
245 state.pathing_dirty ? PathSubmitScope::All : PathSubmitScope::NeedsOnly;
247 process_weighted_path_agents<World, PassableTag, CostTag, MaxCost>(
248 world, agents, runtime, options.cache_policy, graph, scope,
250 stats.processed_paths =
true;
251 state.pathing_dirty =
false;
254 stats.movement = advance_path_agents(agents, state.routes, options.max_steps);
258template <
typename World,
typename PassableTag,
typename CostTag,
259 std::uint32_t MaxCost,
typename OccupancyTag,
typename ReservationTag>
261[[nodiscard]]
auto tick_weighted_path_agents_with_movement(
264 std::uint32_t movement_dirty_mask = 0,
268 stats.tick = advance_sim_tick(state.clock);
270 const bool repath_needed =
271 prepare_path_agent_processing(agents, options, stats);
272 state.routes.ensure_size(agents.size());
273 if (state.pathing_dirty || repath_needed) {
275 state.pathing_dirty ? PathSubmitScope::All : PathSubmitScope::NeedsOnly;
277 process_weighted_path_agents<World, PassableTag, CostTag, MaxCost>(
278 world, agents, runtime, options.cache_policy, graph, scope,
280 stats.processed_paths =
true;
281 state.pathing_dirty =
false;
285 advance_path_agents_with_movement<
World, PassableTag, OccupancyTag,
287 world, agents, state.routes, options.max_steps, movement_dirty_mask);
Definition path_runtime.h:92
Region graph storage specialized by dense or sparse residency policy.
Definition topology.h:309
Summarizes path submission, results, movement, and failure outcomes.
Definition path_agent.h:44
Owns index-paired route copies retained across scoped processing passes.
Definition path_agent.h:88
Configures per-tick movement, caching, and blocked-agent retry limits.
Definition path_agent_tick.h:29
Owns the shared clock, world-dirty flag, and retained routes across ticks.
Definition path_agent_tick.h:13
Summarizes path planning and movement performed during one tick.
Definition path_agent_tick.h:46
Definition path_runtime.h:32
Stores the authoritative monotonically increasing fixed-tick count.
Definition time.h:28