pub struct ObsPlanCache { /* private fields */ }Expand description
Cached observation plan with space-topology-based invalidation.
Holds an ObsSpec and an optional compiled ObsPlan. On each
call to execute, checks whether the cached plan
was compiled for the same space (by SpaceInstanceId and cell count).
On mismatch, the plan is recompiled transparently.
§Example
let mut cache = ObsPlanCache::new(spec);
// First call compiles the plan:
let meta = cache.execute(&space, &snapshot, None, &mut output, &mut mask)?;
// Subsequent calls reuse it (same space):
let meta = cache.execute(&space, &snapshot, None, &mut output, &mut mask)?;§Invalidation
The plan is recompiled when:
- No plan has been compiled yet.
- A different space instance is passed (different
SpaceInstanceId). - The same space object’s
cell_count()has changed (topology mutation). invalidateis called explicitly.
The plan is not recompiled when:
- The snapshot’s
WorldGenerationIdchanges (that is per-tick churn, not a topology change).
Implementations§
Source§impl ObsPlanCache
impl ObsPlanCache
Sourcepub fn new(spec: ObsSpec) -> Self
pub fn new(spec: ObsSpec) -> Self
Create a new cache for the given observation spec.
The plan is not compiled until the first call to
execute or get_or_compile.
Sourcepub fn get_or_compile(
&mut self,
space: &dyn Space,
) -> Result<&ObsPlan, ObsError>
pub fn get_or_compile( &mut self, space: &dyn Space, ) -> Result<&ObsPlan, ObsError>
Get the cached plan, recompiling if needed.
Returns the cached plan if one exists and was compiled for the
same space (by SpaceInstanceId and cell count). Otherwise
recompiles from the stored ObsSpec.
Sourcepub fn execute(
&mut self,
space: &dyn Space,
snapshot: &dyn SnapshotAccess,
engine_tick: Option<TickId>,
output: &mut [f32],
mask: &mut [u8],
) -> Result<ObsMetadata, ObsError>
pub fn execute( &mut self, space: &dyn Space, snapshot: &dyn SnapshotAccess, engine_tick: Option<TickId>, output: &mut [f32], mask: &mut [u8], ) -> Result<ObsMetadata, ObsError>
Execute the observation plan against a snapshot, recompiling if the space has changed.
This is the primary convenience method. It calls
get_or_compile then
ObsPlan::execute.
engine_tick is the current engine tick for computing
ObsMetadata::age_ticks. Pass None in Lockstep mode
(age is always 0).
Sourcepub fn execute_agents(
&mut self,
space: &dyn Space,
snapshot: &dyn SnapshotAccess,
agent_centers: &[Coord],
engine_tick: Option<TickId>,
output: &mut [f32],
mask: &mut [u8],
) -> Result<Vec<ObsMetadata>, ObsError>
pub fn execute_agents( &mut self, space: &dyn Space, snapshot: &dyn SnapshotAccess, agent_centers: &[Coord], engine_tick: Option<TickId>, output: &mut [f32], mask: &mut [u8], ) -> Result<Vec<ObsMetadata>, ObsError>
Execute the Standard plan for N agents, recompiling if the
space has changed.
Convenience wrapper over get_or_compile
Sourcepub fn output_len(&self) -> Option<usize>
pub fn output_len(&self) -> Option<usize>
Output length of the currently cached plan, or None if no
plan has been compiled yet.
Sourcepub fn entry_shapes(&self) -> Option<&[Vec<usize>]>
pub fn entry_shapes(&self) -> Option<&[Vec<usize>]>
Entry shapes of the currently cached plan.
Sourcepub fn is_compiled(&self) -> bool
pub fn is_compiled(&self) -> bool
Whether a compiled plan is currently cached.
Sourcepub fn invalidate(&mut self)
pub fn invalidate(&mut self)
Invalidate the cached plan, forcing recompilation on next use.