Script Only Stack Architecture
Richard Gaskin
ambassador at fourthworld.com
Thu Mar 31 17:51:52 EDT 2016
The difference between a library and a behavior is scope: the library
is global, while the behavior only affects the objects to which it's
assigned.
The preloading thang with behaviors is somewhat specific, only coming
into play when all three of the following are true:
- The behavior script must be outside of the stack file containing
objects that depend on it;
- The objects that depend on it happen to be in a stack file loaded
into memory before the external behavior stack is loaded;
- For some reason just setting the stackfiles property to include
the external stack is prohibitive.
Most of my apps have a substack named "<appname>RSRC" where I keep
images and such, and my behavior scripts are buttons there. I never
think about behavior load order at all.
As for scope:
Your library option is a workable solution. Indeed that's the only way
we did things for many years. And where it's a good fit we still do.
But what if you want to change the script so that rather than respond on
mouseUp you want to respond to mouseDown? Or add a handler for new
mouse message?
With a library you'd either have to change the scripts of every object
you want updated, or you could use the message name directly in the
library with a condition in the library, e.g.:
if the uClassName of the target is "MyClass" then...
But with a behavior you just edit one script. Ever. For any change to
all child objects it governs.
And being limited in scope to child objects assigned to it, a behavior
is slightly more efficient than a library, since it's not in the message
path for all of the objects it's unrelated to.
But that performance difference is tiny (very, almost immeasurable).
The biggest benefit is keeping all code in one place. With a behavior
you know that if any subscribed child has code in it, it's an exception
and the code is there for a very distinct reason (overloading or
overriding the behavior).
For all other objects of a class, chances are they'll have no code at
all. The only code they'll have is code that makes them unique; common
code is stored in one common place.
A small stylistic benefit is not needing to keep track of the target,
which may sometimes change during a multi-call sequence.
With behaviors, "me" refers to the child object subscribing to the
behavior. So if you have complex routines that use "send" or "click at"
or other things that can change the target, you still always know the
child object using the behavior, "me".
In all respects the code acts as though it's attached to that child - it
even maintains its own distinct set of local and script-local variables
for each child.
This latter feature is very handy. You could conceivably use custom
properties similarly to keep info bound to the object, but unless you
need that info to be persistent you'll want to clear it or reset it at
some point. But with variables within a behavior script being unique
to each child using it, you never need to think about it - you just code
as if you were coding on the object's own script.
For more sophisticated systems the ability to subclass can be very
useful. If you had a globally-available library that filters out class
members with a condition, using subclasses or superclasses means adding
more conditions. But with behaviors it's just a single property setting
on the affected behavior to chain another to it.
--
Richard Gaskin
Fourth World Systems
Software Design and Development for the Desktop, Mobile, and the Web
____________________________________________________________________
Ambassador at FourthWorld.com http://www.FourthWorld.com
William Prothero wrote:
> 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?
More information about the use-livecode
mailing list