Game Development Community

Actionmap.push()

by Interface · in Torque Game Engine · 03/26/2007 (10:51 pm) · 8 replies

Looks like the push() and pop() on an actionmap instance are not what i expected.

I have possibly multiple calls to push(), but it takes only one pop() to get the actionmap out. I know it sounds silly to be doing push() for the same actionmap more than once, but i'm fiddling with GUI controls to add some standard key combinations to certain controls. It works fine when there's only one.

So basically

myActionMap.push();
myActionMap.push();
myActionMap.pop();
// myActionMap not active anymore
myActionMap.pop(); // useless

Any ideas? I hate using "workarounds" like keeping a counter or something.

Can anyone explain if i'm missing something about this "stack" feature that doesn't seem to "stack"?

What if i do:

myActionMap.push();
mySecondActionMap.push();
myActionMap.push();
mySecondActionMap.push();
myActionMap.pop();
mySecondActionMap.pop();
// now what is active? myActionMap?

I gotta try that one tomorrow.

#1
03/26/2007 (11:14 pm)
You've lost me???

This is how it works and it does work:

// Assuming actionMap1 is currently active
   actionMap1.pop();
   actionMap2.push();
   // Now actionMap 2 is active
   
   // Assuming actionMap2 is currently active
   actionMap2.pop();
   actionMap1.push();
   // Now actionMap 1 is active

Make sure you pop the current actionMap before pushing a new one.
#2
03/27/2007 (8:59 am)
The standard moveMap would be in effect. I want to keep it that way, just override a particular key. So i have actionMap1 that just has that particular key.

When the pushdialog is executed, i push() that actionMap1, effectively overriding a couple of keys. Works perfectly. When the popdialog is executed, i pop() that actionMap1, getting rid of the key overrides. Works perfectly.

Let's say you're in-game and press the standard ctrl+o in start.fps. This will bring up the options dialog. All is well, key overrides work. When you cancel the options dialog, your keys are back to the original mappings.

Now, let's say you press ctrl+o, get the options dialog. This pushes actionMap1. Then, you press tilde (~) to get the console. It pushes actionMap1 again. Now, when you cancel the console, actionMap1 is pop()'ed. And your options dialog is left without the actionMap1 key bindings.

I had expected push() and pop() to work as a stack, but looks like i doesn't.
#3
03/27/2007 (9:29 am)
No, it doesn't work like a stack... however, if you truly desire that functionality, your best bet would be to just keep track of it yourself... an array, $moveMaps[index], and just keep adding to the end, or pulling from the end, and using a function to figure out what's what, not that I know a really good reason to do this, in f act, I can't think of even a bad reason as to why you'd want to do it, but good luck none-the-less.
#4
03/27/2007 (9:48 am)
Ok, I figured i'd have to keep track of it myself somehow.

The reason i'm doing this is making the gui more useable. I want to move this stuff down to the engine at some point, so maybe i should be looking into that right now already. Adding key behaviours is part of the gui enhancement i'm doing. Right now, i'm just experimenting with the escape key, so you can cancel dialogs with escape (without having to put code on every frikking dialog control).
#5
03/27/2007 (10:16 am)
Interface I think there's definitely better ways of doing what you're trying to do.

for instance, if you just want to override a few keys, then rather than pusing a movemap you're probably better off just overriding the functions for those keys using a package. so for the esc key, you may have a function bound to it called "onEsc()". you could activate a package either when a particular dialog is pushed, or if *any* dialog is pushed which would override onEsc() and change what it does. when the dialog is popped, the package would be deactivated and onEsc() would go back to it's original function.

for what you're doing, youll probably want to call your functionality when a particular dialog is pushed and popped. instead of putting it in guicontrol::onwake(), you would put it in specialGuiName::onWake() and specialGuiName::onSleep(), where specialGuiName is the name of the gui you want the overrides to occur in.
#6
03/27/2007 (10:37 am)
No that's the point. I don't want to be coding for every dialog again. So i put it up a higher level. So instead of doing it in onwakes etc i'm just putting it way up there on the canvas level (pushdialog/popdialog). Hah!

I'm not sure but isn't the package override going to have the same problem? When there's multiple dialogs, the package isn't really a stack so deactivating the package on the top level dialog will deactivate it for the dialog underneath it too?

edit: i like the package idea tho. And depending on how much gui enhancements i end up with i may just make special controls for them, but then still the push/pop problem exists. I'll just have to keep a list myself.
#7
03/27/2007 (5:46 pm)
Why don't you just unbind and bind the keys that you need?

Example:
// unbind "k" from whatever function it's assigned to
   moveMap.unbind(keyboard, k);

   // bind "k" to kill function
   moveMap.bind(keyboard, k, killPlayer);

You're probably better doing something along these lines for bulk changes to key bindings, possibly with an array.

%action   = "k";
   %function = "kill";

   redoMapping(%action, %function);

function redoMapping(%action, %function)
{
   moveMap.unbind(keyboard, %action);
   moveMap.bind(keyboard, %action, %function);
}
#8
03/27/2007 (7:09 pm)
Hmm, another interesting suggestion. This will need to keep a list of the original bindings, since they may potentially be player defined bindings, and i need to be able to restore them.

I'm just a nut for generic code and reuseability (read: i'm an asshole). I don't like much of the standard start.fps code, so bit by bit stuff gets thrown out and replaced. And then I get into these kind of questions... :)