question about delete and order

Tim,

Thanks for offering to help. I posted details to the problem on the following forum.

viewtopic.php?f=8&t=3203

Now onto your response. The reason I mentioned clicking is that it seems to me there is a concept of a “selected” piece. E.g. when you hit a keystroke, I believe that the keystroke is sent to the selected piece. I thought the way you selected a piece was by clicking on it. E.g. if you left-click on a card and then press ctrl-a, it will add THAT card to your hand. If you left-click on a different card, then the ctrl-a will apply to that card instead. There will often be logic in a prototype that fires conditionally based on attributes of a piece; the values of those attributes, I assume, is based on the left-click selection of that piece.

That is why I assumed that #2 and #3 are different. After writing that, it occurred to me that there’s a #5 which is dragging the piece.

The reason I broke out #3 and #4 is it seems to me there are plenty of places in the code where there is a keystroke trigger for a key that it is assumed will be pressed by the engine and not a player (a dumb way to call a function IMO but that’s a separate topic.)

On the programming vs. modding topic, I understand that supporting the VASSAL engine is different work from supporting a module. But I would call both programming, it’s just that in the former you’re programming in the functional programming language of Java whereas in the latter you’re programming in the declarative language VASSAL. Java has a very clear instruction manual. If you want to know what order things happen in Java, it’s very clearly documented. Things also happen in a specific order in the VASSAL programming language, but I’ve been having trouble finding the documentation that will tell me what order key listeners will execute in. But whether it’s programming or modding I guess is a semantic debate.

I had a look at the code and it looks to me like the “active” and “passive” keys in a TriggerAction are treated identically.

From TriggerAction.java:

