On 17 November 2014 12:08, Henrik Johansen <henrik.s.johansen@veloxit.no> wrote:

On 15 Nov 2014, at 10:49 , stepharo <stepharo@free.fr> wrote:

I get dizzy (may be time to go to sleep) but I wonder
why do we need to check first the the window changed and after that it got closed?
Especially since whenWindowChanged: presuppose that we have access to window.
Am I missing something?

self whenWindowChanged: [ :w |��
��������������w whenClosedDo: [ self clear ] ].


ComposableModel>>whenWindowChanged: aBlock
������window whenChangedDo: aBlock


WindowModel>>whenClosedDo: aBlock

������isClosedHolder whenChangedDo: [:value |
��������������value ifTrue: [ aBlock value ] ]


IMHO, APIs that, in essence, glue together announcers and non-self subscribers, are bad, it's an extra level of indirection with little gains. (And quite a few restrictions)
Let the announcers be resolvable, and leave it to subscribers to do the actual subscribing.

To me, it looks like ValueHolders are being used for the sake of using ValueHolders, rather than delivering events in the simplest way possible...
Say you do something like

WindowModel >> announcer
windowAnnouncer := Announcer new

WindowModel >> createWindow
window := blahblah.
window announcer when: GenericWindowEvent do: [:event self announcer announce: event ]-

And all the modelling widgets are free to respond to any window events by subscribing to the models windowAnnouncer, rather than registering blocks for value holders linked to single type changes.

users of whenClosedDo: would instead do something like (usually in an initialize method where it's passed as a windowModel parameter)
windowModel announcer when: WindowClosed do: aBlock
and as such, the code that starts with self whenWindowChanged (I assume in the initialize method on a ComposableModel subclass?)
window announcer when: WindowClosed do: [self clear]


��
After your post, i think i figured, where i see the design flaw. And can articulate it:
��
- the widget model can expose certain properties , like extent, color etc to its controller
- the controller model can expose certain properties of domain object to the widget (for example if we take a list model, it could be: list size, list items, selected item index etc)
- both controller and widget models can expose various events to any interested party(es) via subscription mechanism

��
To me it is clear that properties are not events.. They are conceptually distinct, and there's different mechanisms how and where you use them: you treat one as data, and other as behavior.
Yes, smalltalk largely blurs the distinction between data & behavior since everything is an object, but i think this is the case where you want to keep distinction clear:

- the fact that you should be able to customize your reaction on different events by implementing different behavior, don't means that you should turn that into property e.g. "property which holds a block that will be evaluated when something happens".
No, that's complete nonsense.. when you having announcement mechanism,
you can simply react to announced event the way you want.
And you certainly don't want to react on events like 'what we gonna do when someone changes the block that will be evaluated when certain event triggered'.

Because you want to react on user events, not to events that trigger when your application changes the way it wants to handle the events,
nor
the events that trigger when when your application changes the way it wants to handle the events, that trigger when your application changes the way it wants to handle the events,

nor

the events that trigger when when your application changes the way it wants to handle the events, that trigger when when your application changes the way it wants to handle the events, that trigger when your application changes the way it wants to handle the events
... (you get an idea :)

For example look at:

AbstractWidgetModel subclass: #CheckBoxModel
������ instanceVariableNames: 'actionWhenActivatedHolder actionWhenDesactivatedHolder stateHolder labelClickableHolder labelHolder'
������ classVariableNames: ''
������ category: 'Spec-Core-Widgets'

It is clear that
actionWhenActivatedHolder and actionWhenDesactivatedHolder are events which should just be announced by widget, that anyone would want to handle. period.
you don't need ValueHolder(s) to hold blocks running in case of such events.

Phew...