The Artima Developer Community
Sponsored Link

Agile Buzz Forum
Round Trip Events

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
James Robertson

Posts: 29924
Nickname: jarober61
Registered: Jun, 2003

David Buck, Smalltalker at large
Round Trip Events Posted: Nov 2, 2003 10:30 PM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by James Robertson.
Original Post: Round Trip Events
Feed Title: Travis Griggs - Blog
Feed URL: http://www.cincomsmalltalk.com/rssBlog/travis-rss.xml
Feed Description: This TAG Line is Extra
Latest Agile Buzz Posts
Latest Agile Buzz Posts by James Robertson
Latest Posts From Travis Griggs - Blog

Advertisement
Much thanks to Sames for this one. I had a recent scenario which involved one view (event consumer) and many objects (event sources) it was observing. At first blush it was not quite as easy to set up this scenario as it had been with c/u (changed:/update:). With c/u I would've just created the case statement obimination and used the third argument off of update:with:from: to figure out who I was getting the event from.

You can set your consumers event handler to include information like this:

theObservedObject when: #someEvent send: #respondToChangeIn: with: theObservedObject

This works fine, until you've caused the event source (theObservedObject in the above) to already include some information in addition to the event, something like:

theObservedObject triggerEvent: #someEvent with: someData

What happens is that when the method respondToChangeIn: gets sent, theObservedObject will NOT be what you get as your argument, you'll get the someData that came from theObservedObject.

Luckily, we have other ways of setting up handlers. We can use something like:

theObservedObject when: #someEvent do: [:arg | self respondToChangeIn: theObservedObject]

Problem solved! Kind of. Now the next part of the problem comes along. How do we clean these things up? In many cases, you don't care. The life cycle of the source and consumer is the same and they and the graph created by their interconnected event triggering can just all go away together. I was not so fortunate. My event sources were long lived. And the consumers (one or many) could come and go arbitrarily at will. The last thing you want in a case like that is one where the view gets created, then closes, but is kept alive (ergo, it is not GC'ed) because its still recieving events from the source. This means we want to somehow do something like:

theObservedObject removeAllActionsWithReciever: ourConsumer

Even if we could've got the original to work, this is a problem. It requires our consumer to not only build a handler for the source, but to remember the source (in an ivar or something) so that we can remove them in a release method. Now our actions are blocks (for those that seem to fear blocks, you can use a MessageSend if that eases your closure indigestion a little), and we've got to remember those.

This was where Sames entered the picture and shared the zen masters sense of event-ness with me. C/u, especially with its roots so tied to MVC, is always very unidirectional in event flow. Very client/server-ish. Events seem to encourage a more peer to peer mind set of event flow. The trick is to have the source and consumer flip roles. Cause the consumer to trigger a #release event, and then create handlers for this event which clean things up. With our original consumer object now also triggering events, we can set the whole thing up in one method, something like:

 | action |
action := [:arg | self respondToChangeIn: theObservedObject].
theObservedObject when: #someEvent do: action.
self when: #release do: [theObservedObject removeAllActionsWithReciever: action]

The more I use events versus c/u, the more I like them. One could argue (I have) that technically they and c/u are really no different. Technically, that's probably true. But then, that's like arguing that Java and Smalltalk are both turing complete. I find with events, I'm encouraged to use different (that means better in this context) idioms and approaches than I would with c/u, and that ultimately I wrote smaller/simpler object interactions, and that's a good thing. Thanks again Sames!

Read: Round Trip Events

Topic: Day light savings Previous Topic   Next Topic Topic: Does it walk the dog too?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use