Correct Syntax???!!!

David Burgun dburgun at
Sun Mar 26 10:51:36 EST 2006


I think we are talking about two similar things here and they are  
getting muddled!

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):

Name:                         Group_Select_Folder
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.

Name:                         Group_File_List
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  
notice this!

This is one thing that was drilled into me as a youth when I first  
started programming - "Data dependent algorithms should be avoided  
wherever possible".

> 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  
control here:

> 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 mailing list