Table of Contents

Struct SpatialObserverSet

Namespace
Typhon.Engine
Assembly
Typhon.Engine.dll

Interest management for one spatial component type: register observers over a region, then ask each what changed since it last looked.

public readonly struct SpatialObserverSet
Inherited Members

Remarks

Obtained from SpatialObservers<T>(DatabaseEngine). The handle is a thin façade over per-component state the engine owns, so it is cheap to obtain and holds nothing that needs disposing; observers themselves live until unregistered.

Delta, with a full-sync fallback. GetSpatialChanges(SpatialObserverHandle, long) walks the entities that actually moved since the observer's last consumption tick and tests each against its region — work proportional to CHANGE, not to region population. An observer that falls further behind than the dirty ring is long gets a full sync instead, flagged by IsFullSync, because the ring can no longer say what it missed.

Why this is public. Before #872 step 13 the interest and trigger systems had no production entry point at all: they were reachable only from tests and benchmarks, and read an entity-level R-Tree that had had no writer since #666 — so the half that was reachable was querying an empty index. Step 13 removed that tree, moved both systems onto the per-cell cluster index, and had to resolve which of the two outcomes the design allowed: port them, or delete them together with their rules/spatial.md modules. They are ported, and this surface is what makes that a fact a test can check rather than a claim.

Properties

ActiveObserverCount

How many observers are currently registered.

public int ActiveObserverCount { get; }

Property Value

int

IsValid

false for a default-constructed value, which every other member rejects.

public bool IsValid { get; }

Property Value

bool

Remarks

A public struct can always be default-constructed, and this one is a façade over engine state it cannot invent. Without the check every member would throw NullReferenceException — the one exception that tells a caller nothing about what they did wrong.

Methods

GetSpatialChanges(SpatialObserverHandle, long)

Entities whose spatial position changed inside the observer's region since it last consumed.

public SpatialChangeResult GetSpatialChanges(SpatialObserverHandle handle, long currentTick)

Parameters

handle SpatialObserverHandle
currentTick long

Returns

SpatialChangeResult

Remarks

The returned spans point into the observer's own buffers and are valid only until this observer's next call.

RegisterObserver(ReadOnlySpan<double>, uint, long)

Register an observer watching bounds.

public SpatialObserverHandle RegisterObserver(ReadOnlySpan<double> bounds, uint categoryMask = 0, long initialTick = 0)

Parameters

bounds ReadOnlySpan<double>

[minX, minY, maxX, maxY] for a 2D component, [minX, minY, minZ, maxX, maxY, maxZ] for a 3D one.

categoryMask uint

Category bits the observer cares about; 0 means "no filter".

initialTick long

The tick the observer is considered to have already consumed. Pass the current tick to start from "nothing new".

Returns

SpatialObserverHandle

UnregisterObserver(SpatialObserverHandle)

Release an observer and its buffers. The handle is invalid afterwards.

public void UnregisterObserver(SpatialObserverHandle handle)

Parameters

handle SpatialObserverHandle

UpdateObserverBounds(SpatialObserverHandle, ReadOnlySpan<double>)

Move or resize an observer's region. Its consumption tick is unaffected.

public void UpdateObserverBounds(SpatialObserverHandle handle, ReadOnlySpan<double> newBounds)

Parameters

handle SpatialObserverHandle
newBounds ReadOnlySpan<double>