Signal
Event primitive: a producer holds a `Signal`, consumers attach
handlers with `:Connect`, and `:Fire(...)` invokes every handler in
attachment order. `:Connect` returns a `Connection`; `conn:Disconnect()`
detaches that one handler and `conn.Connected` reports whether it is
still attached.
local sig = Signal.new()
local conn = sig:Connect(function(a, b) ... end)
sig:Fire(1, 2) -- runs every handler with (1, 2)
conn:Disconnect() -- detach this handler
`:Once(fn)` fires the handler at most once, then self-disconnects.
`:Wait()` yields the calling coroutine until the next fire and returns
the fired arguments. `:DisconnectAll()` drops every handler.
Handlers run synchronously inside `:Fire`. A handler that raises is
caught and logged so one bad handler never blocks the rest, and the
connection list is snapshotted before dispatch so a handler may
disconnect itself (or others) mid-fire without skipping a handler.
Handlers must not yield — yielding across the fire boundary raises and
is reported the same way as any other handler error.
Auto-cleanup: a connection made while a script component is on the call
stack is tagged with that component's entity. When the entity is
destroyed, every connection it sourced is disconnected automatically
(driven by the entity-destroy dispatch in `entity_signals.module`), so
a component never has to track and tear down its own connections.
Signals, connections and the indexes below are engine records: a
connection answers to whoever made it, so a module-state restore leaves
every one of them as it stands. `markBaseline` / `resetToBaseline` take
back the connections no component made.
untrackSource(conn: ?) → void
untrackInstance(conn: ?) → void
runDisconnectHook(conn: ?) → void
Run a connection's `_onDisconnect` hook exactly once, on whichever
disconnect path fires first (explicit Disconnect or a DisconnectAll
drain). The hook is a plain field a subscriber system may set on a
connection; it receives the connection and its errors are contained.
Disconnect(self: any) → void
Detach this handler from its signal. Idempotent — a second call
is a no-op. Sets `.Connected` to false.
| arg | type | description |
|---|
| self | any | |
currentInstance( ) → string
makeConnection(self: any, fn: ?) → any
| arg | type | description |
|---|
| self | any | |
| fn | ? | |
Connect(self: any, fn: (...any) → void
Attach a handler. Returns a `Connection` whose `:Disconnect()`
detaches just this handler. Handlers run in attachment order on the
next `:Fire`.
| arg | type | description |
|---|
| self | any | |
| fn | (...any | Handler called with the fired arguments. |
Once(self: any, fn: (...any) → void
Attach a handler that fires at most once, then disconnects itself
before running. Returns the `Connection`.
| arg | type | description |
|---|
| self | any | |
| fn | (...any | Handler called once with the fired arguments. |
Wait(self: any) → void
Yield the calling coroutine until the next `:Fire`, then return
the fired arguments. Must be called from inside a coroutine (e.g. a
`task.spawn` body) — the main thread cannot yield.
| arg | type | description |
|---|
| self | any | |
Fire(self: any, ...: any) → void
Invoke every connected handler with the given arguments, in
attachment order. A handler that raises is caught and logged; the
remaining handlers still run.
| arg | type | description |
|---|
| self | any | |
| ... | any | |
DisconnectAll(self: any) → void
Detach every handler. Each connection's `.Connected` becomes false.
| arg | type | description |
|---|
| self | any | |
connectionCount(self: any) → number
Number of currently-attached handlers. Diagnostic.
| arg | type | description |
|---|
| self | any | |
new( ) → any
Construct a new `Signal`.
examples
local hit = Signal.new()
hit:Connect(function(dmg) print("hit for", dmg) end)hit:Fire(10)
disconnectAllFromEntity(entityId: string) → number
Disconnect every connection that was sourced from `entityId`
(connections made while that entity's script was on the call stack).
Returns the number disconnected. Called by the entity-destroy
dispatch so a destroyed entity's connections never leak.
| arg | type | description |
|---|
| entityId | string | Entity whose sourced connections to drop. |
disconnectAllFromInstance(instanceId: string) → number
Disconnect every connection sourced from a specific component
instance (connections made while that instance's script was on the
call stack). Returns the number disconnected. Called by the component
hot-reload / teardown path so a reloaded instance's stale connections
don't accumulate.
| arg | type | description |
|---|
| instanceId | string | Component instance whose sourced connections to drop. |
markBaseline( ) → number
Record the connections standing right now as the mark
`resetToBaseline` takes back to. A caller running work in an engine it
shares, such as a sweep of test suites, marks before the work and resets after
it.
examples
local mark = Signal.markBaseline()
resetToBaseline(mark: number) → number
Disconnect every connection made since `mark` with no component on
the call stack. A component's connections answer to the component and
go with its entity.
| arg | type | description |
|---|
| mark | number | What `markBaseline` returned. |
examples
Signal.resetToBaseline(mark)