Target not working???
David Burgun
dburgun at dsl.pipex.com
Thu Mar 30 11:20:41 EST 2006
Hi Mark,
On 29 Mar 2006, at 00:04, Mark Wieder wrote:
> David-
>
> Tuesday, March 28, 2006, 3:09:47 AM, you wrote:
>
>> I really can't see that I am "fighting the "natural" object
>> hierarchy". The loop (or something like it needs) to be held
>> somewhere, the fact that it is held in a "central" place really
>> doesn't make much difference. In your example I'd need N loops, one
>> for each stack, doing it my way just results in one loop, e.g. less
>> code. Of course you could make a common function out of your loop and
>> store it in the Stack Script or in a Library and then just call it
>> from each object. This wouldn't be "fighting the "natural" object
>> hierarchy", so how can putting in *my* library be different?
>
> No.
>
> It's tested now. The loop goes in the library stack. One loop. Then it
> gets called on openStack. One line of code per stack. You don't "call"
> it from each object, you send the message to the object from the loop.
> If it's not overloaded in the object it falls through to the library
> stack. That's OOP in action. The fact that it's in a library stack
> makes all the difference. And it's fast because there's no need to
> scan the object scripts.
>
> --in library
> on InitializeEvents
> local x
> repeat with x=1 to the number of controls
> send "ISM_InitializeObject" to control x
> end repeat
> end InitializeEvents
>
> on ISM_InitializeObject
> -- we get here if there no ISM_InitializeObject
> -- handler in the control.
> -- do the default stuff here
> end ISM_InitializeObject
>
> --in each stack
> on openStack
> InitializeEvents
> end openStack
Ok, I understand what you mean now. But that's not what I want to do
in this case. ISM can listen at any level, e.g. the stack level, the
card level, the group level or the specific control level or a
mixture of all these cases), so there can be a ISM_Initialize Handler
in any of the scripts in stack(s), card(s), group(s) control(s). If I
understand the message passing hierarchy, then it works like this:
Control Level
Group Level
Card Level
Stack Level
[other Stacks, such as back scripts or library stack - I have a
question on this, please see later on]
So in the case where I want some controls in a group initialize
themselves *AND* have the Group and/or, Card and/or Stack get
initialized. If I used the normal hierarchy in this base, as far as I
understand it, if I had the following setup:
ButtonControl:
on ISM_InitializeObject
enable me
ListenForMessage(Msg1, kind,token)
end ISM_InitializeObject
FieldControl:
on ISM_InitializeObject
ListenForMessage(Msg1, kind,token)
end ISM_InitializeObject
StaticTextControl1:
----No Handler---
StaticTextControl2:
----No Handler---
StaticTextControl3:
----No Handler---
GroupControlX:
on ISM_InitializeObject
if <something> = <something> then
enable me
else
disable me
end if
ListenForMessage(Msg2,Kind,kind,token)
end ISM_InitializeObject
CardX:
on ISM_InitializeObject
end ISM_InitializeObject
StackY:
on ISM_InitializeObject
end ISM_InitializeObject
In this case:
send "ISM_InitializeObject" to "ButtonControl" and send
"ISM_InitializeObject" to "FieldControl"
would result in "ISM_InitializeObject" being executed in
"ButtonControl" or "FieldControl".
but sending to "StaticTextControl1" would result in
"ISM_InitializeObject" in "GroupControlX" being called, the same
goes for "StaticTextControl2" and "StaticTextControl3".
In this case the initialization paths would be:
StackY: ISM_InitializeObject
CardX: ISM_InitializeObject
Control 1: GroupControlX: ISM_InitializeObject
Control 2: ButtonControl: ISM_InitializeObject
Control 3: FieldControl: ISM_InitializeObject
Control 4: GroupControlX: ISM_InitializeObject (StaticTextControl1
handler not there)
Control 5: GroupControlX: ISM_InitializeObject (StaticTextControl2
handler not there)
Control 6: GroupControlX: ISM_InitializeObject (StaticTextControl3
handler not there)
So GroupControlX: ISM_InitializeObject would be called needlessly
(maybe causing damage) three extra times
If the script of GroupControlX didn't contain an ISM_InitializeObject
handler then it would be:
StackY: ISM_InitializeObject
CardX: ISM_InitializeObject
Control 1: GroupControlX: ISM_InitializeObject
Control 2: ButtonControl: ISM_InitializeObject
Control 3: FieldControl: ISM_InitializeObject
Control 4: GroupControlX: ISM_InitializeObject (StaticTextControl1
handler not there)
Control 5: CardX: ISM_InitializeObject (StaticTextControl2 handler
not there)
Control 6: CardX: ISM_InitializeObject (StaticTextControl3 handler
not there)
If the script of CardX didn't contain an ISM_InitializeObject handler
then it would be:
StackY: ISM_InitializeObject
CardX: ISM_InitializeObject
Control 1: GroupControlX: ISM_InitializeObject
Control 2: ButtonControl: ISM_InitializeObject
Control 3: FieldControl: ISM_InitializeObject
Control 4: GroupControlX: ISM_InitializeObject (StaticTextControl1
handler not there)
Control 5: StackY: ISM_InitializeObject (StaticTextControl2 handler
not there)
Control 6: StackY: ISM_InitializeObject (StaticTextControl3 handler
not there)
If the script of StackY didn't contain an ISM_InitializeObject
handler then ISM_InitializeObject would be called in the Library Stack.
And so on in loads of different combinations.
I just want to visit an object once and if there isn't a handler I
don't want the processing to progress any further. The idea is that
if an object doesn't have an ISM_InitializeObject present then it's
assumed either needs no initialization at all or it has already been
taken care of further up the chain, e.g. it is being taken care of in
either the Group, Card or Stack level.
This is useful since it allows Groups, Cards or Stacks to change
their properties (and therefore alter the appearance of the objects
inside them). For example you might want to change the color of the
text inside a group/card/stack or enable/disable the group/card/stack
depending on the state of another control or group.
Imagine you had 4 Complex Groups (A, B, C and D) that interacted with
each other and they all had to contain valid data before any control
in a fifth Group was allowed to be . You could arrange for the
individual groups to listen to a "ValidState" message with the
parameter A, B, C or D.
Then in the script of the Group or Card or Stack perform the
"container-wide" update (in this case a group), you would:
on ISM_InitializeObject
get ISMListenForMessage("ValidState","KindValidState")
end
on ValidState theMessageID,theMessageKind,theStatus
set itemDelimiter to "|"
switch item 1 of theStatus
case "A"
set the cpGroupAValid of me to item 2 of theStatus
break
case "B"
set the cpGroupBValid of me to item 2 of theStatus
break
case "C
set the cpGroupCValid of me to item 2 of theStatus
break
case "D
set the cpGroupDValid of me to item 2 of theStatus
break
end switch
if ( the cpGroupAValid of me = true) and ( the cpGroupBValid of me =
true) and ( the cpGroupCValid of me = true) and ( the cpGroupDValid
of me = true) then
enable me
else
disable me
end if
end ValidState
any variation of test is possible, e.g.
(GroupAValid or GroupBValid) and( (GroupCValid) or GroupDValid))
etc.
And in the groups A, B, C, D at the appropriate points:
get ISMPutMessage("ValidState","KindValidState",myGroupTag & "|" &
myGroupValidFlag)
where myGroupTag = "A", "B", "C", or "D"
where myGroupValidFlag = true or false
----------------------------------------------------------------------
Now, my question!
I am not clear on the message path with regard to Library Stacks.
Given that the above is correct, e.g. the message passes to the
Control, then Group, then Card, then Stack only calling the next
level up if the handler is defined or it "passes" the message then
what happens in the library stack? Does it follow the same control/
group/card/stack path. e.g. if the path for handler "TestHandler" if
Test Handler were not defined in the target stack be as follows:
StackX:Card1:Group1:ControlA:LibStack:
ControlA ---> Group1: ---> Card1 ---> StackX --->
ControlA ---> Group1 ---> Card1 --> LibStack
All the Best
Dave
More information about the use-livecode
mailing list