[code]
public Command myKeyEvent(KeyStroke stroke) {
/*
* 1. Are we interested in this key command? Is it our command key? Does it
* match one of our watching keystrokes?
*/
boolean seen = false;
if (key.equals(stroke)) {
seen = true;
}

for (int i = 0; i < watchKeys.length && !seen; i++) {
  if (watchKeys[i].equals(stroke)) {
    seen = true;
  }
}[/code]

If it helps in your troubleshooting, I’ve uploaded the output of vassal-module-analyzer for TTA. It prints out all the traits in a human-readable, searchable format as well as lists all key senders and key listeners by key. (I wrote vassal-module-analyzer last week in order to wrap my head around this wonder problem–for more details on it, see my other posts in the forum.)

Thus spake fil512:

Thanks for your patience with me. I still have much to learn about
VASSAL module programming. That post you sent me was helpful. It
should be a part of the “Game Piece” page in the Reference Manual. Is
anyone maintaining the Reference Manual?

Last I checked, Ed Massena said the next version was nearly ready.

Not knowing the answer to these questions makes it hard to program in
VASSAL. It sounds like you are recommending determining the answer to
my question by trial and error, “learn by building modules”. But if I
take the trial and error approach, I’ll probably end up coding all sorts
of stuff unnecessarily, and my resulting module will be complex and
difficult for maintainers to support. In order to create a nice clean
module, I need to know the rules of the VASSAL programming language.

The more discussions I see of the way that traits work, the more I think
that we need to overhaul it to make it more consistent…


J.

In each those four different entry points, which of the 34 traits are
involved?

It doesn’t matter which entry point. And almost all of them are involved
depending on the keystroke.

For a particular entry point, and the traits that are
involved in that entry point, in which order are the traits executed?

If you’re looking at the list of traits in the editor, it goes from bottom
up. There are some exceptions, however. Triggers are always done last and
I believe that Reports are done last.

Not knowing the answer to these questions makes it hard to program in
VASSAL. It sounds like you are recommending determining the answer to
my question by trial and error, “learn by building modules”.

Experience is invaluable. Also looking at other people’s examples.

From what I’ve seen working with it so far, I get the sense there are
two distinct pathways through a piece. If the entry point is mouse
clicking (selecting), then it behaves in the way described in that post
you sent me. If, however, the entry point is a keystroke, then I get
the sense a completely different set of rules apply.

There is no difference.

You mention TriggerAction and ReportAction as being exceptions, but I
count at least 9 different traits that listen for keystrokes.

Actually, almost all of them do. Off the top of my head, I can’t think of
one that doesn’t.

Some of
those determine whether a keystroke makes it to another trait, and in
those cases order could matter (or it could be that those “Restrict”
type traits apply to all other traits in the piece irrespective of
order). From trial and error, so far I’ve determined that ReportAction
and GlobalKeyAction both fire before Delete actions, but TriggerActions
fire after delete actions.

Triggers are usually fired last. All the others are triggered from the
bottommost in the list to the topmost in that order.

This suggests that there is a list. A list
that determines the order in which key listening traits fire when there
are multiple traits on the same piece listening for the same keystroke. I
confirmed that Delete happens before TriggerAction by moving the
Delete above TriggerAction and then below TriggerAction and in both
cases the Delete prevented the TriggerAction.

Triggers are an exception to the rule.

But when I removed the
Delete alltogether, then the TriggerAction happened. Why did Delete
take precedence over TriggerAction in this case? Why is Delete higher
than TriggerAction on the list? (“The list” being the order in which
key-based traits are executed when multiple traits on a single piece
listen for the same key.)

Trigger is last. This is because it waits for the state of the change to be
finalized before checking whether the trigger can be fired.

Hope this helps.

  • M.

I hope that this clarifies my question. I am probably making a number
of mistakes in the way I formulate my question because I am still
learning how VASSAL works. I look forward to further enlightenment.


Read this topic online here:
question about delete and order - #7 by fil512


messages mailing list
messages@vassalengine.org
vassalengine.org/mailman/listinfo/messages







In each those four different entry points, which of the 34 traits are

involved? �

It doesn’t matter which entry point. And almost all of them are involved depending on the keystroke.

For a particular entry point, and the traits that are

involved in that entry point, in which order are the traits executed?

If you’re looking at the list of traits in the editor, it goes from bottom up.� There are some exceptions, however.� Triggers are always done last and I believe that Reports are done last.




Not knowing the answer to these questions makes it hard to program in

VASSAL. �It sounds like you are recommending determining the answer to

my question by trial and error, “learn by building modules”. �

Experience is invaluable.� Also looking at other people’s examples.



From what I’ve seen working with it so far, I get the sense there are

two distinct pathways through a piece. �If the entry point is mouse

clicking (selecting), then it behaves in the way described in that post

you sent me. �If, however, the entry point is a keystroke, then I get

the sense a completely different set of rules apply.

There is no difference.�


You mention TriggerAction and ReportAction as being exceptions, but I
count at least 9 different traits that listen for keystrokes. �

Actually, almost all of them do.� Off the top of my head, I can't think of one that doesn't.
Some of
those determine whether a keystroke makes it to another trait, and in
those cases order could matter (or it could be that those "Restrict"
type traits apply to all other traits in the piece irrespective of
order). �From trial and error, so far I've determined that ReportAction
and GlobalKeyAction both fire before Delete actions, but TriggerActions
fire after delete actions. �

Triggers are usually fired last.� All the others are triggered from the bottommost in the list to the topmost in that order.
This suggests that there is a list. �A list
that determines the order in which key listening traits fire when there
are multiple traits on the same piece listening for the same keystroke. I confirmed that Delete happens before TriggerAction by moving the
Delete above TriggerAction and then below TriggerAction and in both
cases the Delete prevented the TriggerAction. �

Triggers are an exception to the rule.
But when I removed the
Delete alltogether, then the TriggerAction happened. �Why did Delete
take precedence over TriggerAction in this case? �Why is Delete higher
than TriggerAction on the list? �("The list" being the order in which
key-based traits are executed when multiple traits on a single piece
listen for the same key.)

Trigger is last.� This is because it waits for the state of the change to be finalized before checking whether the trigger can be fired.

Hope this helps.

- M.

I hope that this clarifies my question. �I am probably making a number
of mistakes in the way I formulate my question because I am still
learning how VASSAL works. �I look forward to further enlightenment.

_______________________________________________
Read this topic online here:
https://forum.vassalengine.org/t/question-about-delete-and-order/3127/7
_______________________________________________
messages mailing list
[messages@vassalengine.org](mailto:messages@vassalengine.org)
[vassalengine.org/mailman/listinfo/messages](http://www.vassalengine.org/mailman/listinfo/messages)




Maybe I’m missing what it is you are trying to accomplish with having a
delete trait and a trigger trait fire on the same keystroke, but this
behavior I would expect out the delete trait. If you delete a piece you are
telling to the module to remove it completely and make it unable to be
referenced for the rest of that session and save files. I would think delete
would take precedence over other traits just to be sure it couldn’t cause
any undo issues like infinite loops on key strokes or circular references
generating errors.

Perhaps what you are looking for is an invisible piece that can act as a
proxy for the trigger actions and send the delete keystroke to the real
piece when needed.

-----Original Message-----
From: messages-bounces@vassalengine.org
[mailto:messages-bounces@vassalengine.org] On Behalf Of Tim M
Sent: Wednesday, July 28, 2010 7:44 PM
To: messages@vassalengine.org
Subject: [messages] [Developers] Re: question about delete and order

Ok I see what your getting at better.
Your 4 entry points - Im not sure what #1 is/does, a piece doesnt do
anything just by left clicking it unless it is invoking an Action Button
which invokes a Key command to initiate something (or do you mean
dragging)

#2 is no different than #3 that is just how you interface - it is their
key command that initiates the action
#4 cannot happen without some sort of initiation previously from 1-3
above - something told it to do it :slight_smile: If #4 is the cause, you need to
widen the scope to find out where it came from to understand the reason
why

Which of the traits are involved? I’ve d/l and will look, this requires
plain old fashion detective work to figure out what is trying to be done
(Need to find the original sequence description first so I know where to
start)

Programming is different from Modding - which one is it your wanting to
do ?

Delete vs Trigger problem. Something to consider here. A Delete trait
employs an active key command, but a Trigger trait can be employed in
two different ways, active (using only the key command field) or passive
(using only the listen for keystroke field).
Perhaps this may be why you are seeing the Delete occur before the
Trigger if the trigger is using a passive key instead of an active key.


Read this topic online here:
https://forum.vassalengine.org/t/question-about-delete-and-order/3127/8

I agree with you that consistency is the best route whenever possible.

However, there are probably good, practical reasons why VASSAL has made exceptions to consistent trait order execution. But if you are going to make exceptions, then you really need to write down the rules for people so we know how it works. Otherwise module designers will code via trial and error, and guesswork which will result in them feeling frustrated and it will also result in convoluted modules. I’m really happy to hear that someone is working on updating the Reference Manual. That’s hard work, but the benefits to the community will be enormous.

Thanks for all the help with this. Sorry that I sound like a broken record about the question of trait order execution. I feel that it’s important that it be clear to module designers how it works.

It sounds like you’re guessing. How can I get a definitive answer to my question?

Here are some traits that don’t listen for keystrokes:
Action Button
Does not stack
Non-Rectangular
Area of Effect
Sub-Menu
Restrict Commands
Restricted Access
Marker

This sounds like another guess. Is there a forum post maybe somewhere that definitively answers the question about trait execution order?

Are they the only exception? Does this apply to both the watch keys and the key command for the trigger? What about Report Action? Are they last too? Which is laster?

Not trying to be a pain in the ass, just seeking to understand,
Ken

I think it’s extremely dangerous to change things. It may be possible to
deprecate inconsistent features.

It mostly makes sense.

However, there is a feature that I’ve used that only sort of works that
doesn’t make a whole lot of sense. If two traits respond to the same key
event, they will both respond, but some traits do not check the inner trait
to see if anything else will respond. And I don’t mean the “restrict
commands” trait which is obvious. I’ll see if I can find the one I mean –
i.e., it will respond to the keystroke, but nothing above it will. That
drives me nuts.

Another inconsistent feature is traits that check for properties. Some
check for property names starting from
getOutermost(this).getProperty(propName). Others only check property names
starting from getInner().getProperty(propName). That also drives me nuts.

And kids that walk on my lawn. They drive me nuts too.

  • M.

On 29 July 2010 13:32, fil512 ken.stevens@sympatico.ca wrote:

“uckelman” wrote:

Thus spake fil512:
The more discussions I see of the way that traits work, the more I
think
that we need to overhaul it to make it more consistent…

I agree with you that consistency is the best route whenever possible.

However, there are probably good, practical reasons why VASSAL has made
exceptions to consistent trait order execution. But if you are going to
make exceptions, then you really need to write down the rules for people
so we know how it works. Otherwise module designers will code via trial
and error, and guesswork which will result in them feeling frustrated
and it will also result in convoluted modules. I’m really happy to hear
that someone is working on updating the Reference Manual. That’s hard
work, but the benefits to the community will be enormous.

I think it’s extremely dangerous to change things.� It may be possible to deprecate inconsistent features.

It mostly makes sense.�

However, there is a feature that I’ve used that only sort of works that doesn’t make a whole lot of sense.� If two traits respond to the same key event, they will both respond, but some traits do not check the inner trait to see if anything else will respond.� And I don’t mean the “restrict commands” trait which is obvious.� I’ll see if I can find the one I mean – i.e., it will respond to the keystroke, but nothing above it will.� That drives me nuts.


Another inconsistent feature is traits that check for properties.� Some check for property names starting from getOutermost(this).getProperty(propName).� Others only check property names starting from getInner().getProperty(propName).� That also drives me nuts.


And kids that walk on my lawn.� They drive me nuts too.�

- M.

On 29 July 2010 13:32, fil512 <ken.stevens@sympatico.ca> wrote:


"uckelman" wrote:
Thus spake fil512:
The more discussions I see of the way that traits work, the more I
think
that we need to overhaul it to make it more consistent...



I agree with you that consistency is the best route whenever possible.

However, there are probably good, practical reasons why VASSAL has made
exceptions to consistent trait order execution. �But if you are going to
make exceptions, then you really need to write down the rules for people
so we know how it works. �Otherwise module designers will code via trial
and error, and guesswork which will result in them feeling frustrated
and it will also result in convoluted modules. �I'm really happy to hear
that someone is working on updating the Reference Manual. �That's hard
work, but the benefits to the community will be enormous.

Thus spake Michael Kiefte:

I think it’s extremely dangerous to change things. It may be possible to
deprecate inconsistent features.

I’m not suggesting that we change the behavior of existing features without
providing some kind of versioning for them.

However, there is a feature that I’ve used that only sort of works that
doesn’t make a whole lot of sense. If two traits respond to the same key
event, they will both respond, but some traits do not check the inner trait
to see if anything else will respond. And I don’t mean the “restrict
commands” trait which is obvious. I’ll see if I can find the one I mean –
i.e., it will respond to the keystroke, but nothing above it will. That
drives me nuts.

Another inconsistent feature is traits that check for properties. Some
check for property names starting from
getOutermost(this).getProperty(propName). Others only check property names
starting from getInner().getProperty(propName). That also drives me nuts.

If you want to track those down and fix them, go for it. At the rate I’m
going with all the web site stuff, I’ll get to problems like this myself
shortly after the sun burns out.


J.

C,

What I’m trying to do is fix a bug in someone else’s module. It’s a monster module with over 5000 traits (Through the Ages). As someone completely new to VASSAL, I’ve probably bitten off more than I can chew here, but I am confident that if I can just learn the rules that govern trait execution that I WILL be able to fix this bug. It’s been harder than I expected to learn the rules that determine the order traits are executed in. I keep hearing about general rules, and then guesses at exceptions to those rules, but no-one seems to really know how it works. For example, above you write, “I would think delete would take precedence over other traits.” You’re making a guess when you say this. Programming shouldn’t be about guesswork. The rules about how VASSAL works should be clear: no guessing; so we can all just get on with the business of building modules.

Your suggestion to use an invisible piece is intriguing. Someone earlier suggested I use a Dynamic Property. There are probably other ways to skin this cat too. But I want to pick the “proper” solution. And in order to do that, I need to know the rules that govern trait order execution. Surely someone in the VASSAL community knows the answer to that question without guessing… Anybody?

Ken

“mkiefte” wrote:

If you’re looking at the list of traits in the editor, it goes from
bottom
up. There are some exceptions, however. Triggers are always done
last and
I believe that Reports are done last.

It sounds like you’re guessing. How can I get a definitive answer to my
question?

I’ve looked at that code a lot. I wasn’t definitive on Report Actions,
because I’ve never cared about that trait in the past.

Here are some traits that don’t listen for keystrokes:
Action Button
Does not stack
Non-Rectangular
Area of Effect
Sub-Menu
Restrict Commands
Restricted Access
Marker

Ah, well, there you go. But certainly more than 8. And Restrict Commands
does listen for keystrokes.

This sounds like another guess. Is there a forum post maybe somewhere
that definitively answers the question about trait execution order?

It’s not a guess.

Are they the only exception? Does this apply to both the watch keys and
the key command for the trigger? What about Report Action? Are they
last too? Which is laster?

The default is to do your action first and then check for inner traits
(traits that are higher up on the list). Trigger does all the inner
(higher) traits first and then does it’s action(s) which may fire other
triggers which will be after that, etc. Reports are done after the
keystroke that it’s reporting is done. Between reports and triggers,
whichever is higher in the list will go first – i.e., it will be the
reverse of the normal procedure.

Not trying to be a pain in the ass, just seeking to understand,
Ken

No problem. I get the impression you’ve looked at the Java code. You will
learn an awful lot that way. I’ve looked at a lot of programs in my life and
I have to say, that documentation lies a lot, but code never lies.

And I’m more than happy to answer questions about the Java code.

  • M.





“mkiefte” wrote:


If you're looking at the list of traits in the editor, it goes from
bottom
up. �There are some exceptions, however. �Triggers are always done
last and
I believe that Reports are done last.



It sounds like you're guessing. �How can I get a definitive answer to my
question?

I've looked at that code a lot.� I wasn't definitive on Report Actions, because I've never cared about that trait in the past.



Here are some traits that don't listen for keystrokes:
Action Button
Does not stack
Non-Rectangular
Area of Effect
Sub-Menu
Restrict Commands
Restricted Access
Marker

Ah, well, there you go.� But certainly more than 8.� And Restrict Commands _does_ listen for keystrokes.



This sounds like another guess. �Is there a forum post maybe somewhere
that definitively answers the question about trait execution order?

It's not a guess.



Are they the only exception? �Does this apply to both the watch keys and
the key command for the trigger? �What about Report Action? �Are they
last too? �Which is laster?

The default is to do your action first and then check for inner traits (traits that are higher up on the list).� Trigger does all the inner (higher) traits first and then does it's action(s) which may fire other triggers which will be after that, etc.� Reports are done after the keystroke that it's reporting is done.� Between reports and triggers, whichever is higher in the list will go first -- i.e., it will be the reverse of the normal procedure.


Not trying to be a pain in the ass, just seeking to understand,
Ken

No problem.� I get the impression you've looked at the Java code.� You will learn an awful lot that way. I've looked at a lot of programs in my life and I have to say, that documentation lies a lot, but code never lies.

And I'm more than happy to answer questions about the Java code.

- M.

Think we went over that once before, the problem iirc is not that it can’t be fixed to act in a consistent way, it’s that modules might break after if they depend on the way things work now.

Heres a simple example:

Today you might have a stack order like this -

BasicPiece
Report Action, CTRL B, output “Hello”
Trigger Action, inkey CTRL A, outkey CTRL B, CTRL C
Report Action, CTRL B, output “World”
Report Action, CTRL C, output “End of Routine”

when we execute the CTRL A we get the output in the chat window as follows

World
Hello
End of Routine

thasts not quite right, so to fix we reverse the 2 CTRL B reports

BasicPiece
Report Action, CTRL B, output “World”
Trigger Action, inkey CTRL A, outkey CTRL B, CTRL C
Report Action, CTRL B, output “Hello”
Report Action, CTRL C, output “End of Routine”

and when we run again we now get

Hello
World
End of Routine

it works - but now if we leave it like it is and fix all traits to respect stack order properly we would only get

World

which is breaking the way things work today and to fix properly we would have to reorg the entire stack like so

BasicPiece
Report Action, CTRL C, output “End of Routine”
Report Action, CTRL B, output “World”
Report Action, CTRL B, output “Hello”
Trigger Action, inkey CTRL A, outkey CTRL B, CTRL C

Now ideally everything should be organized like the last example and work that way, but unfortunately it’s not and/or doesn’t

I agree with Mike, that change could be dangerous

You didn’t answer my question about whether both the watch keys and key command of trigger action are treated the same way. Earlier I posted that the code suggests they are treated the same way, but I’ve since seen other code that suggests otherwise. Do you know the answer?

I have a bunch of questions about your paragraph above. First, when you say Trigger does all the inner (higher) traits first. By higher, do you mean visibly higher on the list? Because if so, then that seems to contradict Tim’s Hello World example. Has Tim got it wrong or did you misspeak, or do I misunderstand?

But more significantly to me, what you write seems to contradict what I’m experiencing as documented in the first post in this thread, namely I experience that the order between Delete and TriggerAction doesn’t seem to matter–Delete always happens before TriggerAction.

Mike is correct, my example is backwards


From: fil512 ken.stevens@sympatico.ca
To: messages@vassalengine.org
Sent: Thu, July 29, 2010 12:47:40 PM
Subject: [messages] [Developers] Re: [Developers] Re: Edit: [Developers] Re:
quest

“mkiefte” wrote:

Are they the only exception?� Does this apply to both the watch keys
and
the key command for the trigger?� What about Report Action?� Are
they
last too?� Which is laster?

The default is to do your action first and then check for inner traits
(traits that are higher up on the list).� Trigger does all the inner
(higher) traits first and then does it’s action(s) which may fire
other
triggers which will be after that, etc.� Reports are done after the
keystroke that it’s reporting is done.� Between reports and triggers,
whichever is higher in the list will go first – i.e., it will be the
reverse of the normal procedure.

You didn’t answer my question about whether both the watch keys and key
command of trigger action are treated the same way.� Earlier I posted
that the coded suggests they are treated the same way, but I’ve since
seen other code that suggests otherwise.� Do you know the answer?

I have a bunch of questions about your paragraph above.� First, when you
say Trigger does all the inner (higher) traits first.� By higher, do you
mean visibly higher on the list?� Because if so, then that seems to
contradict Tim’s Hello World example.� Has Tim got it wrong or did you
misspeak, or do I misunderstand?

But more significantly to me, what you write seems to contradict what
I’m experiencing as documented in the first post in this thread, namely
I experience that the order between Delete and TriggerAction doesn’t
seem to matter–Delete always happens before TriggerAction.


Read this topic online here:

You didn’t answer my question about whether both the watch keys and key
command of trigger action are treated the same way. Earlier I posted
that the code suggests they are treated the same way, but I’ve since
seen other code that suggests otherwise. Do you know the answer?

They are treated the same way.

I have a bunch of questions about your paragraph above. First, when you
say Trigger does all the inner (higher) traits first. By higher, do you
mean visibly higher on the list?

Yes.

Because if so, then that seems to
contradict Tim’s Hello World example. Has Tim got it wrong or did you
misspeak, or do I misunderstand?

Don’t know. Where’s Tim’s Hello World example?

But more significantly to me, what you write seems to contradict what
I’m experiencing as documented in the first post in this thread, namely
I experience that the order between Delete and TriggerAction doesn’t
seem to matter–Delete always happens before TriggerAction.

Triggers always happen last. No contradiction. I’ve said that already.

  • M.





You didn’t answer my question about whether both the watch keys and key

command of trigger action are treated the same way. �Earlier I posted

that the code suggests they are treated the same way, but I’ve since

seen other code that suggests otherwise. �Do you know the answer?

They are treated the same way.


I have a bunch of questions about your paragraph above. �First, when you
say Trigger does all the inner (higher) traits first. �By higher, do you
mean visibly higher on the list? �

Yes.
Because if so, then that seems to

contradict Tim’s Hello World example. �Has Tim got it wrong or did you

misspeak, or do I misunderstand?


Don’t know.� Where’s Tim’s Hello World example?


But more significantly to me, what you write seems to contradict what
I'm experiencing as documented in the first post in this thread, namely
I experience that the order between Delete and TriggerAction doesn't
seem to matter--Delete always happens before TriggerAction.

Triggers always happen last.� No contradiction.� I've said that already.

- M.

I think the best strategy is to create new Traits with new names that mimic
the behaviour of old Traits but which are implemented in a more consistent
way. The old traits do not need to appear on the list, but will continue
to exist internally.

  • M.

On 29 July 2010 14:22, Tim M timothy.mccarron@sbcglobal.net wrote:

“uckelman” wrote:

The more discussions I see of the way that traits work, the more I
think
that we need to overhaul it to make it more consistent…


J.

Think we went over that once before, the problem iirc is not that it
can’t be fixed to act in a consistent way, it’s that modules might break
after if they depend on the way things work now.

Heres a simple example:

Today you might have a stack order like this -
BasicPiece
Report Action, CTRL B, output “Hello”
Trigger Action, inkey CTRL A, outkey CTRL B, CTRL C
Report Action, CTRL B, output “World”
Report Action, CTRL C, output “End of Routine”

when we execute the CTRL A we get the output in the chat window as
follows

World
Hello
End of Routine

thasts not quite right, so to fix we reverse the 2 CTRL B reports

BasicPiece
Report Action, CTRL B, output “World”
Trigger Action, inkey CTRL A, outkey CTRL B, CTRL C
Report Action, CTRL B, output “Hello”
Report Action, CTRL C, output “End of Routine”

and when we run again we now get

Hello
World
End of Routine

it works - but now if we leave it like it is and fix all traits to
respect stack order properly we would only get

World

which is breaking the way things work today and to fix properly we would
have to reorg the entire stack like so

BasicPiece
Report Action, CTRL C, output “End of Routine”
Report Action, CTRL B, output “World”
Report Action, CTRL B, output “Hello”
Trigger Action, inkey CTRL A, outkey CTRL B, CTRL C

Now ideally everything should be organized like the last example and
work that way, but unfortunately it’s not and/or doesn’t

I agree with Mike, that change could be dangerous

I think the best strategy is to create new Traits with new names that mimic the behaviour of old Traits but which are implemented in a more consistent way.�� The old traits do not need to appear on the list, but will continue to exist internally.


- M.

On 29 July 2010 14:22, Tim M <timothy.mccarron@sbcglobal.net> wrote:


"uckelman" wrote:
The more discussions I see of the way that traits work, the more I
think
that we need to overhaul it to make it more consistent...

--
J.


Think we went over that once before, the problem iirc is not that it
can't be fixed to act in a consistent way, it's that modules might break
after if they depend on the way things work now.

Heres a simple example:

Today you might have a stack order like this -
BasicPiece
Report Action, CTRL B, output "Hello"
Trigger Action, inkey CTRL A, outkey CTRL B, CTRL C
Report Action, CTRL B, output "World"
Report Action, CTRL C, output "End of Routine"

when we execute the CTRL A we get the output in the chat window as
follows

World
Hello
End of Routine

thasts not quite right, so to fix we reverse the 2 CTRL B reports

BasicPiece
Report Action, CTRL B, output "World"
Trigger Action, inkey CTRL A, outkey CTRL B, CTRL C
Report Action, CTRL B, output "Hello"
Report Action, CTRL C, output "End of Routine"

and when we run again we now get

Hello
World
End of Routine

it works - but now if we leave it like it is and fix all traits to
respect stack order properly we would only get

World

which is breaking the way things work today and to fix properly we would
have to reorg the entire stack like so

BasicPiece
Report Action, CTRL C, output "End of Routine"
Report Action, CTRL B, output "World"
Report Action, CTRL B, output "Hello"
Trigger Action, inkey CTRL A, outkey CTRL B, CTRL C

Now ideally everything should be organized like the last example and
work that way, but unfortunately it's not and/or doesn't

I agree with Mike, that change could be dangerous


For example, above you write, “I would think delete would take
precedence over other traits.” You’re making a guess when you say this.

Delete follows the same precedence rules as almost all other traits. It is
not an exception. It is perfectly possible to delete a piece before it’s
finished processing a key command.

Programming shouldn’t be about guesswork. The rules about how VASSAL
works should be clear: no guessing; so we can all just get on with the
business of building modules.

If the rules are still not clear, let me know.

Your suggestion to use an invisible piece is intriguing.

This is done in many cases where it is impossible to manipulate a property
that does not belong to a Game Piece. You can have one invisible Game Piece
that contains all such properties.

Someone
earlier suggested I use a Dynamic Property. There are probably other
ways to skin this cat too. But I want to pick the “proper” solution.

Sometimes there are several “proper” solutions. I wouldn’t get too caught
up in that idea.

And in order to do that, I need to know the rules that govern trait
order execution. Surely someone in the VASSAL community knows the
answer to that question without guessing… Anybody?

Yes. Several.

  • M.



For example, above you write, “I would think delete would take

precedence over other traits.” �You’re making a guess when you say this.

Delete follows the same precedence rules as almost all other traits.� It is not an exception.� It is perfectly possible to delete a piece before it’s finished processing a key command.


Programming shouldn’t be about guesswork. �The rules about how VASSAL

works should be clear: no guessing; so we can all just get on with the

business of building modules.

If the rules are still not clear, let me know.


Your suggestion to use an invisible piece is intriguing. �

This is done in many cases where it is impossible to manipulate a property that does not belong to a Game Piece.� You can have one invisible Game Piece that contains all such properties.
Someone
earlier suggested I use a Dynamic Property. �There are probably other
ways to skin this cat too. �But I want to pick the "proper" solution.

Sometimes there are several "proper" solutions.� I wouldn't get too caught up in that idea.

And in order to do that, I need to know the rules that govern trait
order execution. �Surely someone in the VASSAL community knows the
answer to that question without guessing... �Anybody?

Yes. Several.

- M.

What do you mean by a “Trigger does all the inner traits first”? Do you mean that if a keystroke is hit that a Trigger is listening to, then the trigger first sends that keystroke to all inner traits, then processes the keystroke itself, and then the keystroke is sent to traits below the Trigger? If that is what you mean, then that would seem to contradict the fact that triggers “always go last”. So I guess that probably means that I don’t understand what you mean by “does all the inner traits first”…

Thanks to your patience in answering my question, it is getting clearer for me. I guess I still don’t have a complete answer to the question of what happens when multiple traits in the same piece are listening to the same keystroke. Let me take a crack at answering this question based on what I know so far:

Case 1) keystroke came from outside the piece.
In this case, all traits listening for the keystroke execute in order, starting with the bottom of the trait list working backwards up to the top, with the exception being trigger actions which are always executed last (in presumably the same order–i.e. bottom to top).

Case 2) keystroke came from a trait within the piece.
Case 2a) keystroke came from a trigger
In this case, all traits listening for the keystroke execute in order, starting from the one above the trigger working backwards to the top, then the trigger sends its keystrokes and those are resolved, and then all traits below the trigger are executed working backwards from the bottom up to 1 below the trigger.
Case 2b) keystroke came from another trait, not a trigger (e.g. an action button)
In this case, the traits are executed in the same order as Case 1.

Have I got it right yet?

P.S. If you reply by clicking on the little icon on the top-right corner of a post, your replies will be half the size.

Thus spake fil512:

P.S. If you reply by clicking on the little icon on the top-right
corner of a post, your replies will be half the size.

This is not Micheal’s fault. It’s due to the code I wrote for the
mailing list-forum bridge which translates quoted parts to BBCode
not being quite right yet. (I see that I must also have a character
encoding problem in there, too.)

If anyone who knows PHP wants to debug this, feel free to volunteer.


J.

What do you mean by a “Trigger does all the inner traits first”? Do you
mean that if a keystroke is hit that a Trigger is listening to, then the
trigger first sends that keystroke to all inner traits, then processes
the keystroke itself, and then the keystroke is sent to traits below the
Trigger? If that is what you mean, then that would seem to contradict
the fact that triggers “always go last”. So I guess that probably means
that I don’t understand what you mean by “does all the inner traits
first”…

I think I see where you misunderstand.

If a trigger is listening for a keystroke, it will let all the inner (i.e.,
higher) traits respond to the key first. It will then do the keystrokes
it’s asked to do afterwards. That is what I mean by triggers always go
last.

For example, a trigger is asked to respond to SHIFT-A and, in response, it
sends SHIFT-B. When it receives SHIFT-A, all the the inner traits respond
to it before the trigger does SHIFT-B.

Case 1) keystroke came from outside the piece.
In this case, all traits listening for the keystroke execute in order,
starting with the bottom of the trait list working backwards up to the
top, with the exception being trigger actions which are always executed
last (in presumably the same order–i.e. bottom to top).

Correct, except for the trigger part. Triggered keystrokes are done from
top downwards – the opposite of the usual.

Case 2) keystroke came from a trait within the piece.
Case 2a) keystroke came from a trigger
In this case, all traits listening for the keystroke execute in order,
starting from the one above the trigger working backwards to the top,

Trigger properties are activated from the top down – i.e., after all the
non-trigger traits have done their thing, the triggers then respond to the
event one at a time from the top downward. When they fire their keystrokes,
they affect the game piece in exactly the same way as if you had done it
externally.

then the trigger sends its keystrokes and those are resolved, and then
all traits below the trigger are executed working backwards from the
bottom up to 1 below the trigger.
Case 2b) keystroke came from another trait, not a trigger (e.g. an
action button)
In this case, the traits are executed in the same order as Case 1.

That sounds right.

P.S. If you reply by clicking on the little icon on the top-right

corner of a post, your replies will be half the size.

I’m not even using the forum.

  • M.





What do you mean by a “Trigger does all the inner traits first”? �Do you

mean that if a keystroke is hit that a Trigger is listening to, then the

trigger first sends that keystroke to all inner traits, then processes

the keystroke itself, and then the keystroke is sent to traits below the

Trigger? �If that is what you mean, then that would seem to contradict

the fact that triggers “always go last”. �So I guess that probably means

that I don’t understand what you mean by “does all the inner traits

first”…

I think I see where you misunderstand.

If a trigger is listening for a keystroke, it will let all the inner (i.e., higher) traits respond to the key first.� It will then do the keystrokes it’s asked to do afterwards.� That is what I mean by triggers always go last.�


For example, a trigger is asked to respond to SHIFT-A and, in response, it sends SHIFT-B.� When it receives SHIFT-A, all the the inner traits respond to it before the trigger does SHIFT-B.


Case 1) keystroke came from outside the piece.
In this case, all traits listening for the keystroke execute in order,
starting with the bottom of the trait list working backwards up to the
top, with the exception being trigger actions which are always executed
last (in presumably the same order--i.e. bottom to top).

Correct, except for the trigger part.� Triggered keystrokes are done from top downwards -- the opposite of the usual.�

Case 2) keystroke came from a trait within the piece.
Case 2a) keystroke came from a trigger
In this case, all traits listening for the keystroke execute in order,
starting from the one above the trigger working backwards to the top,

Trigger properties are activated from the top down -- i.e., after all the non-trigger traits have done their thing, the triggers then respond to the event one at a time from the top downward.� When they fire their keystrokes, they affect the game piece in exactly the same way as if you had done it externally.

then the trigger sends its keystrokes and those are resolved, and then
all traits below the trigger are executed working backwards from the
bottom up to 1 below the trigger.
Case 2b) keystroke came from another trait, not a trigger (e.g. an
action button)
In this case, the traits are executed in the same order as Case 1.

That sounds right.

P.S. �If you reply by clicking on the little icon on the top-right

corner of a post, your replies will be half the size.


I’m not even using the forum.

- M.