New Tutorial on Events in Squeak, Pharo and Cuis

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

New Tutorial on Events in Squeak, Pharo and Cuis

Peter Dinges
Hello everyone,

I recently started to study Morphic and its implementation in Squeak, Pharo,
and mostly Cuis. Reading through the code, I noticed that there currently are
three implementations of "events". All of them are mechanisms to signal state
changes; two are very generic, the third specializes in Morphic input.

Slightly confused by the many meanings of "event", I began to sort the
different parts and assign them unique names. The result of this process is a
short tutorial on Events in Squeak, Pharo, and Cuis. It might reduce confusion
for people starting their tour through the code, or simply help when using
events in own projects.

You can download it from

        http://www.elwedgo.de/fileadmin/events_in_smalltalk.pdf

I would greatly appreciate any comments, ideas, or corrections.

Thanks and have a good day,
Peter

Reply | Threaded
Open this post in threaded view
|

Re: New Tutorial on Events in Squeak, Pharo and Cuis

Juan Vuletich-4
Peter Dinges wrote:

> Hello everyone,
>
> I recently started to study Morphic and its implementation in Squeak, Pharo,
> and mostly Cuis. Reading through the code, I noticed that there currently are
> three implementations of "events". All of them are mechanisms to signal state
> changes; two are very generic, the third specializes in Morphic input.
>
> Slightly confused by the many meanings of "event", I began to sort the
> different parts and assign them unique names. The result of this process is a
> short tutorial on Events in Squeak, Pharo, and Cuis. It might reduce confusion
> for people starting their tour through the code, or simply help when using
> events in own projects.
>
> You can download it from
>
> http://www.elwedgo.de/fileadmin/events_in_smalltalk.pdf
>
> I would greatly appreciate any comments, ideas, or corrections.
>
> Thanks and have a good day,
> Peter
>  

Hi Peter,

Nice writing, thank you! Just a few comments.
- #when:send:to: and #changed/#update serve a similar purpose, and only
one of them is really needed. Their main use is to reflect model changes
in user interfaces. For instance, PluggableMorphs use #changed/#update
and LightWidgets use #when:send:to: for this.
- At the implementation notes of #changed/#update you forgot about class
Model.
- At the implementation notes of #when:send:to: you didn't mention that
ActiveModel is an optimization, using own actionMap instance variable
and not the dictionary in the class side. This optimization is not
unlike the one in Model.
- MorphicEvents are really something really different... They are not
message sends, but objects. This is not an implementation of the
observer pattern, there is no mechanism for message delivery. Instead,
MorphicEvents are stateful objects that are sent around until handled.
- You forgot the AbstractEvent hierarchy. While this is not as general
as #when:send:to: and #changed/#update, it is closer to them than
MorphicEvents are. AbstractEvent is used to notify various Smalltalk
tools of system changes.

I hope you find these comments useful on your journey. Please keep your
document updated with further explorations!

Cheers,
Juan Vuletich

Reply | Threaded
Open this post in threaded view
|

Re: New Tutorial on Events in Squeak, Pharo and Cuis

K K Subbu
In reply to this post by Peter Dinges
On Tuesday 16 Nov 2010 8:55:52 pm Peter Dinges wrote:
> You can download it from
>
>         http://www.elwedgo.de/fileadmin/events_in_smalltalk.pdf
>
> I would greatly appreciate any comments, ideas, or corrections.
Good stuff. You should add it to squeak wiki so that you can directly link
terms to their wiki entries.

when:send:to: and changed/update are used for different situations. WS is used
when event listeners are known apriori and the listener is interested in the
happening. Changed/update is used when they are unknown and the listener is
interested in the state change caused by the event.

For instance, when up key is pressed in a list, the listener is well known and
interested only in the happening of key press. WS is ideal for this case. On
the other hand, when a value in viewer is changed, an unknown number of
watchers need to read the new value. This would be a case for changed/update.
Of course, we could use a WS when the watcher is created but it wouldn't be
simple.

In your CU example, Alice would be an instance of Dresser and Bob will be an
instance of Eater, where Dresser and Eater are subclasses of Person. Alice
would wear office dress if the alarm went off in the morning or an evening dress
if it went off in the evening.

Subbu

Reply | Threaded
Open this post in threaded view
|

Re: New Tutorial on Events in Squeak, Pharo and Cuis

Peter Dinges-2
Hello Subbu,

> Good stuff. You should add it to squeak wiki so that you can directly link
> terms to their wiki entries.

thank you very much. Putting the text into the squeak wiki is on my todo list.

Also, thank you for your clarifications on the different usage scenarios.
Unfortunately, I think I do not fully grasp why CU events are easier for
unknown listeners. All that a change from CU to WS events seems to require is
maybe a relocation of the registration code(?)

