Re: Parent of Target
On Wed, Aug 23, 2017 at 1:30 PM, Monte Goulding via use-livecode < use-livecode@lists.runrev.com> wrote: > We could parse the message being sent and check if there’s a handler that > can handle it at the time it’s being sent but that would be a dangerous > change > > Wouldn't it be a bit less drastic to simply allow an error handler to be specified? send "foo" to field "bar" in 7 seconds handle with button "oops" of this stack ? With a rule naming the handler to be used in a script? (perhaps, "on errorHandler (target, error)" -- Dr. Richard E. Hawkins, Esq. (702) 508-8462 ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
> On 24 Aug 2017, at 2:07 am, Mark Wieder via use-livecode > wrote: > > Good to know. Yeah, that's weird. It’s not _that_ weird. Using in time there’s no context to throw an error on at the time the handler is sent… Of course pending messages could keep track of the caller info which would also be handy for sending private handlers to yourself in time (which I would love). We could parse the message being sent and check if there’s a handler that can handle it at the time it’s being sent but that would be a dangerous change causing errors here and also not cope with object deletion etc between using the send command and handling it: send “Foo” to me in 0 start using stack “FooBar" Cheers Monte ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 08/23/2017 08:23 AM, Trevor DeVore via use-livecode wrote: That is correct, as long as you aren’t using `in time` with `send`. The following script won’t cause an error until the last `send`: Good to know. Yeah, that's weird. -- Mark Wieder ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 08/23/2017 08:50 AM, Bob Sneidar via use-livecode wrote: This is actually useful. Let's say you have some fields which do some basic validations against database table constraints and some that do not require them. You could simpy dispatch a command to validate to all fields and only the ones which need to will handle the message. I like it. Right. I use dispatch in that mode quite a lot. Sometimes I want to check the returned status to see if I need to do something, but in other cases an "unhandled" return state is fine. -- Mark Wieder ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
This is actually useful. Let's say you have some fields which do some basic validations against database table constraints and some that do not require them. You could simpy dispatch a command to validate to all fields and only the ones which need to will handle the message. I like it. Bob S > On Aug 23, 2017, at 08:44 , prothero--- via use-livecode > wrote: > >> Right. >> Dispatch will return an "unhandled" status if it can't be executed, while >> send will throw an error. >> >> -- >> Mark Wieder >> ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
Odd. I wouldn't have guessed the dependence on "in time" for the send command. Bill P William Prothero http://es.earthednet.org > On Aug 23, 2017, at 8:22 AM, Mark Wieder via use-livecode > wrote: > >> On 08/23/2017 07:59 AM, Bob Sneidar via use-livecode wrote: >> Wh??? So send would but dispatch won't? >> Bob S >>> On Aug 23, 2017, at 06:21 , Trevor DeVore via use-livecode >>> wrote: >>> >>> I'm in the habit of using "dispatch" as it mimics how the engine works and >>> won't throw an error if a message isn't handled. > > Right. > Dispatch will return an "unhandled" status if it can't be executed, while > send will throw an error. > > -- > Mark Wieder > ahsoftw...@gmail.com > > ___ > use-livecode mailing list > use-livecode@lists.runrev.com > Please visit this url to subscribe, unsubscribe and manage your subscription > preferences: > http://lists.runrev.com/mailman/listinfo/use-livecode ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On Wed, Aug 23, 2017 at 9:59 AM, Bob Sneidar via use-livecode < use-livecode@lists.runrev.com> wrote: > Wh??? So send would but dispatch won't? > That is correct, as long as you aren’t using `in time` with `send`. The following script won’t cause an error until the last `send`: on mouseUp send "NotThere" to me in 0 seconds dispatch "NotThere" to me send "NotThere" to me end mouseUp -- Trevor DeVore ScreenSteps www.screensteps.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 08/23/2017 07:59 AM, Bob Sneidar via use-livecode wrote: Wh??? So send would but dispatch won't? Bob S On Aug 23, 2017, at 06:21 , Trevor DeVore via use-livecode wrote: I'm in the habit of using "dispatch" as it mimics how the engine works and won't throw an error if a message isn't handled. Right. Dispatch will return an "unhandled" status if it can't be executed, while send will throw an error. -- Mark Wieder ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
OH! "This sends the message down the normal message path starting at the object containing the script. " And here I've been thinking that a target was required for specificity, because of this in the dictionary: "If no target is specified, the message is sent to ' me '. In the context of a behavior, this is typically the child that is executing rather than the behavior object itself." Life just go easier. BR On 8/22/17, 6:42 PM, "use-livecode on behalf of Trevor DeVore via use-livecode" wrote: This is the part that I don't think I understand. Why do you need to turn the long id of the parent into a small array and dispatch to to any object along the path? From the search custom control I would just do the following: dispatch "behaviorSearchAndFilter" You can then handle the message farther down in a group, card, or stack script. What is it you are trying to accomplish with the parent of the search custom control? ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
Wh??? So send would but dispatch won't? Bob S > On Aug 23, 2017, at 06:21 , Trevor DeVore via use-livecode > wrote: > > I'm in the habit of using "dispatch" as it mimics how the engine works and > won't throw an error if a message isn't handled. ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
I have that very thing. I call it searchBar. It looks pretty much like a search field from a browser or Finder window (in a somewhat earlier version of the OS) and it's designed to retrieve data and update a datagrid. I would post the rather simple code, except it is dependent on sqlYoga and some custom functions I have. I could probably make it self contained (although it almost is now) but that has no value to me. If you are interested I can send you a stack with the custom control, and you can massage it to do what you want. Bob S > On Aug 22, 2017, at 15:46 , Trevor DeVore via use-livecode > wrote: > >> >> See earlier longer memo. >> USE CASE aka "Problem to Solve" >> >> is a frame work with multiple stacks/aka "modules" with content. >> >> Search will be a global requirement. >> >> I can identify, at least for now, three "classes" of content to be search >> in any given context/module >> > > Hi BR, > > Let's see if I understand the problem sufficiently. Below you will find my > responses. If they seem way off then assume I didn't understand the > question :-) > > You have multiple components that are involved with a basic search UI. At > the very least you need the following: > > 1. The UI element that the user types the search term into. > 2. The code that processes the search term entered and fetches the search > results > 3. The UI element that displays the search results. ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On Wed, Aug 23, 2017 at 1:33 AM J. Landman Gay via use-livecode < use-livecode@lists.runrev.com> wrote: > On 8/22/17 11:42 PM, Trevor DeVore via use-livecode wrote: > > Why do you need to turn > > the long id of the parent into a small array and dispatch to to any > object > > along the path? From the search custom control I would just do the > > following: > > > > dispatch "behaviorSearchAndFilter" > > > > This sends the message down the normal message path starting at the > object > > containing the script. > > Would you even need "dispatch"? Why not just "behaviorSearchAndFilter"? I'm in the habit of using "dispatch" as it mimics how the engine works and won't throw an error if a message isn't handled. In this case you could argue that you want an error to occur if you haven't implemented the handler. When I'm testing a component I don't want to deal with the debugger opening up though. -- Trevor DeVore ScreenSteps > ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 8/23/17 1:33 AM, J. Landman Gay via use-livecode wrote: On 8/22/17 11:42 PM, Trevor DeVore via use-livecode wrote: Why do you need to turn the long id of the parent into a small array and dispatch to to any object along the path? From the search custom control I would just do the following: dispatch "behaviorSearchAndFilter" This sends the message down the normal message path starting at the object containing the script. Would you even need "dispatch"? Why not just "behaviorSearchAndFilter"? Actually, where's that list showing the mesage path hierarchy as regards behaviors? I know I saw it somewhere once. I need a refresher. -- Jacqueline Landman Gay | jac...@hyperactivesw.com HyperActive Software | http://www.hyperactivesw.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 8/22/17 11:42 PM, Trevor DeVore via use-livecode wrote: Why do you need to turn the long id of the parent into a small array and dispatch to to any object along the path? From the search custom control I would just do the following: dispatch "behaviorSearchAndFilter" This sends the message down the normal message path starting at the object containing the script. Would you even need "dispatch"? Why not just "behaviorSearchAndFilter"? -- Jacqueline Landman Gay | jac...@hyperactivesw.com HyperActive Software | http://www.hyperactivesw.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On Tue, Aug 22, 2017 at 6:11 PM, Sannyasin Brahmanathaswami via use-livecode wrote: > > > in this case behavior_SearchAndFilter is attache to the searhView custom > control > > yep I plan that simple dispatch > > hence my function to turn the long idea of the parent into a small array > > when can dispatch discretely to any object along the path of the target This is the part that I don't think I understand. Why do you need to turn the long id of the parent into a small array and dispatch to to any object along the path? From the search custom control I would just do the following: dispatch "behaviorSearchAndFilter" This sends the message down the normal message path starting at the object containing the script. You can then handle the message farther down in a group, card, or stack script. What is it you are trying to accomplish with the parent of the search custom control? -- Trevor DeVore ScreenSteps www.screensteps.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
Trevor I'm sorry I muddied the waters by using the word "widget" which I have carelessly tossed around in the past for "small group of objects that team up for a job" But really widgets are widgets now and what I mean is "custom Control" You understand me very well…. The card or SearchView behavior scripts would call any library handlers as needed and then massage the search results into a format that can be displayed in the search results UI element [3]. Using the above approach your UI elements are self contained and can be reused. The behaviors attached to these UI elements should not use complicated branching. Just dispatch messages and let the "controllers" catch and process the messages. exactly! in this case behavior_SearchAndFilter is attache to the searhView custom control yep I plan that simple dispatch hence my function to turn the long idea of the parent into a small array when can dispatch discretely to any object along the path of the target Brahmanathaswami ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On Tue, Aug 22, 2017 at 3:24 PM, Sannyasin Brahmanathaswami via use-livecode wrote: > > See earlier longer memo. > USE CASE aka "Problem to Solve" > > is a frame work with multiple stacks/aka "modules" with content. > > Search will be a global requirement. > > I can identify, at least for now, three "classes" of content to be search > in any given context/module > Hi BR, Let's see if I understand the problem sufficiently. Below you will find my responses. If they seem way off then assume I didn't understand the question :-) You have multiple components that are involved with a basic search UI. At the very least you need the following: 1. The UI element that the user types the search term into. 2. The code that processes the search term entered and fetches the search results 3. The UI element that displays the search results. Here is how I design such things. The search UI element [1] is a custom control/widget in and of itself that can be reused multiple times your application. Because it involves text entry it will probably be a custom control and not just a widget. Make this custom control completely self contained. It should not need to know anything about what is going on outside of the custom control. The custom control should dispatch a message when the user does something that should trigger a search (e.g. types some number of characters or presses the return key). You might use a name like "SearchOnTerm" for the message name. The code that handles the "SearchOnTerm" message and searches using the search term [2] can go in a couple of different places. The lowest place I would but it (I think of messages as falling down) is the behavior script attached to the card the search UI element appears on. If your search widget is part of yet another custom control (let's call this SearchView) that also includes the UI element that displays the search results [3] AND you have a behavior attached to SearchView then I would handle "SearchOnTerm" there. The card or SearchView behaviors will do whatever needs to be done with the search term. Maybe this card searches an array. Maybe it queries a SQL database. Or maybe it makes a REST call. [1] and [2] don't need to know about what is going on. [1] sends a message, the card or SearchView behavior code processes and then displays it in [3]. Of course you can use libraries to contain handlers that help with searching. Perhaps you have a handler that parses a search phrase and breaks it up into a SQL query or REST request. The card or SearchView behavior scripts would call any library handlers as needed and then massage the search results into a format that can be displayed in the search results UI element [3]. Using the above approach your UI elements are self contained and can be reused. The behaviors attached to these UI elements should not use complicated branching. Just dispatch messages and let the "controllers" catch and process the messages. > We had developed this framework (since about Feb of 2016) starting with > libs, but over time behaviors are becoming more and more useful. Then I > watched Trevor's Levure Video… and see that he's doing very much what we > are, though I'm not sure where levure goes when we get to the > "widget/custom-controls that will be used in many stacks/across many > context" use case, and believe me, you will be there in no time at all. > There is nothing special that you have to do with widgets as they are single controls. If you ever update the widget code and recompile then the widget is updated in your entire application. Levure doesn't ship with a Helper (features are added to Levure using Helpers) that provides templates. I have one Levure app that has a template concept in it and one that doesn't. The general concept is that you use a card to layout a "view" that will be used in your application. You can then insert this "view" anywhere you want. Updating the "view" on the card will go through your app and update all instances of the "view". This type of functionality isn't directly connected to any particular framework, though a framework can make it easier to work with templates and package up the resulting application. -- Trevor DeVore ScreenSteps www.screensteps.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
[ignore previous post… hit send prematurely] [@ Trevor if you have thoughts based on your experience with Levure… love to hear the ] Disclaimer: this my first time ever doing something with such a huge, modular architect, all previous experience to data has been in 1 Stack with Many Cards = 1 App This new frame work is Many text only libs/models/behaviors Many binary stacks which are -- content rich with many cards -- act as pure "view" containers -- a "customControls" with one custom control per card which again serves as a mini "view" anywhere at any time. Mark Wieder via use-livecode" wrote: >># do different things based on calling context. That's exactly the opposite of what behaviors are for. BR: ?? but a behavior may contain a script with a mouseup handler at that responds to different targets with different actions/results. >> I'm not sure I follow the underlying reasoning here Thank you. That was my reaction as well. B- what problem are you trying to solve? See earlier longer memo. USE CASE aka "Problem to Solve" is a frame work with multiple stacks/aka "modules" with content. Search will be a global requirement. I can identify, at least for now, three "classes" of content to be search in any given context/module 1) an array with the full data extract from our media metadata database. where one might want to search in the title, file name subtitle 2) a list (of song titles, or books, or chapters or whatever) = highly likely to be refactored to DataGrid 2 in many contexts when that is rolled out. 3) a field with text, typically chapter of a book aggregated text form different sources into one field. In all these stacks/modules, the UI/UX will want to offer search. so then, you are faced with 1) create code for each module in the behavior that runs that stack/card = you will be re-created the same scripts over and over again in dozens of places = be forced to add this every time a new module is added to the frame work. OR 2) Use a library that is always open and it is booted into the back script with start using on init. OR 3) create a behavior that is can be attached to a small group comprised of a searchstring field and a search button. You say "used all over the place" breaks the mandate for use of behaviors… my actual experience says otherwise When used in a library, you don't get "me" and "me" is very useful. e.g. in our customControls stack we have a "socialShare" group this is dynamically copied on demand to modules as needed. There is a behavior attached to this group. The local module/card has commands that insert the data to be share, in this context, to local var in behavior which is the card script, This card script has a function which returns that data function getShareData return sShareData end getShareData Now the behavior for the group ( has buttons for FB, Twitter and Email and perhaps more once we get Global Connect into this mix) just has to check the target, and getShareData() I don't remember exactly why today, but as I was developing that, I was working harder, writing more code when I tried is as a lib. But as a behavior, some how it was both easier to write and easier to debug… Anyway.. using a behavior as an "agent" to handle processes called from different context/stacks works pretty well . All I have to do is attached it to the search Button and it will server everywhere. Very easy to find, just edit the behavior of the search but (oh yeah, that was another advantage over libs. if functions/handlers are very unique to a given context, then doing it as a behavior means you have super easy access via the Inspector for the very obvious controls that would use it: vs, scanning through and clicking on the script for the library in the Project Browser. We had developed this framework (since about Feb of 2016) starting with libs, but over time behaviors are becoming more and more useful. Then I watched Trevor's Levure Video… and see that he's doing very much what we are, though I'm not sure where levure goes when we get to the "widget/custom-controls that will be used in many stacks/across many context" use case, and believe me, you will be there in no time at all. BR Who constantly faces "choice paralysis" because Livecode makes it too easy to do almost anything, any way you want, and without a lot of experience in module frameworks, its too easy to hack yourself into mess of spaghetti code: and having experienced this last year (a great deal of pain ove initial work done on the app) I'm constantly "over thinking what is the best way here…" ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 08/22/2017 12:53 PM, Sannyasin Brahmanathaswami via use-livecode wrote: Mark Wieder via use-livecode" wrote: >># do different things based on calling context. That's exactly the opposite of what behaviors are for. BR: ?? but a behavior may contain a script with a mouseup handler at that responds to different targets with different actions/results. I see two ways of dealing with this: 1. Override the mouseUp handler in the objects that need special handling. That way the behavior script will take care of the other objects, and you can still have specialized actions without having to test for the target. 2. If you need different mouseUp actions in every object that uses the behavior script, don't put the mouseUp handler in the behavior script. You're just creating extra work for yourself that you have to unwind later on. B- what problem are you trying to solve? See earlier longer memo. Will dig through the archives when I have time. -- Mark Wieder ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
Mark Wieder via use-livecode" wrote: >># do different things based on calling context. That's exactly the opposite of what behaviors are for. BR: ?? but a behavior may contain a script with a mouseup handler at that responds to different targets with different actions/results. >> I'm not sure I follow the underlying reasoning here Thank you. That was my reaction as well. B- what problem are you trying to solve? See earlier longer memo. I've waffled between ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 08/21/2017 12:54 PM, J. Landman Gay via use-livecode wrote: # do different things based on calling context. That's exactly the opposite of what behaviors are for. I'm not sure I follow the underlying reasoning here Thank you. That was my reaction as well. B- what problem are you trying to solve? -- Mark Wieder ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
I don't understand quite what you're trying to do. If this is a behavior, the calling context is "me" or the "long name of me", isn't it? Also, why store it? It's always there. I'm likely missing something. On 8/21/17 1:35 PM, Sannyasin Brahmanathaswami via use-livecode wrote: Back at it here with attempst to make "generic" behaviors as text only stacks that can serve as slaves "all over the place" So this is all about the calling context/target. I wonder If I am working too hard here, may be useful to have the calling context ready for a dispatch, to parse the long owner? So this little array that could be stored as a local and then used later in the script to "do something different" based on the calling context. local sOwnerHierarchy on mouseup put the short name of the target into pTarget put the long owner of the target into sOwnerHierarchy split sOwnerHierarchy with " of " -- ## test ## put the number of lines of the keys of tOwner into tLevels repeat with x = 1 to tLevels put tOwner[x] & cr after tHierarchy end repeat put tHierarchy -- ## end test ## switch pTarget case "search" if fld "searchString" is empty then answer "Please enter a search string" with "OK" exit to top else runsearch pClass, pContent end if break end switch end mouseup command runSearch pClass, pContent # do different things based on calling context. - I'm not sure I follow the underlying reasoning here - why not just use 'the long id of the target'?* The message path means that the message will hit the group/card/stack if not handled in the control (which it won't be, from what you are saying). ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode -- Jacqueline Landman Gay | jac...@hyperactivesw.com HyperActive Software | http://www.hyperactivesw.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
Back at it here with attempst to make "generic" behaviors as text only stacks that can serve as slaves "all over the place" So this is all about the calling context/target. I wonder If I am working too hard here, may be useful to have the calling context ready for a dispatch, to parse the long owner? So this little array that could be stored as a local and then used later in the script to "do something different" based on the calling context. local sOwnerHierarchy on mouseup put the short name of the target into pTarget put the long owner of the target into sOwnerHierarchy split sOwnerHierarchy with " of " -- ## test ## put the number of lines of the keys of tOwner into tLevels repeat with x = 1 to tLevels put tOwner[x] & cr after tHierarchy end repeat put tHierarchy -- ## end test ## switch pTarget case "search" if fld "searchString" is empty then answer "Please enter a search string" with "OK" exit to top else runsearch pClass, pContent end if break end switch end mouseup command runSearch pClass, pContent # do different things based on calling context. - I'm not sure I follow the underlying reasoning here - why not just use 'the long id of the target'?* The message path means that the message will hit the group/card/stack if not handled in the control (which it won't be, from what you are saying). ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 08/10/2017 12:10 PM, Richard Gaskin via use-livecode wrote: Indeed - a very poor example on my part. Also "teh" is not a recognized token. :) Yes, but if we're looking for common code patterns... -- Mark Wieder ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
AHH HAAH HAHAHAA ! I have often thought of pointing that out. :-) Bob S > On Aug 10, 2017, at 12:10 , Richard Gaskin via use-livecode > wrote: > > Also "teh" is not a recognized token. :) ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Speed of control lookup (Was Re: Parent of Target)
> On 12 Aug 2017, at 7:26 pm, Mark Waddingham via use-livecode > wrote: > > I'd be happier about introducing a new id if we could solve the multiple > mainstack with same name issue too (or at least get a step closer to it) Hmm… what about giving stacks a meaningful ID… stack ID is completely useless right now as far as I can tell. What is currently the stack ID could be just an internal thing to maintain the ID sequence and stacks could be assigned a read only session ID. I very much doubt such a change would break any code but I guess I could be wrong there… Perhaps better to make these references storable would be a UUID (ducks ;-). Maybe if _only_ stacks had a UUID they would be more palatable? Cheers Monte ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Speed of control lookup (Was Re: Parent of Target)
On 08/12/2017 02:26 AM, Mark Waddingham via use-livecode wrote: I'd be happier about introducing a new id if we could solve the multiple mainstack with same name issue too Yes, please. -- Mark Wieder ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Speed of control lookup (Was Re: Parent of Target)
On 2017-08-11 23:58, Monte Goulding via use-livecode wrote: That would mean speed improvements could be done on an object reference that is relatively robust to changes in the object tree and unless you are creating an IDE you would be very unlikely to need to do the LCB object reference repository thing. I was pondering that whilst writing my 'experiment'. Whilst it says 'for strict long ids', its strictness is more in the string structure (all tokens lowercase, all integers 0 or start with 1, one space between tokens etc. - this is mainly where the speed comes from - the 'parser' in my experiment is basically an unrolled regular expression). It could be evolved to parse more general control chunk chains over time. Indeed, I was wondering whether 'minimal id' might be a reasonable name - however, whatever the name, there's still the choice of stack short name vs filename. I'd be happier about introducing a new id if we could solve the multiple mainstack with same name issue too (or at least get a step closer to it) - whilst it might be nice to think it could be done with more appropriate search order, given the move towards libraries and other such things I worry that no search order would ever solve the problem really; and would end up with issues appearing in complex circumstances which are hard to diagnose. However, certainly, it would mean that the LCB idea is only something you would need if you were writing a full IDE - as the problems the IDE has only really come about because arbitrary script runs within it which it can't control; in particular, locking messages around changes to stack names, control ids, or control ownership. Warmest Regards, Mark. -- Mark Waddingham ~ m...@livecode.com ~ http://www.livecode.com/ LiveCode: Everyone can create apps ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Speed of control lookup (Was Re: Parent of Target)
> On 12 Aug 2017, at 8:11 am, Mark Wieder via use-livecode > wrote: > >> Hmm… Would it be a good idea to create a new ID form with the bare minimum >> to identify an object. > > > UUID > Let’s not start that again ;-) ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Speed of control lookup (Was Re: Parent of Target)
On 08/11/2017 02:58 PM, Monte Goulding via use-livecode wrote: Hmm… Would it be a good idea to create a new ID form with the bare minimum to identify an object. UUID -- Mark Wieder ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Speed of control lookup (Was Re: Parent of Target)
> On 12 Aug 2017, at 1:23 am, Mark Waddingham via use-livecode > wrote: > > It has also suggested (to me, at least) a slightly different approach - we > make the return value of the 'long id' property of objects what you might > call a StringyLongId value. Instead of returning a string: > > button id 1003 of group id 1004 of card id 1002 of stack "MyStackName" > > It would be a value which acts like a string, but internally stores: > >[ BUTTON, 1003, [ 1004 ], 1002, "MyStackName" ] Hmm… Would it be a good idea to create a new ID form with the bare minimum to identify an object. Say: id of card id of stack “” Although I guess unplaced groups would need just id of stack “” That would mean speed improvements could be done on an object reference that is relatively robust to changes in the object tree and unless you are creating an IDE you would be very unlikely to need to do the LCB object reference repository thing. Cheers Monte ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Fwd: Speed of control lookup (Was Re: Parent of Target)
On 2017-08-11 14:57, Mark Waddingham via use-livecode wrote: The question of course is 'how fast could we get long id parsing to be' (as that is the bottleneck here, or at least appears to be). Okay so I got stuck on what I am *meant* to be doing, so spent a little time trying to answer this question. The results are quite encouraging... So, my idea was this - long ids which the engine generates have a *very* strict structure - so write a very fast parser for them which fails as soon as it encounters anything it doesn't expect. If this happens you just use the existing (relatively slow) method which handles all the edge cases. It turns out you can hand-craft a parser for 'the long id' in about 150 lines of C (char-bashing, one might call it, as opposed to bit-bashing) and assuming you restrict yourself to only looking up things on the current card of the target stack, and don't check group ownership (oops!) you end up with something which can resolve a long id in about the same time as you could if you hand-coded the syntax. i.e. put "button id 1003 of group id 1004 of card id 1002 of stack " & quote & "MyStackName" & quote into tRuggedId get the id of tRuggedId -- has about the same speed (assuming all those objects are in the cache) as put the id of button id 1003 of group id 1004 of card id 1002 of stack "MyStackName" Now, I do wonder if the long id parsing method we currently have is actually using the stack-id cache everywhere it could (this code is somewhat old and knotty - so it is quite hard to see) - so I'm not sure quite how fair the above comparison is with current long id parsing (were the latter as optimal as it potentially could be) but there is obviously quite a significant overhead in the way chunks are parsed from strings (which I kind of already knew - but perhaps not just *how much*!). Anyway, it is quite pleasing to know that we perhaps don't need the complexity of 'caching an object-handle along side a string from which a long id has been parsed' (where getting the cache validation right is going to be hard to do performantly enough) as we can probably make parsing of long ids (or variants of) themselves so quick, that the time taken to do so is thoroughly lost in the actual operation they are being used for. This was just an 'experiment', so I can't really say when this change might (if ever) appear - however, it certainly suggests a slightly less fiddly approach than the caching method. It has also suggested (to me, at least) a slightly different approach - we make the return value of the 'long id' property of objects what you might call a StringyLongId value. Instead of returning a string: button id 1003 of group id 1004 of card id 1002 of stack "MyStackName" It would be a value which acts like a string, but internally stores: [ BUTTON, 1003, [ 1004 ], 1002, "MyStackName" ] i.e. A list of component parts - [ main chunk, main chunk id, [ group id, ... ], card id, stack name/filename ] This has the advantage that you use up a great deal less memory for long ids of very frequently referenced objects (filenames / names can be quite long!). They can be resolved quickly assuming the stack-id cache (and if we add a name / filename cache for top-level stacks); compared more quickly; and still be rendered as a string when doing stringy things to them (it would also be possible to optimize the 'word' chunk for them). This has the *distinct* advantage of not needing to be validated (long ids change as objects move around in the hierarchy or id / names change ] before use. Of course, this actually requires a bit of machinery we don't actually have (but could be used for other things) - the ability for a value (internally) to be able to act like a string, but not actually be a string. On balance the optimized long id chunk parser is probably less work (as it only needs a bit of code in *one* place - in the chunk evaluator); and probably less prone to causing regressions - especially if we only used the optimized code path in cases where we were sure there weren't any 'difficult' edge-cases to deal with. I suppose I should now get back to what I was meant to be doing... Warmest Regards, Mark. -- Mark Waddingham ~ m...@livecode.com ~ http://www.livecode.com/ LiveCode: Everyone can create apps ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Fwd: Speed of control lookup (Was Re: Parent of Target)
On 2017-08-11 11:12, Mark Waddingham via use-livecode wrote: On 2017-08-10 21:10, Richard Gaskin via use-livecode wrote: How might I measure the benefits of long ID caching? Here is perhaps a better set of simple benchmarks to compare approaches to lookup (related to ids, anyway): on mouseUp local tIterations put 10 into tIterations -- card id is 1002 -- button id is 1003 -- group id is 1004 local tLongId put the long id of button id 1003 of group id 1004 of card id 1002 into tLongId local tButtonIdOfStack put "button id 1003 of stack" && quote & "LongIdSpeedTest" & quote into tButtonIdOfStack local tButtonIdOfCardIdOfStack put "button id 1003 of card id 1002 of stack" && quote & "LongIdSpeedTest" & quote into tButtonIdOfCardIdOfStack local tTime put the millisecs into tTime repeat tIterations times get the id of me end repeat put "Control" && (the millisecs - tTime) & return into msg put the millisecs into tTime repeat tIterations times get the id of tLongId end repeat put "GetIdOfLongIdInString" && (the millisecs - tTime) & return after msg put the millisecs into tTime repeat tIterations times get the id of tButtonIdOfCardIdOfStack end repeat put "GetIdOfButtonIdOfCardIdOfStackInString" && (the millisecs - tTime) & return after msg put the millisecs into tTime repeat tIterations times get the id of tButtonIdOfStack end repeat put "GetIdOfButtonIdOfStackInString" && (the millisecs - tTime) & return after msg put the millisecs into tTime repeat tIterations times get the id of button id 1003 of group id 1004 of card id 1002 of stack "LongIdSpeedTest" end repeat put "GetIdOfButtonIdOfGroupIdOfCardIdOfStack" && (the millisecs - tTime) & return after msg put the millisecs into tTime repeat tIterations times get the id of button id 1003 of card id 1002 of stack "LongIdSpeedTest" end repeat put "GetIdOfButtonIdOfCardIdOfStack" && (the millisecs - tTime) & return after msg local tStackString put "LongIdSpeed" & "Test" into tStackString put the millisecs into tTime repeat tIterations times get the id of button id 1003 of group id 1004 of card id 1002 of stack tStackString end repeat put "GetIdOfButtonIdOfGroupIdOfStackNotName" && (the millisecs - tTime) & return after msg put the millisecs into tTime repeat tIterations times get the id of button id 1003 of card id 1002 of stack tStackString end repeat put "GetIdOfButtonIdOfCardIdOfStackNotName" && (the millisecs - tTime) & return after msg end mouseUp On my machine (in 8.1.5) I get: Control 21 GetIdOfLongIdInString 714 GetIdOfButtonIdOfCardIdOfStackInString 497 GetIdOfButtonIdOfStackInString 320 GetIdOfButtonIdOfGroupIdOfCardIdOfStack 56 GetIdOfButtonIdOfCardIdOfStack 53 GetIdOfButtonIdOfGroupIdOfStackNotName 65 GetIdOfButtonIdOfCardIdOfStackNotName 63 So, currently, there is a significant overhead to getting a control reference out of a string - the minimum you actually need in a string to uniquely identify a control (which may or may not have per-card data) is "control id ... of card id ... of stack ...". Indeed - using the minimal info you need hard-coded in syntax: get the id of button id 1003 of card id 1002 of stack tStackString Is about 10 times faster than using a long id in a string and about 8 times faster than using a modified form of a string id to cut out the (strictly) unnecessary bits: get the id of "button id 1003 of card id 1002 of stack LongIdSpeedTest" -- quoted name, appropriately So, my advice changes *slightly* - if you are doing tight loops which need to manipulate lots of controls in the current card of the defaultStack use: control id If the things aren't on the current card of the default stack, then extract the card id and stack name outside of the loop and use: control id of card id tCardId of stack tStackName The question of course is 'how fast could we get long id parsing to be' (as that is the bottleneck here, or at least appears to be). Warmest Regards, Mark. P.S. Due to a mailing server glitch any mails which were sent here between 12:30BST and 14:00BST will not have got through. -- Mark Waddingham ~ m...@livecode.com ~ http://www.livecode.com/ LiveCode: Everyone can create apps ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 2017-08-10 21:10, Richard Gaskin via use-livecode wrote: How might I measure the benefits of long ID caching? It isn't long ids which are cached - it is ids. I made a few adjustments, tweaked a few things to remove some overheads which aren't relevant here: private function MarkObjRef1 pCount repeat with x = 1 to pCount get the long id of button x of group 1 of card 1 of this stack end repeat end MarkObjRef1 private function MarkObjRef2 pCount put the long id of group 1 of card 1 of this stack into tGrpObj repeat with x = 1 to pCount get the long id of button x of tGrpObj end repeat end MarkObjRef2 private function MarkObjRef3 pCount repeat with x = 1 to pCount get the long id of sObjRefsA[x] end repeat end MarkObjRef3 private function MarkObjRef4 pCount repeat with x = 1 to pCount get the long id of button id word 3 of sObjRefsA[x] of this stack end repeat end MarkObjRef4 I get these results for (100 iterations with) 1000 groups: 0.000801 - Method 1 - full expression by number 0.001399 - Method 2 - mixed expression 0.001786 - Method 3 - long ID only 0.000665 - Method 4 - ID only 0.05 - Control 0.000796 - Method 1 wo Control - full expression by number 0.001394 - Method 2 wo Control - mixed expression 0.001781 - Method 3 wo Control - long ID only 0.00066 - Method 4 wo Control- ID only And these results for (10 interations with) 1 groups: 0.05243 - Method 1 - full expression by number 0.05965 - Method 2 - mixed expression 0.0498 - Method 3 - long ID only 0.00697 - Method 4 - ID only 0.6 - Control 0.05237 - Method 1 wo Control - full expression by number 0.05959 - Method 2 wo Control - mixed expression 0.04974 - Method 3 wo Control - long ID only 0.00691 - Method 4 wo Control - ID only Here you can see that: Method 1 takes 65 times as long, even though the number of groups has only increased 10 times Method 2 takes 42 times as long, even though the number of groups has only increased 10 times Method 3 takes 30 times as long, even though the number of groups has only increased 10 times Method 4 takes 10 times as long - the same factor as the increase in number of groups. Here Method 4 is the only one truly exploiting the id cache to maximum effect - Methods 2 and 3 both have a stack lookup too - which is *not* currently cached. The modified code is below. Warmest Regards, Mark. = local sObjRefsA on mouseUp put 10 into n put (the number of btns of grp 1) * n into tIterations put 1 into tCount -- put the millisecs into t repeat n put MarkObjRef1(tCount) into r1 end repeat put the millisecs - t into t1 -- put the millisecs into t repeat n put MarkObjRef2(tCount) into r2 end repeat put the millisecs - t into t2 -- -- Last test requires that we first obtain the object refs to -- measure the benefits of long ID caching: repeat with i = 1 to the number of btns of grp 1 put the long id of btn i of grp 1 into sObjRefsA[i] end repeat -- put the millisecs into t repeat n put MarkObjRef3(tCount) into r3 end repeat put the millisecs - t into t3 -- put the millisecs into t repeat n put MarkObjRef4(tCount) into r4 end repeat put the millisecs - t into t4 put the millisecs into t repeat n put MarkObjRefControl(tCount) into r5 end repeat put the millisecs - t into t5 put the millisecs into t repeat n put MarkObjRefControlStackLookup(tCount) into r6 end repeat put the millisecs - t into t6 put t1/tIterations &" - Method 1 - full expression by number " &cr \ & t2/tIterations &" - Method 2 - mixed expression" &cr \ & t3/tIterations &" - Method 3 - long ID only" &cr \ & t4/tIterations &" - Method 4 - ID only" &cr \ & t5/tIterations &" - Control" & cr\ & t6/tIterations & " - Control Stack Lookup" & cr put (t1 - t5)/tIterations &" - Method 1 - full expression by number " &cr \ & (t2 - t5)/tIterations &" - Method 2 - mixed expression" &cr \ & (t3 - t5)/tIterations &" - Method 3 - long ID only" &cr \ & (t4 - t5)/tIterations &" - Method 4 - ID only" after msg end mouseUp private function MarkObjRef1 pCount repeat with x = 1 to pCount get the long id of button x of group 1 of card 1 of this stack end repeat end MarkObjRef1 private function MarkObjRef2 pCount put the long id of group 1 of card 1 of this stack into tGrpObj repeat with x = 1 to pCount get the long id of button x of tGrpObj end repeat end MarkObjRef2 private function MarkObjRef3 pCount repeat with x = 1 to pCount get the long id of sObjRefsA[x] end repeat end MarkObjRef3 private function MarkObjRef4 pCount repeat with x = 1 to pCount get the long id of button id (word 3 of sObjRefsA[x]) of this stack end repeat end MarkObjR
Re: Parent of Target
On 10/08/2017 18:44, Richard Gaskin via use-livecode wrote: Mark Wieder wrote: I do use getter and setter routines regularly. I think your function is useful, but won't by itself get at the question of "who changed that?", and for that question there are at least two possible methods: method 1: local sCurrentFlavorA command setCurrentFruitFlavorTo pFlavor put pFlavor into sCurrentFlavor["fruit"] end setCurrentFruitFlavorTo setCurrentFruitFlavorTo "orange" With rare exceptions I use Method 1 almost exclusively. I do a variant of this local sCurrentFlavorA, sCurrentFlavorSetterA command setCurrentFruitFlavorTo pFlavor put pFlavor into sCurrentFlavorA["fruit"] put the executioncontexts into sCurrentFlavorSetterA["fruit"] end setCurrentFruitFlavorTo (usually only if in 'development' mode) Alex ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
Ali Lloyd wrote: > Richard wrote >> Jacque recently showed me the speed difference between explicitly >> writing out the element of an object reference: >> >>get the width of btn 1 of cd 2 of stack "MyStack" >> >> ...vs other forms like long IDs: >> >>put the long is of btn 1 of cd 2 of stack "MyStack" into t5Obj >>get teh width of tObj >> >> The latter is much slower, yet long IDs are so good to work with. > > The only reason this is true is that in the second case you are > resolving the object twice. Indeed - a very poor example on my part. Also "teh" is not a recognized token. :) > It is not true in general - the second time the long id is used it > will use the id cache which is constant time, whereas "button n" > is O(n). Try benchmarking repeated use of the stored long id vs the > number version, especially if the numbers are large. > > So it's horses for courses. If it's a one-shot object access then the > number form is faster. For repeated use, get the long id. Sounds good, but the benefits of long ID caching have been difficult for me to measure. I was exploring this a while back in response to this forum thread: http://forums.livecode.com/viewtopic.php?f=7&t=29555 Of course object ref performance matters most when you need to traverse a lot of objects or refer to objects frequently, so my test attempts to do both: I made a simple stack with one button containing the script below, and one group containing 100 buttons. The script uses three different methods to obtain a property value from every object in the group, through 100 iterations, for a total of 10,000 accesses with each method. When I'd posted earlier the property being obtained was the short ID, which seems a reasonable reflection of time needed to obtain an arbitrary property value. After reading your post I changed that to long ID, but see little difference in relative performance. How might I measure the benefits of long ID caching? --=-- local sObjRefsA on mouseUp put 100 into n put (the number of btns of grp 1) * n into tIterations -- put the millisecs into t repeat n put ObjRef1() into r1 end repeat put the millisecs - t into t1 -- put the millisecs into t repeat n put ObjRef2() into r2 end repeat put the millisecs - t into t2 -- -- Last test requires that we first obtain the object refs to -- measure the benefits of long ID caching: repeat with i = 1 to the number of btns of grp 1 put the long id of btn i of grp 1 into sObjRefsA[i] end repeat -- put the millisecs into t repeat n put ObjRef3() into r3 end repeat put the millisecs - t into t3 set the numberformat to "0." put t1/tIterations &" - Method 1 - full expression by number " &cr \ & t2/tIterations &" - Method 2 - mixed expression" &cr \ & t3/tIterations &" - Method 3 - long ID only" &cr \ & (r1 = r3) end mouseUp -- Ordinal references all the way down: function ObjRef1 put the number of btns of grp 1 into tNumBtns repeat with x = 1 to tNumBtns put the long id of btn x of grp 1 of cd 1 of stack \ "objref test" &cr after s end repeat return s end ObjRef1 -- Mix of ordinal button with group long ID: function ObjRef2 put the long id of grp 1 into tGrpObj put the number of btns of tGrpObj into tNumBtns repeat with x = 1 to tNumBtns put the long id of btn x of tGrpObj &cr after s end repeat return s end ObjRef2 -- Long ID: function ObjRef3 put the number of btns of grp 1 into tNumBtns repeat with x = 1 to tNumBtns put the long id of sObjRefsA[x] &cr after s end repeat return s end ObjRef3 -- Richard Gaskin Fourth World Systems Software Design and Development for the Desktop, Mobile, and the Web ambassa...@fourthworld.comhttp://www.FourthWorld.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
Mark Wieder wrote: I do use getter and setter routines regularly. I think your function is useful, but won't by itself get at the question of "who changed that?", and for that question there are at least two possible methods: method 1: local sCurrentFlavorA command setCurrentFruitFlavorTo pFlavor put pFlavor into sCurrentFlavor["fruit"] end setCurrentFruitFlavorTo setCurrentFruitFlavorTo "orange" method 2: setProp CurrentFruitFlavor pFlavor put pFlavor into sCurrentFlavor["fruit"] end CurrentFruitFlavor getProp CurrentFruitFlavor return sCurrentFlavor["fruit"] end CurrentFruitFlavor set the CurrentFruitFlavor of me to "orange" get the CurrentFruitFlavor of me With rare exceptions I use Method 1 almost exclusively. Method 2 feel more natural in many respects, but suffers from one drawback critical in some cases: when lockMessages is true getProp and setProp won't fire. Custom handlers will always fire regardless of the current state of message locking. This has been discussed before, and IIRC Mark Waddingham expressed an interest in perhaps reclassifying getProp and setProp from system messages to custom messages, so they would become as immune to locking as other custom handlers. But despite the good intention, it seems the work involved would have murky non-trivial implications. So for the sake of robustness (and sanity during debugging when things go mysteriously wrong), as much as I would prefer to use property syntax for things that behave like properties, I don't. -- Richard Gaskin Fourth World Systems Software Design and Development for the Desktop, Mobile, and the Web ambassa...@fourthworld.comhttp://www.FourthWorld.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
Remember that arrays stored as properties provides a kind of scoping. For example 2 stacks can hold the same array but with different values in a property with the same name. The added advantage is they are persistent through idle and you can now check the contents of the properties by drilling down in the property inspector to the value you want to check to see what it contains. Properties work great as a kind of scoped global. Bob S > On Aug 9, 2017, at 18:24 , Sannyasin Brahmanathaswami via use-livecode > wrote: > > Addendum on Scoping > > This new "modular" world, of behaviors, libs that have been put into msg path > with "start Using" or "insert into back".. text files, multiple > binary.livecode stacks -- not substacks as such, but separate.livecode files. > The app is now a complete "environment/framework". With Andre constant > warnings along with my experience using globals in this environment gets very > dangerous very fast, typically want to use an array to starts holding all > kind of things we think we need to reference across many different > stacks/libs. Seems OK on the surface, but then as Andre says, if > someGlobalArray["fruit"] = "apple" when you thought for sure it should now > be "orange" then then debugging "hell" door opens. So instead we start > sending and dispatching commands, setting up locals in scripts with lots of > small > > local sCurrentFlavorA > > function returnCurrentFlavor > put sCurrentFlavorA["fruit"] > end returnCurrentFlavor > > So now, with debug on you can trace easily where things are happening. so > some way to track, not only "where did this come from" (which is what debug > stepping is really doing) but to look "up" "Who is asking?" > would be interesting. ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 2017-08-09 05:39, Sannyasin Brahmanathaswami via use-livecode wrote: The more we separate our code/libraries/behaviors from the binary UI, the more I find myself trying to dispatch call backs or other messages back to the group/card/stack that has a behavior and not the individual control: widget/button/field on the card itself, whose job was simply to intercept a mouse event and server as the target in higher switch. So you need to get the long ID I'm not sure I follow the underlying reasoning here - why not just use 'the long id of the target'?* The message path means that the message will hit the group/card/stack if not handled in the control (which it won't be, from what you are saying). Warmest Regards, Mark. * This is the model used in the engine (e.g. for sockets), and in LCB widgets (which post a message to the script of the widget, which then filters down the message path in the usual way). -- Mark Waddingham ~ m...@livecode.com ~ http://www.livecode.com/ LiveCode: Everyone can create apps ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 2017-08-10 09:32, Ali Lloyd via use-livecode wrote: Jacque recently showed me the speed difference between explicitly writing out the element of an object reference: get the width of btn 1 of cd 2 of stack "MyStack" ...vs other forms like long IDs: put the long is of btn 1 of cd 2 of stack "MyStack" into t5Obj get teh width of tObj The latter is much slower, yet long IDs are so good to work with. The only reason this is true is that in the second case you are resolving the object twice. It is not true in general - the second time the long id is used it will use the id cache which is constant time, whereas "button n" is O(n). Try benchmarking repeated use of the stored long id vs the number version, especially if the numbers are large. So it's horses for courses. If it's a one-shot object access then the number form is faster. For repeated use, get the long id. Just to expand on what Ali said... There is an overhead in parsing a long id string - however, that is proportional to the length of the id string which are generally quite short. Also, this is purely 'parsing' it is basically munching chars and branching which means the 'step' taken at each char is very very very fast. Certainly something which is overwhelmed by whatever operation you might be doing with the resolved chunk. What takes up the time in resolving object references is finding the objects at each step. If you use the indexed form - e.g. btn 3 - then the time taken is proportional to the magnitude of the index as the engine has to step through a list to find the object. If you use the id form, however, then the lookups are cached at the stack level after the first time they are resolved. The id of an object is unique within the confines of a stack, and every stack has a hash-table which caches id->objectptrs internally. If you are doing custom control type work (which is where you tend to have to manage lots of child control references), then I'd generally suggest not using long ids, but instead just store the id property of the child object and use explicit syntax: control id ... of me -- here I'm assuming that 'me' is a group ;) The reason is that this is (after the first lookup for any given id/me pair) a completely constant time lookup: - 'me' is stored internally as a direct pointer - id's can be looked up in the stack hash table. Warmest Regards, Mark. -- Mark Waddingham ~ m...@livecode.com ~ http://www.livecode.com/ LiveCode: Everyone can create apps ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 2017-08-10 01:47, Monte Goulding via use-livecode wrote: Thinking about this some more I wonder if a stringified representation and string representation type could be paired with the object reference so that if you got say the abbreviated id then that would be the stringified representation and if the object is deleted then the stringified representation is used from then on until it is re-resolved (say the stack is reloaded). Then if it is re-stringified then the new representation stored. The only issue here would be any code that relied on the string not changing when you rename etc an object etc but I’m not sure how common that would be. That and there could be quirks like if you get the reference, rename it and then delete it the string representation would probably still be the original name. The general idea though is it would be something like a string is now in the engine. We don’t need to know if under the hood it is currently an 8 bit native string or a 16 bit unicode string. This sounds very much like the idea proposed here - http://forums.livecode.com/viewtopic.php?f=66&t=15017 - as a reason for why UUIDs were not necessarily the 'right' approach (and never will be, IMHO) ;) This is something which could be done (with the new architecture in 7+, indeed the potential for it was one of the many many reasons that motivated the refactor) - however, in reality, we risk changing the language quite fundamentally. Something which I became acutely aware of during the refactoring process (partly through direct conversation with a variety of long-term xTalkers - trying to explain what could become possible with it). If we are going to break the everything-but-arrays are strings semantic then let's do it (1) completely and (2) in a way which ensures we 'bring everyone with us' (how many VB users didn't move to VB.NET?). [ The latter point is the most important one, btw ]. 'Creeping' language changes just don't work - particularly at the core semantic (types, in this case) level - you risk ending up with something which may be much more powerful but also much less accessible/easy/familiar/... ] Indeed, this realisation of the crucial 'semantic gap'* LiveCode Script has (which is true of 4GLs *in general*) was one of the motivations for Builder**. Builder already has the 'object handle' (ScriptObject) idea - so we can use that to build a library which manages the object references the IDE holds at any one time. This solves the robustness problem we face in the IDE and in a way which doesn't require a single change to LCS. (Over time it could also solve the speed issue too - we implement the parts which are bottle-necked by ScriptObject<->StringId conversions in LCB so they aren't necessary). [ Robustness is far more important than speed here, though ]. In terms of user-code, then yes, there are also user apps which require this - so we can just make the functionality a user available library extension when it is mature enough. Users can then evaluate whether it is 'worth' the extra cognitive cost of using such a thing for their situation on a per-project basis (just like the IDE - being a LiveCode Script project itself). Warmest Regards, Mark. * I should stress that what I call a 'semantic gap' does not in any way make LCS a 'lesser' language - because it really is not. xTalks have evolved with a different focus from many other languages and fill that very well, that's all. They make the tasks it is focused on easier, at the expense of making some other things harder (but only slightly - you still have the 'ease' of the language as a whole to couch them in). ** I do see a future where there are not two languages - 'Script' and 'Builder' - but only 'LiveCode'. However, that 'unification' has to be done in a way which does not, in any way, detract from what makes LiveCode Script what it is (which sounds subjective, but the recent study released about 'cognitive load' does perhaps suggest a means of measurement - which starts to make it objective). -- Mark Waddingham ~ m...@livecode.com ~ http://www.livecode.com/ LiveCode: Everyone can create apps ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
> > Jacque recently showed me the speed difference between explicitly > writing out the element of an object reference: > >get the width of btn 1 of cd 2 of stack "MyStack" > > ...vs other forms like long IDs: > >put the long is of btn 1 of cd 2 of stack "MyStack" into t5Obj >get teh width of tObj > > The latter is much slower, yet long IDs are so good to work with. > The only reason this is true is that in the second case you are resolving the object twice. It is not true in general - the second time the long id is used it will use the id cache which is constant time, whereas "button n" is O(n). Try benchmarking repeated use of the stored long id vs the number version, especially if the numbers are large. So it's horses for courses. If it's a one-shot object access then the number form is faster. For repeated use, get the long id. > > ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 8/9/17 8:24 PM, Sannyasin Brahmanathaswami via use-livecode wrote: the behavior is attached to a stack that is not the same stack as the target (a download button) so "this me" won't work I think it should... Object with an assigned behavior: "me" Object that contains the behavior script: "this me" If the backscript stack holds the behavior script then the stack itself should be "this me". The target (the download button) which has the behavior assigned would be "me". Logically, anyway. So instead we start sending and dispatching commands If the script is in the message hierarchy, I wouldn't think you'd need to send or dispatch anything, just issue the command normally. You can debug that pretty easily and there's one less level of abstraction. -- Jacqueline Landman Gay | jac...@hyperactivesw.com HyperActive Software | http://www.hyperactivesw.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 08/09/2017 06:24 PM, Sannyasin Brahmanathaswami via use-livecode wrote: local sCurrentFlavorA function returnCurrentFlavor put sCurrentFlavorA["fruit"] end returnCurrentFlavor So now, with debug on you can trace easily where things are happening. so some way to track, not only "where did this come from" (which is what debug stepping is really doing) but to look "up" "Who is asking?" would be interesting. I do use getter and setter routines regularly. I think your function is useful, but won't by itself get at the question of "who changed that?", and for that question there are at least two possible methods: method 1: local sCurrentFlavorA command setCurrentFruitFlavorTo pFlavor put pFlavor into sCurrentFlavor["fruit"] end setCurrentFruitFlavorTo setCurrentFruitFlavorTo "orange" method 2: setProp CurrentFruitFlavor pFlavor put pFlavor into sCurrentFlavor["fruit"] end CurrentFruitFlavor getProp CurrentFruitFlavor return sCurrentFlavor["fruit"] end CurrentFruitFlavor set the CurrentFruitFlavor of me to "orange" get the CurrentFruitFlavor of me By placing breakpoints into either of these methods you can track what sets the values in the debugger, or by placing logging statements into either you can display the stack traces as they fly by: put pFlavor into sCurrentFlavor["fruit"] put the executionContexts & cr after msg -- Mark Wieder ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
@ Jacque the behavior is attached to a stack that is not the same stack as the target (a download button) so "this me" won't work @ Bob " getParentStack(the long id of me). All it does is parses the long id by using wordOffset to find the word "stack" then returns word tWord to -1 of the long id. Pretty basic." Awesome: this has been added to the main backscript utilities section… Nandri! (thank you) @ Monte & Richard " Monte Goulding wrote: > I have actually thought about whether it would be reasonable for `the > long id` to return such an object reference as it would stringify > automagically if necessaryI think complex objects that handle many > object references and the IDE would have a significant bump in speed > if we did such a thing. Oh yes please! +1! Addendum on Scoping This new "modular" world, of behaviors, libs that have been put into msg path with "start Using" or "insert into back".. text files, multiple binary.livecode stacks -- not substacks as such, but separate.livecode files. The app is now a complete "environment/framework". With Andre constant warnings along with my experience using globals in this environment gets very dangerous very fast, typically want to use an array to starts holding all kind of things we think we need to reference across many different stacks/libs. Seems OK on the surface, but then as Andre says, if someGlobalArray["fruit"] = "apple" when you thought for sure it should now be "orange" then then debugging "hell" door opens. So instead we start sending and dispatching commands, setting up locals in scripts with lots of small local sCurrentFlavorA function returnCurrentFlavor put sCurrentFlavorA["fruit"] end returnCurrentFlavor So now, with debug on you can trace easily where things are happening. so some way to track, not only "where did this come from" (which is what debug stepping is really doing) but to look "up" "Who is asking?" would be interesting. Somehow I think this relates to another Idea I keep having: which is place group [custom control] "downloading" of stack "customControlsLibrary onto this card Where: a) group "downloading" has progressField, progressTitle, progressBar (ala the lesson on line for load URL which I just copied to the SivaSiva app and modified yesterday) i.e. a customcontrol b) that group has a behavior c) that it can be made to magically appear and disappear "anywhere at any time" d) such that one update updates all future instances. OK well now we can do that by copying the group dynamically and since after the standalone is built, that group is never saved.. "kinda" works, but in dev I keep getting multiple copies of this group in different stacks… i.e we already have this with icons for buttons… you can have a single image + ID for a button that appears on multiple stacks.. change the image and all buttons change. So why not a phantom group whose "real" presence is a single instance in another stack. Perhaps this has nothing to do with the parent of target; but seems all vaguely related. [/end of babbling about what I do not really understand very well] On 8/9/17, 6:25 AM, "use-livecode on behalf of Bob Sneidar via use-livecode" wrote: getParentStack(the long id of me). All it does is parses the long id by using wordOffset to find the word "stack" then returns word tWord to -1 of the long id. Pretty basic. ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
> On 10 Aug 2017, at 6:48 am, Monte Goulding via use-livecode > wrote: > > I have actually thought about whether it would be reasonable for `the long > id` to return such an object reference as it would stringify automagically if > necessary. However, deleting the object would mean the string form couldn’t > be created so that probably wouldn’t work... I think complex objects that > handle many object references and the IDE would have a significant bump in > speed if we did such a thing. Thinking about this some more I wonder if a stringified representation and string representation type could be paired with the object reference so that if you got say the abbreviated id then that would be the stringified representation and if the object is deleted then the stringified representation is used from then on until it is re-resolved (say the stack is reloaded). Then if it is re-stringified then the new representation stored. The only issue here would be any code that relied on the string not changing when you rename etc an object etc but I’m not sure how common that would be. That and there could be quirks like if you get the reference, rename it and then delete it the string representation would probably still be the original name. The general idea though is it would be something like a string is now in the engine. We don’t need to know if under the hood it is currently an 8 bit native string or a 16 bit unicode string. If we could work out all the little niggles in the idea then it could be that we wouldn’t need to change our code at all (other than to remove all the code which tries to handle name and id changes) which would be nice. Also things like `the target` and `the owner` could seamlessly upgrade to being references. Cheers Monte ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
Pretty funny... reading the conversation and I immediately thought "pointer". > > On Aug 9, 2017 at 4:17 PM, (mailto:use-livecode@lists.runrev.com)> wrote: > > > > On 08/09/2017 01:48 PM, Monte Goulding via use-livecode wrote: > One day I > dream of an object reference that we can get and use that is not a string > that needs to be resolved every time it’s used but a direct reference to the > object. Perhaps if someone tries to do a string operation on it then it would > be turned into a long id string just like when someone tries to do “1” + 1 > it’s turned into a number. But if it’s just passed around or stored in a > custom property then it remains a resolved handle to the object and can cope > with things like the ID or name or filename being changed in the session. If > we had that we would want things like `is a {stack | card | button …}` and > `{stack | card | mainstack} of`. ...and then... we could name them 'pointers' > and 'handles' and I'd be very happy. -- Mark Wieder ahsoftw...@gmail.com > ___ use-livecode mailing list > use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe > and manage your subscription preferences: > http://lists.runrev.com/mailman/listinfo/use-livecode > > ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
> On 10 Aug 2017, at 7:17 am, Mark Wieder via use-livecode > wrote: > > ...and then... > we could name them 'pointers' and 'handles' and I'd be very happy. > Ha… one of the reasons I thought about overloading long ID is because pointer and handle aren’t very LiveCode… Maybe reference: get the reference of Using such a reference to a deleted object would need to throw an error I think. People would need to understand that you couldn’t use such references in delimited lists. So if you wanted a list of object references you would need to use an array. FWIW the ScriptObject in LCB is basically what I’m talking about but as a regular script value type. Cheers Monte ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
On 08/09/2017 01:48 PM, Monte Goulding via use-livecode wrote: One day I dream of an object reference that we can get and use that is not a string that needs to be resolved every time it’s used but a direct reference to the object. Perhaps if someone tries to do a string operation on it then it would be turned into a long id string just like when someone tries to do “1” + 1 it’s turned into a number. But if it’s just passed around or stored in a custom property then it remains a resolved handle to the object and can cope with things like the ID or name or filename being changed in the session. If we had that we would want things like `is a {stack | card | button …}` and `{stack | card | mainstack} of`. ...and then... we could name them 'pointers' and 'handles' and I'd be very happy. -- Mark Wieder ahsoftw...@gmail.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
Monte Goulding wrote: > I have actually thought about whether it would be reasonable for `the > long id` to return such an object reference as it would stringify > automagically if necessaryI think complex objects that handle many > object references and the IDE would have a significant bump in speed > if we did such a thing. Oh yes please! Jacque recently showed me the speed difference between explicitly writing out the element of an object reference: get the width of btn 1 of cd 2 of stack "MyStack" ...vs other forms like long IDs: put the long is of btn 1 of cd 2 of stack "MyStack" into t5Obj get teh width of tObj The latter is much slower, yet long IDs are so good to work with. Anything that can be done to speed up object references would be great. I'd never before seen the impact until last week's testing, but once I did I'm now tempted to write tediously long code for those cases where a lot of objects need to be addressed. Your proposal makes all that go away, and fast that any form we have now. -- Richard Gaskin Fourth World Systems Software Design and Development for the Desktop, Mobile, and the Web ambassa...@fourthworld.comhttp://www.FourthWorld.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
> On 10 Aug 2017, at 2:25 am, Bob Sneidar via use-livecode > wrote: > > I have a function that returns the stack of an object by passing the long id > of the object. getParentStack(the long id of me). All it does is parses the > long id by using wordOffset to find the word "stack" then returns word tWord > to -1 of the long id. Pretty basic. > > That method can be used for anything, from the owner to the card to the first > group etc. I don't think we need more properties per se. Yes we have these kinds of functions in the ide too. I just think we shouldn’t need something that depends on the format of a long ID to do something so common as to get a reference to the card of a control or stack of anything. One day I dream of an object reference that we can get and use that is not a string that needs to be resolved every time it’s used but a direct reference to the object. Perhaps if someone tries to do a string operation on it then it would be turned into a long id string just like when someone tries to do “1” + 1 it’s turned into a number. But if it’s just passed around or stored in a custom property then it remains a resolved handle to the object and can cope with things like the ID or name or filename being changed in the session. If we had that we would want things like `is a {stack | card | button …}` and `{stack | card | mainstack} of`. I have actually thought about whether it would be reasonable for `the long id` to return such an object reference as it would stringify automagically if necessary. However, deleting the object would mean the string form couldn’t be created so that probably wouldn’t work... I think complex objects that handle many object references and the IDE would have a significant bump in speed if we did such a thing. Cheers Monte ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
I have a function that returns the stack of an object by passing the long id of the object. getParentStack(the long id of me). All it does is parses the long id by using wordOffset to find the word "stack" then returns word tWord to -1 of the long id. Pretty basic. That method can be used for anything, from the owner to the card to the first group etc. I don't think we need more properties per se. Bob S > On Aug 8, 2017, at 20:43 , Monte Goulding via use-livecode > wrote: > > >> On 9 Aug 2017, at 1:39 pm, Sannyasin Brahmanathaswami via use-livecode >> wrote: >> >> is there a better way? > > Perhaps you want this? > > the long owner of the target > > or > > the long owner of me > > Of course things get a bit more complicated if you want the card of or the > stack of the object… we really should put some read only properties in for > those... > > Cheers > > Monte > ___ > use-livecode mailing list > use-livecode@lists.runrev.com > Please visit this url to subscribe, unsubscribe and manage your subscription > preferences: > http://lists.runrev.com/mailman/listinfo/use-livecode ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
I'm not sure I follow all your explanation but you can refer to the object that holds the behavior script as "this me". I still get a kick out of that but it's quite appropriate. On August 8, 2017 10:41:46 PM Sannyasin Brahmanathaswami via use-livecode wrote: The more we separate our code/libraries/behaviors from the binary UI, the more I find myself trying to dispatch call backs or other messages back to the group/card/stack that has a behavior and not the individual control: widget/button/field on the card itself, whose job was simply to intercept a mouse event and server as the target in higher switch. So you need to get the long ID -- Jacqueline Landman Gay | jac...@hyperactivesw.com HyperActive Software | http://www.hyperactivesw.com ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Parent of Target
> On 9 Aug 2017, at 1:39 pm, Sannyasin Brahmanathaswami via use-livecode > wrote: > > is there a better way? Perhaps you want this? the long owner of the target or the long owner of me Of course things get a bit more complicated if you want the card of or the stack of the object… we really should put some read only properties in for those... Cheers Monte ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Parent of Target
The more we separate our code/libraries/behaviors from the binary UI, the more I find myself trying to dispatch call backs or other messages back to the group/card/stack that has a behavior and not the individual control: widget/button/field on the card itself, whose job was simply to intercept a mouse event and server as the target in higher switch. So you need to get the long ID widget id 1104 of card id 1002 of stack "/Users/Brahmanathaswami/Documents/_Siva-Siva-App/modules/listen/listen.livecode" # widget is "downloadSelection" so it seems a bit "hacky" but all I can think of to send a callback to the behavior attached to the card and not the widget itself is: put the long ID of the target into pRequestedBy delete word 1 to 4 of pRequestedBy dispatch "someCommand" to "someOtherStack with param1, param 2, sRequestedBy # intent is, once load URL is done to close the download view dispatch update commands aback to the UI that initiated the Download: the stack "listen" maybe hacky, but simple enough and well, this *is* supposed to be "English like coding" but sometimes my code seems like "baby xTalk" is there a better way? OTOH Baby xTalk is more fun than C++! BR ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode