Script Only Stack Architecture

William Prothero prothero at earthednet.org
Thu Mar 31 20:34:59 EDT 2016


Thanks for the comments. Very interesting. And I guess the big advantage of behaviors over a library is the scope issue.

I’ll put this info into my toolchest.
Best,
Bill

> On Mar 31, 2016, at 3:33 PM, Ali Lloyd <ali.lloyd at livecode.com> wrote:
> 
> Or more accurately
> on preOpenStack
>  local tBehaviorLongID
>  put the long id of stack "<path to MyBehaviorStack>" into tBehaviorLongID
>  set the behavior of field "FieldWithBehavior" of me to tBehaviorLongID
> end preOpenStack
> 
> On Thu, Mar 31, 2016 at 11:31 PM Ali Lloyd <ali.lloyd at livecode.com> wrote:
> 
>> My solution to this:
>> 
>> Stack "MyTestStack" has a field, which is assigned stack
>> "MyBehaviorStack" as its behavior property.
>> 
>> Stack "MyBehaviorStack" is a separate stack file.
>> 
>> would be to also include the behavior *setting* in the preOpenStack
>> handler of "MyTestStack".
>> 
>> on preOpenStack
>>  set the behavior of field "FieldWithBehavior" of me to <path to
>> MyBehaviorStack>
>> end preOpenStack
>> 
>> This is the model used repeatedly for such things in the IDE.
>> 
>> On Thu, Mar 31, 2016 at 10:10 PM William Prothero <prothero at earthednet.org>
>> wrote:
>> 
>>> Richard:
>>> Ok, for the sake of argument (and my learning), compare that to:
>>> 
>>> 1. Make  new stack and call it “Alt Behavior Playground”
>>> 
>>> 2. Make a new button and enter the script:
>>> on mouseDown
>>> 
>>>   put the long ID of the target into theTarg
>>> 
>>>   doABehavior theTarg
>>> 
>>> end mouseDown
>>> 
>>> 3. Make a substack and call it “myBehaviorLib”  —just for the heck of it.
>>> Put the following script in it:
>>> 
>>> on doABehavior tCtl
>>> 
>>>    doTheGrab tCtl
>>> 
>>> end doABehavior
>>> 
>>> 
>>> on doTheGrab tCtl
>>> 
>>>   grab tCtl
>>> 
>>> end doTheGrab
>>> 
>>> 4. Better do: start using stack “myBehaviorLib”
>>> 
>>> Run it and drag the button you made. This will work in all stacks with
>>> the on mouseDown script in it.
>>> 
>>> So, the “myBehaviorLib” substack could be simply a script only stack that
>>> contains some reasonable number of separate behavior type scripts, and once
>>> the “start using” is invoked, say on a preopenStack script, all common code
>>> for button behaviors becomes a single code element. Inheritance, like
>>> adding new behavior is just adding another script to the “on doABehavior”
>>> handler in the “myBehaviorLib” stack. What you don’t get is the ability to
>>> have the same name for a bunch of different behaviors, but …… perhaps it’s
>>> easier to keep track of handler names that are different anyway.
>>> 
>>> Somehow, this seems more direct to me. It also avoids the need for a
>>> preloader stack the opens a bunch of small files that are behaviors.
>>> 
>>> What do you think?
>>> Bill
>>> 
>>> 
>>> 
>>>> On Mar 31, 2016, at 9:52 AM, Richard Gaskin <ambassador at fourthworld.com>
>>> wrote:
>>>> 
>>>> William Prothero wrote:
>>>> 
>>>>> Reading this kinda makes my head spin. Now I’m thinking it is going
>>>>> to be a heck of a lot more robust for my situation, as a single
>>>>> developer, to not use behaviors at all, but to have a single
>>>>> (possibly script only) substack that holds all of the handlers that I
>>>>> would normally use as behaviors, and just put a call to that handler
>>>>> in each button. I can use “the target”  or “me” as a passed variable
>>>>> to make the action specific to a particular control.
>>>>> 
>>>>> This approach seems a lot less prone to idiosyncrasies and more
>>>>> easily transportable to other apps, to me. It also means that all of
>>>>> my “behavior type scripts” would sit in a single script-only stack,
>>>>> which would make it a lot more convenient to access and edit than a
>>>>> bunch of small script only stacks sitting in my project browser.
>>>>> 
>>>>> Am I wrong. misguided, foolish, or brilliant?
>>>> 
>>>> Behaviors are very powerful for all sorts of things, whether you work
>>> alone or in a team of twenty.
>>>> 
>>>> The biggest benefit for teamwork comes from the very separate question
>>> of whether to use script-only stacks to define behaviors.  Script-only
>>> stacks are an ideal solution for Github-based workflows, but have minimal
>>> value (some, but not as much) for anyone not dependent on a version control
>>> system designed for other languages.
>>>> 
>>>> Ditch script-only stacks for now and continue to explore behaviors.
>>> You'll thank me.  You'll want to buy me lunch next time I'm in Santa
>>> Barbara.  I'll accept.  Behaviors will change everything, very powerfully,
>>> the more you explore and use them.
>>>> 
>>>> Once we step away from the very separate issue of script-only stacks,
>>> we have really only two guidelines for using behaviors effectively:
>>>> 
>>>> - A behavior definition can be any button or stack.
>>>> 
>>>> - When using behaviors, the object containing the behavior script
>>>> must be in memory when anything relying on it is brought into
>>>> memory.
>>>> 
>>>> That's it.
>>>> 
>>>> When exploring a new feature I like to make a simple stack I can use as
>>> a playground to poke around and experiment without mucking up anything
>>> important I'm working on.
>>>> 
>>>> Here's a quick tutorial that may get you hooked on the power of
>>> behaviors:
>>>> 
>>>> 1. Make a new stack titled "Behavior Playground"
>>>> 
>>>> 2. Add a button named "MyClass"
>>>> 
>>>> 3. Set the script of that button to:
>>>> 
>>>>   on mouseUp
>>>>      answer the name of me
>>>>   end mouseUp
>>>> 
>>>> There - you've just created a behavior, defining an action for what
>>> will be an entire class of custom button objects:
>>>> 
>>>> 4. Make a new button named "A"
>>>> 
>>>> 5. In the Message Box run:
>>>> 
>>>>  set the behavior of btn "A" to the long id of btn "MyClass"
>>>> 
>>>> 6. Make two copies of btn "A", naming them "B" and "C" respectively.
>>>> 
>>>> 7. Click any of them.
>>>> 
>>>> What you'll see is that each of them uses the script of button
>>> "MyClass" as if it's their own, bringing up an answer dialog showing the
>>> unique name of each.
>>>> 
>>>> At this point your mind is already thinking of a dozen times in recent
>>> projects where you have several objects you wanted to work the same without
>>> affecting any other scripts.  We could leave it here and you'd be off
>>> writing behaviors very productively right now.
>>>> 
>>>> But we're going to take this one step further - we'll create a
>>> superclass:
>>>> 
>>>> 8. Make a new button named "MySuperClass"
>>>> 
>>>> 9. Set this script of that button to:
>>>> 
>>>>  on mouseDown
>>>>     grab me
>>>>  end mouseDown
>>>> 
>>>> 10. In the Message Box run:
>>>> 
>>>> set the behavior of btn "MyClass" to the long id of btn "MySuperClass"
>>>> 
>>>> 11. Drag any of the "A", "B", or "C" buttons.
>>>> 
>>>> In just 11 steps, each taking only a few seconds, you've just created a
>>> rich hierarchy of custom messaging:
>>>> 
>>>>     "A" "B" "C"
>>>>       \  |  /
>>>>        \ | /
>>>>       MyClass
>>>>          |
>>>>          |
>>>>    MySuperClass
>>>> 
>>>> 
>>>> If you wanted the drag behavior used for an entirely different set of
>>> objects that do something else on mouseUp, you could make another button
>>> named "MyOtherClass" and extend your scope of custom controls even further:
>>>> 
>>>> "A" "B" "C" "D" "E" "F"
>>>>  \  |  /     \  |  /
>>>>   \ | /       \ | /
>>>>  MyClass   MyOtherClass
>>>>      \         /
>>>>       \       /
>>>>      MySuperClass
>>>> 
>>>> Behaviors can be chained as deeply as you like, allowing for very rich
>>> class hierarchies.
>>>> 
>>>> This will get you started.  And it only takes a few minutes to explore.
>>>> 
>>>> 
>>>> ------ EXTRA CREDIT -------
>>>> 
>>>> After you feel comfortable with this, an extra credit exercise might be
>>> explore overriding and overloading.
>>>> 
>>>> Overriding is blocking an action defined in a parent by using a handler
>>> of the same name in a child.
>>>> 
>>>> For example, if you decided button "C" was different from the others
>>> and should reports its long ID rather than its name, you could write a
>>> script in it with:
>>>> 
>>>> on mouseUp
>>>>   answer the long id of me
>>>> end mouseUp
>>>> 
>>>> ...and it'll do that, without affecting any other behaviors provided by
>>> the parent script, or affecting any other objects that use the parent
>>> script.
>>>> 
>>>> Overloading is augmenting a behavior without replacing it.
>>>> 
>>>> So if you wanted your custom controls (buttons "A", "B", etc.) to be
>>> able to have their own mouseUp messages independent of any handling
>>> provided in their parent behavior script, you could write the behavior with
>>> either of two special forms of message handlers: before or after.
>>>> 
>>>> The script of button "MyClass" could be revised as:
>>>> 
>>>> after mouseUp
>>>>   answer the name of me
>>>> end mouseUp
>>>> 
>>>> ...and then the mouseUp message can be handled however you like in any
>>> of the class instances ("A", "B", etc.), yet the behavior script will also
>>> fire immediately after.
>>>> 
>>>> The "before <message>" works similarly, but as you can guess those fire
>>> before the child gets the message.
>>>> 
>>>> Before and after handlers are limited to behavior scripts, as they were
>>> added specifically to allow behaviors to augment actions without limiting
>>> the scope of normal messages a subscribed object can act on.
>>>> 
>>>> This may be a lot to take in all at once.
>>>> 
>>>> Play with steps 1 to 11 to get going, explore ways to apply that to
>>> your work.  Later on you can add "before" and "after" handlers if you need
>>> them.  You may not (I rarely use them), but if you do need them they're
>>> good to know about.
>>>> 
>>>> Don your pith helmet and begin your adventure!
>>>> 
>>>> --
>>>> Richard Gaskin
>>>> Fourth World Systems
>>>> Software Design and Development for the Desktop, Mobile, and the Web
>>>> ____________________________________________________________________
>>>> Ambassador at FourthWorld.com                http://www.FourthWorld.com
>>>> 
>>>> 
>>>> _______________________________________________
>>>> use-livecode mailing list
>>>> use-livecode at 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 at 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 at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode





More information about the use-livecode mailing list