An event is very similar to a Block type Field, bu rather than just storing a single block reference, events are "multi-cast". This means they maintain a list of subscribers, and when calling the event, all subscribers will get a callback.
Although events are most commonly used on .NET and both Cocoa and Java have different paradigms to deal with similar concepts (such as regular Blocks, Delegate Classes (not to eb confused with .NET'suse of the term) and ), events are supported on all platforms.
Event Declaration Syntax
A simple event declaration consists of the
event keyword, followed by a name for the event and the type of Block that can be used to subscribe to the event. The block type can be a named Alias, or an explicit block declaration:
event ButtonClick: EventHandler; // EventHandler is a named block defined elsewhere event Status: block(aMessage: String);
Just as with Stored Properties, with this short syntax the compiler will take care of creating all the infrastructure for the event, including a private variable to store subscribers, and
remove clause can be provided to explicitly name the methods responsible for adding and removing handlers. These methods must then be declared and implemented separately, and they must take a single parameter of the same type as the event (This, too, is comparable to the
write statements for a Property). It is then up to the implementation of these methods to handle the subscription/unsubscription logic.
private method AddCallback(v: EventHandler); method RemoveCallback(v: EventHandler); public event Callback: EventHandler add AddCallback remove RemoveCallback;
Alternatively, on .NET only, a block field to be used for storage can be provided via the
block (or legacy
private fCallback: EventHandler; public event Callback: EventHandler block fCallback;
Subscribing to or Unsubscribing from Events
Externally, code can subscribe or unsubscribe from an events by adding or removing handlers. This is done with the special
-= operators, to emphasize that events are, by default, not a 1:1 mapping, but that each event can have an unlimited number of subscribers.
method ReactToSomething(aEventArgs: EventArgs); //... myObject.Callback += @ReactToSomething //... myObject.Callback -= @ReactToSomething
Please refer to the Event Access Expression topic for more details.
An event can be raised by simply calling it like a Block or Method. Before doing so, one should ensure that at least one subscriber has been added, because firing a unassigned event, just as calling a
nil block, will cause a NullReferenceException.
assigned() System Function or comparison to
nil can be used to check if an event is assigned.
if assigned(Callback) then Callback();
By default, only the type that defines the event can raise it, regardless of the visibility of the event itself. See more on this in the following section.
This visibility extends to the ability to add and remove subscribers, but not to the ability to raise (or fire off) the event, which can be controlled by the
raise statement, described below.
Optionally, separate visibility levels can be provided for the
raise statements. These will override the general visibility of the event itself:
event Callback: EventHandler public add AddCallback private remove RemoveCallback;
raise statement combined with an (also optional) visibility level can be specified, in order to extend the reach of who can raise (or fire off) the event. By default, the ability to raise an event is
private, and limited to rhe class that declares it.
event Callback: EventHandler protected raise;
In the example above, raising the event (normally private) is propagated to a
protected action, meaning it is now available to descendant classes.
Like most type members, events are by default defined on the instance – that means the event can be called on and will execute in the context of an instance of the class. A event can be marked as static by prefixing the event declaration with the
class keyword, or by applying the
static Member Modifier:
class event SomethingChanged: EventHandler; // static event on the class itself event SomethingElseChanged: EventHandler; static; // also static event on the class itself
event SomethingChanged; virtual;
Events can be marked as abstract, if a descendant class must provide the implementation. Abstract events (and events in Interfaces may not define an
event OnClick: EventHandler; abstract;
A number of other Member Modifiers can be applied to events.
ISomeInterface.SomeMember(See Explicit Interface Implementations)
mapped to(See Mapped Members)
optional(Interface members only)