Subscription Handles and Event Values
Every subscription produces a subscription handle, and an event name in value position produces an event value. The handle covers unsubscribing and stats; the event value covers passing a channel around as data.
event Ticked(n: int);
event MovedX(dx: int);
var total = 0;
func Add(n: int)
{
print($"added {n}");
}
func Track(n: int)
{
total += n;
}The Subscription Handle’s Three Members
The value of a ~> / <~ / once ~> expression is a subscription: Cancel() unsubscribes, IsCancelled reports status, TriggerCount counts firings:
val h: subscription = Ticked ~> Add;
emit Ticked(1);
print("triggered", h.TriggerCount, "cancelled?", h.IsCancelled);
h.Cancel();
emit Ticked(2);
print("cancelled?", h.IsCancelled);
h.Cancel();added 1
triggered 1 cancelled? False
cancelled? TrueAfter cancellation, later emits are not delivered, and calling Cancel() again is harmless.
once: Auto-Cancel After One Firing
A once ~> subscription automatically becomes cancelled after its first firing:
val single = Ticked once ~> Add;
emit Ticked(10);
emit Ticked(20);
print("once cancelled?", single.IsCancelled, "count", single.TriggerCount);added 10
once cancelled? True count 1Unsubscribing Anonymous Lambdas
An anonymous lambda subscription gets a handle too; keep the handle and unsubscribe with it:
val lh = Ticked ~> (n: int) => { total += n; };
emit Ticked(100);
lh.Cancel();
emit Ticked(1000);
print("total =", total);total = 100Events as First-Class Values
An event name in value position is an event value, typed by the shape type event<P...>. Equality is by declaration identity (only the same declaration compares equal), and an emit through a value still runs the pipelines declared on it:
val v: event<int> = MovedX;
print(v == MovedX);
emit v(7);TrueA “group of channels” can be expressed as a list of event values, subscribed and unsubscribed in a loop:
val watch: list<event<int>> = [MovedX, Ticked];
for e in watch
{
e ~> Track;
}
emit MovedX(3);
emit Ticked(4);
print("total =", total);total = 107Notes
- Event values must share the same payload shape: more, fewer, or mismatched parameter types cannot be assigned to each other.
eventof(obj.Prop)takes an event prop channel as anevent<T, T>value (payload: old value, new value), usable like any other event value afterwards.- A generic event’s type arguments are inferred from the handler’s parameters or the emit arguments.
