Event propagation
What is an event?
An event is something that happens in the world. When a dog barks,
for example, a sound event is generated. This sound event is represented
as an object containing information about who created the sound, where,
how loud, etc. As soon as the dog barks, the dog will create an instance
of a sound event. Now what? Well let's say Joe is standing in the same
room as the dog - unless he is deaf, he should hear the sound of
the dog barking. In this particular case the dog is the event source
and Joe is an event listener. There can only be one source but there
can be an indefinite amount of listeners.
Of course, not all events are sound events. If Joe smiles, that's
an event too. Maybe the dog will see Joe smiling and wag his tail. It's
the same thing - the event travels from the source (Joe) to all
potential listeners (including the dog). Note that I use the term
listener even when it's not specifically a sound event, for the
sake of consistency.
An event is thus something that has happened, and event propagation
is about how that event travels through from the source to all potential
listeners.
How does an event propagate?
The main issue here is that the event should only be propagated to those
that care to listen. The issue is similar to that of GUI programming (and
I got some inspiration by studying the internal design of the Java AWT
classes when designing this model) - a mouse click should only be reported
to those who might want to do something about a mouse click. Otherwise
the windowing system would be wasting too much time sending events to components
that don't care anyway.
For this reason the Physical
class (see the class relations document)
defines methods like wantsPropertyEvents and wantsSoundEvents. These answer
true if that particular instance is interested in receiving such
events.
Now there are two types of event interest: direct and indirect.
If an object is directly interested in a particular type of event,
for example sound events, then that means the object really wants those
events and will do something about the event if it receives one. If an
object is only indirectly interested in a particular type of event,
then that object is only interested because one or more of it's children
(or other dependents) are interested, and if it receives an event it will
ignore it and propagate it along to the registered listeners.
Example - Joe & the puppy in the pub
OK let's take a concrete example. Our world consists of four objects: the
pub, Joe, the puppy, and a chest. By default the sound interest of each
of these objects is as follows:
The pub: not interested
Joe: directly interested
Puppy: directly interested
Chest: not interested
Let's say Joe enters the pub. As soon as he does so, he will tell the pub
(in the program - not in "reality") that he is interested in sound events.
This means that the pub itself is now indirectly interested in sound events.
Let's say the puppy also enters the pub. The same thing will happen, although
now the pub was already indirectly interested so nothing changes. The status
is now:
The pub: indirectly interested
Joe: directly interested
Puppy: directly interested
Chest: not interested
If the puppy barks now, a sound event will be produced by the puppy.
The sound event will "reach" the puppy first, ie the puppy will hear his
own bark (and will probably not be too surprised about that). The sound
will then propagate to all listeners - in this case none, since no one
has registered sound interest to the puppy. Finally, the sound will propagate
"upwards" in the container hiearchy (this is the default behaviour of the
Physical class from which most objects are derived - these rules are summarized
later), ie the sound will be propagated to the Pub.
When the pub receives the event, it will not process it on it's own
(since it couldn't care less about sound). That means the pub won't really
"hear" the event, but it must still propagate it. In this case it has two
listeners: Joe and the puppy. It will not propagate the event back
down to the puppy, since that's the direction from which the event came,
but it will propagate the event down to Joe.
Joe will receive the event and process it (which might mean that the
client program that is controlling Joe will display a message such as "the
puppy barks"). That's it. Joe has no listeners, and he is not allowed to
send it up to his parent (the Pub) since that is where the event came from.
Here's an illustration of how the event moves through the container hierarchy:
If the puppy jumps into the chest, the chest will also become an indirect
listener to sound events. This means if Joe says "hi", the sound event
will reach the objects in this order:
-
Joe will send the event to the Pub (since that is Joe's "parent")
-
The pub will send the event to the chest (since the chest is registered
as a listener to the Pub).
-
The chest will send the event to the puppy (since the puppy is registered
as a listener to the chest).
Summary of propagation rules
The basic propagation rules are defined in the Item class. These rules
state that when an event is received, do the following:
-
Process the event, if I am directly interested in it.
-
Propagate the event to all registered listeners. Exception: never propagate
the event back the same direction from which it came.
The Physical class (being a
subclass if Item - see the class
relations document) adds one more step to this:
-
Process the event, if I am directly interested in it.
-
Propagate the event to all registered listeners. Exception: never propagate
the event back the same direction from which it came.
-
Propagate the event to my parent (unless I received the event from my parent).
It is important to differ between the event sender and the event
source. In the example above when Joe receives the bark event, the
puppy is the definite source of the event, but the Pub is (from
Joe's point of view) the sender of the event.
Current event classes
The current event hierarchy looks something like this.
![](eventHierarchy.gif)
To learn more details about these classes check out the Actions
document.
Henrik
Kniberg
Last updated: