[Squeakfoundation]Ad-hoc final harvesting for 3.4

Rob Withers squeakfoundation@lists.squeakfoundation.org
Sun, 8 Dec 2002 23:31:19 -0500


Hi Andreas,

It's probably useful to discuss publically, if nothing else than to learn
about how your scripting system works!   It's interesting.  The subscripter
(new word!) holds onto his scripts and knows where they are triggered from?
Are you thinking Linda?  :).

My first reaction to this, aside from thinking how neat it is to have
scripts, is that this is a different 'layer' than multicast events.  With
events, you have to have a reference to the object with which you are
establishing a registration (the window does know the button), therefore
your object knows which of his objects are publishers of interesting events.
Since the object holds a reference to his event publishers, he _can_ reflect
about his subscriptions and it is still reasonably memory compact.  The
frequency of the subscriber reflecting is much less (presumably) that the
evaluation of registrations by the publisher.

What the events cause to happen in specific objects is up to the subscriber,
which is where your scripts fit, I believe.

You said:
> Ever looked at EventMessageSet?! I did this for probably the exact same
> reasons that you are using weak messages sends now. And yet, neither is
> not going to solve your problems ;-(

I am not aware of a problem that this doesn't solve that I want to solve
with this event code.  :)    I believe the 3.4 events will do what you want.

and you then said:
> to do this. And while this is a nice first-order theory it is
> problematic if we close that window by any other means (in which case we
> may want to stop the subscription) and naturally, the button will hold
> on to the window for the rest of its live. This is the problem which you
> are trying to solve with weak references but it is conceptually wrong.

we are solving this problem.  The button doesn't strongly hold the window in
the registration.  If the window goes bye-bye, the button (if it doesn't go
bye-bye too), will drop that registration.

and then:
> weak refs) and the publisher is not bothered by it [*1]. However, what's
> even more important is that in a case like the above, the window can
> reflect about its subscriptions and cancel them if it gets closed
> without having to know any "external subscriptions" (e.g., added by
> someone else).

have you really looked at the New events code regarding its deregistration
facet?  :)   The NuBlu events introduce the following dereigstration
interface: (
    #releaseActionMap   "hari-kari"
    #removeActionsWithReceiver: object  "your targeted deregistration"
    #removeActionsWithReceiver:forEvent:  "even finer grained based on the
target"
    #removeActionsForEvent: "disable an event"
    #removeAction:forEvent:  "even finer grained based on the action"
    #removeActionsSatisfying:forEvent: "queriable to filter receivers or
actions")

This should handle any reflection and discretionary registration management
you may want.


regarding you examples of scripts, why not do this:
    button when: #click send: #startScript: to window with: #close.

and in close:
    button removeActionsWithReceiver: self.

your intialize (and destroy) are very interesting, since you are controlling
the responsiveness to events *and* controlling the scheduling of your
scripts.  It sounds to me like the scripts may be better suited to be the
receivers of these event registrations, and the scripts can either be
receptive (active) or not for triggered events.  If you turn off receptivity
at the script, even if the event fires, you could ignore it (conditional
code/state machine - yuck) in the script, or you could deregister the
action.  Or...control the state of the MessageSend that you register.

So, how about:
Morph>>#startScript: aScriptName when: anEvent from:  publisher
    |script|
    script := self scriptNamed: aScriptName ifAbsent: [self error: 'unknown
script'].
    script startWhen: anEvent from: publisher.
    ^ script

and:

Morph>>pauseScript: aScriptName when: anEvent from: publisher
    |script|
    script := self scriptNamed: aScriptName ifAbsent: [self error: 'unknown
script'].
    script pauseWhen: anEvent from: publisher.
    ^ script

This is really only sugar, since you are hardcoding the script action you
want to result from the event.  What happens if you have to add another
script action, like retry?  Do you add retryScript:when:from:?

I am quite sure that I am missing a lot of what scripts are doing and I
unfortunately haven't had time to look deeply again.  However, I do feel
that a separation of concerns is useful to distinguish scheduling state
control from event registrations.

There is something missing from my arguments, and I think it comes from not
understanding scripts.  They seem to be editable anonymous methods, that has
special scheduling properties.  You have made the script a first class
object which needs to bridge the script owner with any event publishers.

One thing to consider is that you can control the type of MessageSend used
in a registration with #when:evaluate:.  In squeak-e I use EventualMessages
and FutureMessages in addition to MessageSends.  Perhaps you need a
ScriptActivation heirarchy of message sends?

cheers,
robert