System Module
Generic system pipeline for composing frame updates with type-enforced snapshot boundaries.
This module provides a pipeline pattern where mutable systems run first (physics, particles), then a snapshot is taken, and readonly systems run on the snapshot. The type system enforces this ordering at compile time.
The pipeline accumulates a single Cmd (not a list) to keep it fast: no list appends, no reversing, and no quadratic behavior as you add phases.
Pattern Overview:
-
- Begin with mutable model -
- Run systems that mutate (physics, AI movement) -
- Take readonly snapshot (type changes from Model to Snapshot) -
- Run readonly systems (rendering prep, queries) -
- Convert back to model and return the accumulated command
Example
let updateSystems model =
model
|> System.start
|> System.pipeMutable physicsSystem
|> System.pipeMutable particleSystem
|> System.snapshot Model.toSnapshot
|> System.pipe aiDecisionSystem
|> System.finish Model.fromSnapshot
Functions and values
| Function or value |
Description
|
|
Dispatch commands based on snapshot state. Use for systems that produce messages without modifying state. The snapshot passes through unchanged.
Example
namespace System
|
|
Dispatch commands with input selection from snapshot.
Use for encapsulated/autonomous subsystems that:
The selector extracts relevant data from the snapshot, allowing the dispatcher to remain decoupled from the parent's model structure.
Example
val healthTracker: (obj voption -> obj -> obj)
type 'T voption = ValueOption<'T>
val mutable hp: float32
val input: obj voption
val snap: obj
Multiple items
module ValueOption from Microsoft.FSharp.Core -------------------- [<Struct>] type ValueOption<'T> = | ValueNone | ValueSome of 'T static member Some: value: 'T -> 'T voption static member op_Implicit: value: 'T -> 'T voption member IsNone: bool with get member IsSome: bool with get member Value: 'T with get static member None: 'T voption with get val iter: action: ('T -> unit) -> voption: 'T voption -> unit
val amt: float32
val min: e1: 'T -> e2: 'T -> 'T (requires comparison)
val selectHealthInput: snap: 'a -> 'b voption
val snap: 'a
union case ValueOption.ValueSome: 'T -> ValueOption<'T>
union case ValueOption.ValueNone: ValueOption<'T>
namespace System
|
|
|
|
|
|
|
|
Transition from mutable Model to readonly Snapshot. This is the "barrier" in the pipeline. After calling snapshot, only readonly systems (using System.pipe) can be added.
Example
namespace System
|
Full Usage:
start model
Parameters:
'Model
Returns: 'Model * Cmd<'Msg>
Modifiers: inline Type parameters: 'Model, 'Msg |
Mibo