[Note that my text is meant as a description of what is, not of what should
be. What was/is important to me, is to document that several mechanisms exist
so that people don't end up looking for errors in the wrong places.]

Suppose we have a viewer as you proposed. When a value in the viewer is
changed,
- with CU events, viewer would issue "self changed: #valueUpdate";
- with WS events, viewer would issue "self triggerEvent: #valueUpdate".

> For instance, when up key is pressed in a list, the listener is well known
> and interested only in the happening of key press. WS is ideal for this
> case. On the other hand, when a value in viewer is changed, an unknown
> number of watchers need to read the new value. This would be a case for
> changed/update. Of course, we could use a WS when the watcher is created
> but it wouldn't be simple.
Why is it more complicated? At some point you have to tell the watcher which
viewer to watch. So couldn't you just have a method

Watcher>>watch: viewer
    viewer when: #valueUpdate send: #doSomethingWatcherSpecific to: self

that is called during initialization (or maybe later)? It certainly has more
characters than "viewer addDependent: self", but avoids the (possibly) huge
distinction of cases in Watcher>>update:

Also, if the watcher watches several viewers, it has to query all of them if
it only receives the CU event "update: #valueUpdate". (The viewer triggering
the update might not be provided.) With WS events, above method could be
modified to:

MultiWatcher>>watch: viewer
    viewer when: #valueUpdate
           send: #doSomethingWatcherSpecific
           to: self
           with: viewer

No code change in the viewer class is required to accomodate MultiWatcher :-)

> In your CU example, Alice would be an instance of Dresser and Bob will be
> an instance of Eater, where Dresser and Eater are subclasses of Person.
> Alice would wear office dress if the alarm went off in the morning or an
> evening dress if it went off in the evening.
I guess I overemphasized instance specific behavior. The situation I made up
to show that CU events are less general probably rarely occurs in real code. I
will incorporate your suggestion in the next version.

Cheers,
Peter

Reply | Threaded
Open this post in threaded view
|

Re: New Tutorial on Events in Squeak, Pharo and Cuis

K K Subbu
On Sunday 21 Nov 2010 9:57:06 am Peter Dinges wrote:
> Unfortunately, I think I do not fully grasp why CU events are easier for
> unknown listeners. All that a change from CU to WS events seems to require
> is maybe a relocation of the registration code(?)
CU and WS are meant for different scenarios. Studying senders of model: will
make the context clear. CU is for situations where the views are intentionally
decoupled from the object being observed (model).

> Suppose we have a viewer as you proposed. When a value in the viewer is
> changed,
> - with CU events, viewer would issue "self changed: #valueUpdate";
> - with WS events, viewer would issue "self triggerEvent: #valueUpdate".
The viewer does not know the number and kind of listeners interested in the
changes so it cannot register handlers for them. Of course, you could add a
method in the Viewer that Watchers can call when created to register a handler
for them but it would only be duplicating CU logic in a roundabout way.

> Why is it more complicated? At some point you have to tell the watcher
> which viewer to watch. So couldn't you just have a method
A watcher is for a single variable in a morph. When you click on 'simple
watcher' or 'detailed watcher' from a variable's menu in a Viewer, the watcher
is created to get/set that variable from that morph.

Subbu

Reply | Threaded
Open this post in threaded view
|

Re: New Tutorial on Events in Squeak, Pharo and Cuis

Peter Dinges
In reply to this post by Juan Vuletich-4
Hi Juan,

thanks for telling me about the optimizations in Model and ActiveModel; I
guess I should have looked more thoroughly at which classes reimplement parts
of the mechanisms. I will add a paragraph to the implementation notes.

> - MorphicEvents are really something really different... They are not
> message sends, but [...] stateful objects that are sent around until
> handled.
OK, I see your point. They do, however, fulfill the criterion of "signaling an
asynchronous state change" (the user pressed a key, etc.). Don't you think
that they should at least get mentioned?

> - You forgot the AbstractEvent hierarchy. While this is not as general
> as #when:send:to: and #changed/#update, it is closer to them than
> MorphicEvents are. AbstractEvent is used to notify various Smalltalk
> tools of system changes.
Concerning the AbstractEvent hierarchy: I do not know why I had not found this
one, but you are of course right, it deserves some paragraphs in the text.
Furthemore, Torsten Bergmann noted that Pharo additionally includes the
Announcements framework. So two more event mechanisms to choose from. :-)

Thank you very much for your comments. The next draft will certainly benefit
from them. Also thank you for your work on Cuis.

Cheers,
Peter

Reply | Threaded
Open this post in threaded view
|

Re: New Tutorial on Events in Squeak, Pharo and Cuis

Juan Vuletich-4
Hi Peter,

Peter Dinges wrote:

> Hi Juan,
>
> thanks for telling me about the optimizations in Model and ActiveModel; I
> guess I should have looked more thoroughly at which classes reimplement parts
> of the mechanisms. I will add a paragraph to the implementation notes.
>
>  
>> - MorphicEvents are really something really different... They are not
>> message sends, but [...] stateful objects that are sent around until
>> handled.
>>    
> OK, I see your point. They do, however, fulfill the criterion of "signaling an
> asynchronous state change" (the user pressed a key, etc.). Don't you think
> that they should at least get mentioned?
>  

Yes, sure. I just say that it is not a direct replacement for
#when:send:to: and #changed/#update. Those are indeed redundant, but
MorphicEvent is not IMO.

>> - You forgot the AbstractEvent hierarchy. While this is not as general
>> as #when:send:to: and #changed/#update, it is closer to them than
>> MorphicEvents are. AbstractEvent is used to notify various Smalltalk
>> tools of system changes.
>>    
> Concerning the AbstractEvent hierarchy: I do not know why I had not found this
> one, but you are of course right, it deserves some paragraphs in the text.
> Furthemore, Torsten Bergmann noted that Pharo additionally includes the
> Announcements framework. So two more event mechanisms to choose from. :-)
>  

Right.

> Thank you very much for your comments. The next draft will certainly benefit
> from them. Also thank you for your work on Cuis.
>
> Cheers,
> Peter
>  

Good! You're welcome!

Cheers,
Juan Vuletich