dburgun at dsl.pipex.com
Sun Mar 26 09:51:36 CST 2006
I think we are talking about two similar things here and they are
1. Developing new controls and code to control them.
2. Re-using Existing Controls or Groups of Controls that are stored
in an "ObjectLibrary" (which is really just a "Dummy" stack that is
used to store the objects).
For point 1, you have to write new code regardless of the method
employed. Whether it's in one location or spread over a few different
objects make no real odds. The Code to solve the problem will be
roughly the same. The main difference is that using ISM I can then
make the new Group/Control available via the "ObjectLibrary" and it
will work with any existing objects in the library.
For point 2, I can just drop a number of objects/groups from the
Object Library into a new stack and they will interact with each
other without changing *anything*, *anywhere*. Also if I want the
same group/object twice, then I just paste it twice and change the
Custom Property that specifies the "kind" of message. This means of
course that code in a control may be duplicated in another control.
However, this is nothing stopping you having a "common" function
defined in the Group that can be called from all the controls within
that group, I do this a lot. Also there is nothing stopping you
"listening" at the group level, then the Message will be sent to the
Group and it can do what it needs to do to the objects "below" it, in
the same way as having a "mouseUp" handler in the group and using
"target". In fact "target" still works and returns the target of the
control that caused the event (e.g ControlX:mouseUp->ISMPutMessage-
>GroupY:MessageHanlder returns the target "ControlX". The fact that
the message was delivered via ISM doesn't matter). Similarly Groups/
Controls can do a "start using" and get access to all routines
defined in a Library Stack. I haven't tried it but I can't see any
reason why Front/Back Scripts wouldn't work either. So ISM isn't
ignoring the xTalk environment it's just making it easier to re-use
objects and it's ensuring that only objects that need to have an
action taken are visited.
In a similar manner you can also "listen" at the card or stack level
or have "common" functions at the Card or Stack Level.
It also aids in documentation since you can easily do something like
this (which I am in the process or doing):
Purpose: Allows the User to choose a folder and
broadcasts the folder to all listening objects.
Message Sent: msg_FolderSelected, sends cpFolderKind and the
Path Name of the Folder selected.
Custom Properties: cpFolderKind, defaulted to "FolderKindX", change
if you wish to send a different folder kind.
Message Handled: None.
Purpose: Displays a List of Files in a Specified
Folder, allows the user to select a file and broadcasts the file to
all listening objects.
Message Sent: msg_FileSelected, sends cpFileKind and the
Path Name of the File selected.
Custom Properties: cpFolderKind, defaulted to "FolderKindX", change
if you wish to receive a different folder kind.
cpFileKind, defaulted to
"FileKindX", change if you wish to send a different file kind.
Message Handled: msg_FolderSelected.
It makes debugging easier too. I have some functions in ISM that
switch on/off Debug mode. With Debugging enabled, ISM will dump
information into a field or file and you can then trace the messages
being sent and which handlers are being called, along with the
message data. There are also filters that work in a similar (but more
specialized) way to the Message Watcher in the IDE. It also dumps the
time in the message handler so you can see how long a particular
message takes to process.
> No, there is no hard-coding of object names in the script anywhere.
> That is always a bad idea and always to be avoided. And the script
> example I posted deals transparently with new objects, deleted
> objects, and existing objects. You don't have to do anything.
Ok, then you have to scan all objects.
> As for visiting each object, this isn't much of an issue given
> Revolution's engine speed; I have successfully updated thousands of
> objects in a preopenstack handler in only a few ticks. With your
> method, there must be some way for the "listening" objects to know
> they are supposed to listen.
I keep a number of Arrays which are fast. There is some overhead in
the "send" command but I've found it is faster then visiting all
objects especially when dealing with multiple stacks.
> The only way you can do that without scanning all objects in the
> stack is to keep a list somewhere of which objects need to be
> triggered, and use "send" to send an instruction to each object in
> the list in order to trigger that response. The "send" command has
> a high overhead; I'd guess that with a long list of objects to
> trigger your method could take as much time or longer than a simple
> repeat scan. Another disadvantage to keeping such a list is that
> you have yet another detail to maintain in your setup.
I really can't see this! Say you had 100 objects but only 10 needed
to be updated. The code to do the updating would be roughly the same
in either case, so we are only talking about 10 additional "sends" as
the overhead. I can't see that running a repeat loop for 90
additional objects is faster than doing 10 sends.
Surely the only time scanning all objects would be faster in this
case is if the number of objects needing "action" at a given time is
near to the total number of objects, the worse case being if all 100
needed action. In this case my method would incur the time taken to
do 100 sends, however the actual processing time needed to perform
the action(s) is likely to be large in this case and the overhead of
one additional send per object would be a small percentage of the
total processing time.
If we now change the total number of objects to 1000, but only 10
needed to be updated then you are visiting 990 additional objects!
The real point here is that using your method you can't tell in
general how much overhead an update for a particular action will
take, it will depend on the total number of objects, e.g. the
algorithm is data dependent and will slow down as the number of
objects grows. Whereas my method I can calculate the overhead exactly
and that overhead will be in direct proportion to the number of
objects needing attention as a result of an event.
According to Richard Gaskin a Send operation has an overhead of
0.011 ms. So for 100 objects we are talking about 1.1 thousandths of
a second and for 1000, 11 thousandths of a second and that's only if
*ALL* the objects needed attention. I doubt if a user would even
This is one thing that was drilled into me as a youth when I first
started programming - "Data dependent algorithms should be avoided
> I'll snip the rest; I really didn't mean to start an argument. And
> I get the feeling that neither of us really understands the other's
> method, so I probably shouldn't keep talking. I only wanted to
> point out to those who may still be following this that your method
> adds some overhead and a degree of complexity that isn't necessary,
> and it ignores the native message path and object inheritance that
> Revolution depends on for efficiency. Using Revolution's native
> techniques, I believe, will be simpler and more productive. But if
> you have found a way to do something you like, that's fine with me.
> I certainly have no argument with that, and it is proof that Rev
> can be used in so many ways that it can accomodate all styles and
> scripting techniques. If you like how your method works, that's
> great. Really, I don't have an disagreement with that.
See above, my method doesn't stop you from doing this.
I snipped the rest too, since I think the first few paragraphs
explain how we are talking at cross purposes here and hopefully
explains my method a little more clearly. You don't *need* to have a
script on *each* control, you can handle the message at a higher
level if you want to and it doesn't stop you from using any of the
features of the xTalk environment. There are differing levels of
> Sigh. No, I'm not scared of "different" things. You've been using
> xtalk for 2 years, I've been using it for 21 years. I have pretty
> much figured out, I think, which methods work best. In my HyperCard
> days, someone told me once that I wrote the most elegant and
> efficient code they had ever seen. I don't usually toot my own
> horn, but that was something that made me very proud. I have spent
> quite a bit of time figuring out what works and I use those methods
> in my professional work. But I have no "fear" of any experimental
> method you choose to use. I probably won't use it myself, as it
> doesn't seem to be the best use of the xtalk paradigm, but feel
> free by all means.
I wasn't really aiming that remark at you personally or anyone on
this list. I was actually a bit hacked off with the attitude of
someone I work with who won't even look at anything unless it's coded
in C++! I had just gotton off the phone with him when I wrote it and
I suppose it bubbled over into this discussion. Please accept my
sincere apologies if I caused offense. You have been of great help to
me in on the list in the past and I would like to take this
opportunely to say "THANKS A LOT".
Take Care and All the Best
More information about the use-livecode