RAD - Case Study Version 2
dburgun at dsl.pipex.com
Tue Mar 28 08:09:47 EST 2006
On 27 Mar 2006, at 19:26, Mark Wieder wrote:
> Monday, March 27, 2006, 2:01:22 AM, you wrote:
>> I looked at your example and the ISM stack I have developed is *VERY*
>> similar to your mc2_libDispatcher. The only main difference I can see
>> is that I have a secondary Message/Event ID which I call a "Kind".
>> This is to allow you to have more than one copy of the same event.
> Obviously I can't paste the whole library in here, but yes, the
> approach is very similar. Not sure why you need the "Kind" property.
> The tuple of sender-message-observer should uniquely identify and
> event, no?
I explained this in more detail in reply to another post you made.
Basically it's so you can more than one of the same message-type.
There is a Base Folder object in the standard library, it has a Kind
of "FolderKindDefault" (or whatever). If you want another object that
does exactly the same thing, but instead of being (say) a source
folder, it's a destination folder, you just change the "kind" of
folder selected. I hold this "kind" in a custom property (I don't
*need* to have it in a custom property, it could be a constant in the
script(s)) in both the Sender and the Receiver. In your example you
have to change a line of the script (the object name) in order to
register the to receive the message. in mine I just change the custom
property. If I used a constant, I'd have to change the script too. It
just seems easier to change a custom property then change a script.
All the objects in the Object Library default to a "XXXKindDefault"
whether they send or receive events so as standard (e.g. only one of
the said object is needed) they just work without changing
*anything*, *anywhere*. e.g. The object that sends the Folder
Selected message sends "FolderKindDefault" and the object that
receives the Folder Selected message listens for "FolderKindDefault",
so they work straight out of the box Just paste them into a stack and
they work! No need to change *anything*, *anywhere*.
It's only if you want to have more than one Folder Selected Generator
and/or more than one Folder Selected Receiver that you need to change
anything and in that case all you need to change is the "kind" custom
Paste the "Select_Folder" Object from the Object Library (sends
"FolderKindDefault" via a custom property).
Paste the "Select_File" Object from the Object Library (receives
"FolderKindDefault" and sends "FileKindDefault" via custom properties).
Now you want to have a "Select_SourceFolder" , a ""Select_
DestinationFolder", a "Select_SourceFile" and a
"Select_DesintionFile" in the card.
Paste another copy of the "Select_Folder" Object from the Object
Paste another copy of the "Select_File" Object from the Object Library.
If you now ran the stack, selecting a folder in either of the folder
objects would send a "FolderKindDefault" message. The same goes for
the file object(s), it would send "FolderKindDefault" or
"FileKindDefault", and any object "listening" would receive the
message. So you'd get the *same* folder path name displayed and the
same file list displayed in both sets of objects.
If you now change the two new objects so the Custom Property was now
"FolderKindDestination" and "FileKindDestination" then they now would
work independently and so two different folders/files would be
>> There is also a difference in the way in which your example actually
>> uses the Dispatcher, you do your "Listening" or "Registering" at the
>> Stack level, which means you have to change the Stack Script when you
>> add a control to the stack:
> The two lines of code I listed were the *only* changes anywhere. I
> cheated and put them into a "Register" button for testing, but they
> could have gone into the openStack handler. Interesting idea, though -
> I'll have to take a look at your code again. You're saying that the
> objects register themselves? Hmmm. That sounds like it's breaking the
> Loosely-Coupled Objects pattern. My main goal was to ensure that
> controls don't need to know where their events are coming from. Drag
> and drop, then connect the dots.
It's the same for ISM. The Objects don't know where the message is
coming from either. I put the "register" or "listen" in the object(s)
so that I can just delete the object and it stops "listening" without
having to change *anything*, *anywhere*. The idea is that the object
in the Object Library has as many bells and whistles as possible,
then if want less functionality you just delete it, e.g. you
customize the object to suite the requirements once pasted into your
stack. If you find that a particular customized object is being used
a lot, you can then rename the object and paste it back into the
ObjectLibrary as a variant of the original.
By deleting an object here, I mean that, for instance, in the Object
Library the "standard" folder selected object is a group that has a
clear button, a choose button, a label with fixed text that says
"Folder Selected" and a locked field that holds the Folder Path Name
of the currently selected folder.
The choose button sends a "FolderSelected", "FolderKindDefault"
message, it is always enabled.
The clear buttons sends "FolderSelected", "FolderKindDefault" with
an empty folder path name, it also listens for "FolderSelected",
"FolderKindDefault" and enables or disables itself depending on
whether the folder selected is empty or not. So pressing the clear
button sends an empty folder to itself as well as any other object
that is "listening!).
The Folder Path Name field listens for "FolderSelected",
"FolderKindDefault" and stores path name of the folder selected by
the user into itself. It also has Drag and Drop code in it's script
that allows a folder to be dropped onto it in which case it sends a
"FolderSelected", "FolderKindDefault" message (which is received by
the same field since it is Listening and sets it's contents to the
folder selected by the user (either from the choose button or from
itself via the drag and drop operation)).
The "FolderKind" is held in the Custom Property so changing that
changes the kind of folder sent and listened for with the Group Object.
You can delete any of the objects inside the object group and all the
other objects in the group will still work, it's just that the
deleted object is no longer listening.
The "FolderSelected", "FolderKindDefault" can be sent from
*anywhere*, from a different stack, card, group or control and object
(s) will get the event!
>> This means you are hardcoding control names into the stack. I *could*
>> do it this way too, but in order to allow objects to be pasted and
>> duped in a stack and have them just work without changing any other
>> scripts, I do the "Register" at the control level.
> Got it. You change the script of the object when you paste it in. I
> went the other way, allowing the objects to be pasted without any
> changes. I think I avoided a lot of the pitfalls you're finding. But
> the approach sounds equally valid.
No! I don't change *anything* if I only have one of the object type.
If I want more than one (as above) I then change the custom property
that specifies the "kind" of message sent and received. Obviously I
have to change that custom property in *all* objects, but copy and
paste makes that easy and less error prone.
>> Other than that the concepts are identical!
> Yep. The big difference, I think, is that extracting the event
> dispatching into a library means that you can instrument a control to
> be an event generator with one line of code and you can likewise
> instrument a control to receive events with just a setProp handler.
> And then the objects are totally reusable.
It's the same, see above! It's just I use a custom property instead
of changing a script.
The bottom line is that (AFAIK!) you *have* to change something
somewhere, you change a script, I change a custom property. I was
toying with the idea of using the long name of the object as the
"kind". Then you'd have to change the name. I thought that this would
be more work though so used a custom property instead.
Thanks a lot for this discussion - all I can say is great minds think
All the Best
More information about the Use-livecode