std/ecs/events

std/ecs/src/events.trb

Events between systems: a buffer that survives a frame boundary, and the cursor a consumer reads it with.

type EventCursor

type EventCursor with Equals, Show

Where a consumer of Events has read up to. The consumer holds it, so reading is something Events does to a cursor and not to itself.

Examples

var cursor = EventCursor()
assert(cursor == EventCursor())

field seen

var seen: Int = 0

How many events had been sent when the consumer last read, counted from the first one ever sent.

type Events

type Events<Event>

Events as a value in a field of a group of columns: two buffers and a read cursor per consumer, exactly Bevy's shape. A system sends, a system reads, and the program calls advance once per frame.

An event survives exactly two advance calls. A consumer that reads at least once per frame sees every event exactly once; one that skips frames loses the oldest events and gets the rest. Reading changes the cursor and never the events, so a read-only system takes Events by value.

Examples

var events: Events<String> = Events()
var cursor = EventCursor()
events.send "hit"
events.send "miss"
assert(events.read(cursor) == ["hit", "miss"])
assert events.read(cursor).isEmpty()
events.advance()
events.send "heal"
assert(events.read(cursor) == ["heal"])

Pitfalls

  • A consumer that has not read for two advance calls misses the events that were dropped, without a failure; the cursor is not an obligation.

field older

protected var older: List<Event> = []

The events of the frame before, dropped by the next advance.

field newer

protected var newer: List<Event> = []

The events of this frame.

field dropped

protected var dropped: Int = 0

How many events advance has dropped so far; a cursor counts from the first event ever sent.

fn send

var fn send(event: Event)

Adds an event after the ones already sent.

fn read

fn read(var cursor: EventCursor): List<Event>

The events sent since cursor last read, oldest first, and moves cursor to now. The events themselves are not touched.

fn advance

var fn advance()

The frame boundary: the older buffer is dropped and the newer one becomes the older.

fn length

fn length(): Int

How many events are buffered, the ones a consumer that never read would still see.