tess 0.4.0
Performance-first tile and path simulation substrate
Loading...
Searching...
No Matches
scheduler.h
1#pragma once
2
3#include <tess/ops/queued.h>
4#include <tess/sim/path_agent_tick.h>
5#include <tess/sim/render_delta.h>
6
7#include <cstddef>
8#include <cstdint>
9#include <span>
10#include <utility>
11#include <vector>
12
13namespace tess {
14
17 PathAgentTickState path_agents{};
18};
19
22 std::uint32_t pathing_dirty_mask = 0;
23 std::uint32_t render_dirty_mask = 0;
24 PathAgentTickOptions path_agent_options{};
25 bool clear_render_dirty = false;
26 std::uint32_t movement_dirty_mask = 0;
27};
28
31 std::uint64_t tick = 0;
32 bool planned_ops = false;
33 bool executed_ops = false;
34 ExecutionReport op_report{};
35 PlannedExecutionResult op_execution{};
36 PathAgentTickStats path_agents{};
37 std::size_t render_delta_count = 0;
38};
39
41template <typename World, WritePolicy Policy, typename Fn>
42auto run_queued_operations(World& world, const FrameOps& ops, Fn&& fn)
45 stats.op_report = plan_operations(world, ops);
46 stats.planned_ops = !ops.empty();
47 if (!stats.op_report.ok()) {
48 return stats;
49 }
50 stats.op_execution = execute_plan<Policy>(world, stats.op_report.plan(), fn);
51 stats.executed_ops =
52 stats.op_execution.status == PlannedExecutionStatus::Executed;
53 return stats;
54}
55
56namespace detail {
57
58// Shared tick sequence for all scheduler variants: run queued operations,
59// mark pathing dirty when planned work dirtied configured pathing fields,
60// run the variant-specific path-agent tick, then collect (and optionally
61// clear) render deltas. `path_tick` returns the variant's
62// `PathAgentTickStats`.
63template <typename World, WritePolicy Policy, typename Fn, typename PathTick>
64auto tick_scheduler_core(SimSchedulerState& state, World& world,
65 const FrameOps& ops,
66 std::vector<RenderTileDelta>& render_deltas, Fn&& fn,
67 const SimSchedulerOptions& options,
68 PathTick&& path_tick) -> SimSchedulerStats {
69 auto stats =
70 run_queued_operations<World, Policy>(world, ops, std::forward<Fn>(fn));
71 // A plan can abort partway (e.g. PolicyMismatch): operations that
72 // already executed have applied their world writes, and execute_plan
73 // reports their chunks in the aborted result's chunk_count. Gate on any
74 // executed chunk rather than on full-plan success so path caches are
75 // refreshed over partially applied plans too.
76 const bool any_op_wrote =
77 stats.executed_ops || stats.op_execution.chunk_count > 0;
78 if (any_op_wrote && options.pathing_dirty_mask != 0) {
79 for (const auto& report : stats.op_report.operations()) {
80 if (report.status == OperationStatus::Planned &&
81 (report.field_access.dirty_mask & options.pathing_dirty_mask) != 0) {
82 mark_pathing_dirty(state.path_agents);
83 break;
84 }
85 }
86 }
87
88 stats.path_agents = path_tick();
89 stats.tick = stats.path_agents.tick;
90
91 const auto old_size = render_deltas.size();
92 collect_render_tile_deltas(world, options.render_dirty_mask, render_deltas);
93 stats.render_delta_count = render_deltas.size() - old_size;
94 if (options.clear_render_dirty) {
95 clear_render_delta_dirty(world, options.render_dirty_mask);
96 }
97 return stats;
98}
99
100} // namespace detail
101
103template <typename World, typename PassableTag, WritePolicy Policy, typename Fn>
104auto tick_unit_scheduler(SimSchedulerState& state, World& world,
105 const FrameOps& ops, std::span<PathAgentState> agents,
106 PathRequestRuntime& runtime,
107 std::vector<RenderTileDelta>& render_deltas, Fn&& fn,
108 SimSchedulerOptions options = {})
110 return detail::tick_scheduler_core<World, Policy>(
111 state, world, ops, render_deltas, std::forward<Fn>(fn), options, [&] {
112 return tick_unit_path_agents<World, PassableTag>(
113 state.path_agents, world, agents, runtime,
114 options.path_agent_options);
115 });
116}
117
118template <typename World, typename PassableTag, typename OccupancyTag,
119 typename ReservationTag, WritePolicy Policy, typename Fn>
121auto tick_unit_movement_scheduler(SimSchedulerState& state, World& world,
122 const FrameOps& ops,
123 std::span<PathAgentState> agents,
124 PathRequestRuntime& runtime,
125 std::vector<RenderTileDelta>& render_deltas,
126 Fn&& fn, SimSchedulerOptions options = {})
128 return detail::tick_scheduler_core<World, Policy>(
129 state, world, ops, render_deltas, std::forward<Fn>(fn), options, [&] {
130 return tick_unit_path_agents_with_movement<
131 World, PassableTag, OccupancyTag, ReservationTag>(
132 state.path_agents, world, agents, runtime,
133 options.path_agent_options, options.movement_dirty_mask);
134 });
135}
136
137template <typename World, typename PassableTag, typename CostTag,
138 std::uint32_t MaxCost, WritePolicy Policy, typename Fn>
140auto tick_weighted_scheduler(SimSchedulerState& state, World& world,
141 const FrameOps& ops,
142 std::span<PathAgentState> agents,
143 PathRequestRuntime& runtime,
144 std::vector<RenderTileDelta>& render_deltas,
145 Fn&& fn, SimSchedulerOptions options = {})
147 return detail::tick_scheduler_core<World, Policy>(
148 state, world, ops, render_deltas, std::forward<Fn>(fn), options, [&] {
149 return tick_weighted_path_agents<World, PassableTag, CostTag, MaxCost>(
150 state.path_agents, world, agents, runtime,
151 options.path_agent_options);
152 });
153}
154
155template <typename World, typename PassableTag, typename CostTag,
156 std::uint32_t MaxCost, typename OccupancyTag, typename ReservationTag,
157 WritePolicy Policy, typename Fn>
159auto tick_weighted_movement_scheduler(
160 SimSchedulerState& state, World& world, const FrameOps& ops,
161 std::span<PathAgentState> agents, PathRequestRuntime& runtime,
162 std::vector<RenderTileDelta>& render_deltas, Fn&& fn,
163 SimSchedulerOptions options = {}) -> SimSchedulerStats {
164 return detail::tick_scheduler_core<World, Policy>(
165 state, world, ops, render_deltas, std::forward<Fn>(fn), options, [&] {
166 return tick_weighted_path_agents_with_movement<
167 World, PassableTag, CostTag, MaxCost, OccupancyTag, ReservationTag>(
168 state.path_agents, world, agents, runtime,
169 options.path_agent_options, options.movement_dirty_mask);
170 });
171}
172
173} // namespace tess
Definition queued.h:1047
Definition queued.h:1157
Definition path_runtime.h:92
Definition world.h:22
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 phase_executor.h:63
Configures dirty propagation, path-agent work, and render-delta clearing.
Definition scheduler.h:21
Owns simulation subsystem state retained across scheduler ticks.
Definition scheduler.h:16
Summarizes queued operations, path agents, and render deltas for one tick.
Definition scheduler.h:30