Context
A typed collection of agents with optional Projections attached. Modeled on Repast Simphony's context concept: membership lives here, structure (positions, edges, networks) lives in attached projections.
Why a separate abstraction from AgentModel._agents:
The model-level registry tracks every setup-time agent for lifecycle dispatch. Contexts are user-defined groupings — pedestrians vs. vehicles, friendlies vs. adversaries, members of organization X — and the same agent can belong to multiple contexts.
Projections need a stable, queryable membership set to attach to. Contexts give it to them; projections subscribe to add / remove via
Projection.onAgentJoined/onAgentLeft.
Context is a ModelElement so it gets a stable name in the model, lifecycle hooks (in case future projections need them), and a place in KSL reporting output. Membership changes during a replication are fine; the context itself must be constructed before simulate().
Generic in the agent type A — typically AgentModel.Agent or a user subclass. Bounded by AgentLike so contexts can also hold PermanentAgent or AgentResource instances.
Properties
The dynamics declared via attachDynamics.
The flow fields declared via attachFlowField, keyed by space name.
The geometry graphs declared via attachGeometry, keyed by projection name.
Read-only view of the current membership.
The named locations declared via location, keyed by name.
Read-only view of attached projections.
Functions
Attach projection to this context. The projection's lifecycle hooks fire on subsequent add / remove operations. Existing members do NOT retroactively trigger onAgentJoined — projections that need to initialize state for all existing members should do so explicitly.
Declare a dynamics so the velocity/force overlay (G10) can sample its per-agent velocities and net forces. Animation-only — no effect on the simulation. A Dynamics is a plain object the model holds, so the animation layer can't find it otherwise. Keyed by space name, so re-declaring each replication (e.g. from initialize()) overwrites rather than accumulates.
Declare that graph supplies the obstacles/costs for the space drawn as projection. This is for animation/extraction only — it does not change simulation behavior (the model still uses the graph however it already does). Lets the animation layer find a graph it otherwise can't discover (a GridGraph is not a model element and projections don't reference one). P5a/G2.
Clear all members and notify projections. Rarely needed now that initialize resets runtime membership automatically; still available for models that want to empty the context mid-replication.
Reset context membership at the start of every replication.
Declares a named location at point.
Declares a named location at point, flattening 3-D to its x–y footprint (G8).
Declare a named location (a landmark / point of interest) at (x, y) in this context's space — a depot, drop-off, station, etc. Like attachGeometry, this is for animation/extraction only: the animation layer surfaces and places it (no hand-authored layout needed); it does not change simulation behavior. Re-declaring a name overwrites its position.