Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [COMPLICATED:] Dynamic Input Manager  (Read 4818 times)

0 Members and 1 Guest are viewing this topic.

heishe

  • Full Member
  • ***
  • Posts: 121
    • View Profile
[COMPLICATED:] Dynamic Input Manager
« on: June 28, 2009, 12:32:16 am »
Hi.

I'm writing a class that enables me to let the user decide what buttons he wants to press to access a certain function (basically something that enables the user to configure his keymapping for my games himself).

For obvious reasons, I need to save the configuration to and read it from a file (in my case i'm using xml files + tinyxml).

anyways, the keymapping in my class is saved like this:

Code: [Select]

std::vector<std::pair<std::string,sf::Key::Code>> m_actionlist;


a vector that is full of all the "action" configurations that are read from the config file. for example: one element of that vector could have the name "move player up" as the first member of that pair and sf::Key::Up as the second member (or whatever i write in that config file).

the problem now is, that there is no such thing as pure "numbers" in c++; when I read the corresponding for some action from the config file (for example, sf::Key::Up is something like 297 i think), I can  only read ints or doubles from the file.

now, I don't know how to dynamically assign these "numbers" to my vectors pair second member. something like this will obviously not compile

Code: [Select]

m_actionlist[current_iteration].second = myxmlfile.GetValue("Up")


because the returned value will be double, or int if I static_cast<int> it and the compiler can't convert int or double to sf::Key::Code.

Now, what am I supposed to do now, to avoid having to do something like this for any Code that is in sf::Key::Code and sf::Joy

Code: [Select]

if(myxmlfile.GetValue() == 297)
     m_actionlist[whatever].second = sf::Key::Up
else if(myxmlfile.GetValue() == 298)
     m_actionlist[whatever].second = sf::Key::Right
//And so on


I'm kinda lost here.

By the way to make it easier for anyone that seriously wants to help me (laurent maybe?) i'm posting the current state of the class on pastebin.net: [i'm adding descriptions of my XMLFile and XMLElement classes to the bottom of the paste, to make it easier for you]

http://pastebin.com/m6d494ef3

i'd really appreciate your help.

greetings,
travis

edit: A typical config file would look like this:
Code: [Select]

<action ID=297>Up</action>


This will assign the sf::Key::Up key to the name "Up".

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
[COMPLICATED:] Dynamic Input Manager
« Reply #1 on: June 28, 2009, 10:07:02 am »
Three things about your arch :

first I would use std::map<Key, Action> instead of std::vector<std::pair<Action, Key> > ( BTW there is a white space between two > with templates ) .

second : sf::Key::Code is an enum. So each of its value are int. ( I don't have English tutorial about that. You should find one to get better explanations.  :wink: )

third : why would I chose std::map<Key, Action> and not std::map<Action, Key> ? Because when you get an key event you can do something like :
Code: [Select]
// assume that 'event' is an key event .
Action = m_actionlist[event.Key.Code];
if ( Action == "...") {
 ...
} else if. ...

Or you can use a class Action that is some callback system.
SFML / OS X developer

nitram_cero

  • Full Member
  • ***
  • Posts: 166
    • View Profile
[COMPLICATED:] Dynamic Input Manager
« Reply #2 on: July 06, 2009, 11:20:19 pm »
Quote
because the returned value will be double, or int if I static_cast<int> it and the compiler can't convert int or double to sf::Key::Code.


int-enum cast should work:
Code: [Select]
static_cast<sf::Key::Code>(static_cast<int>(doubleValue))

if not, knowing that an enum is an int, you could call:
Code: [Select]
reinterpret_cast<sf::Key::Code>(static_cast<int>(doubleValue))




I also agree with Hiura on the std::map thingy. It will be exactly the same, but it does the search for you when actually testing against pressed buttons.


Regards
-Martín

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
[COMPLICATED:] Dynamic Input Manager
« Reply #3 on: July 07, 2009, 11:20:11 am »
Quote from: "heishe"
because the returned value will be double, or int if I static_cast<int> it and the compiler can't convert int or double to sf::Key::Code.
Why is there a double? That's weird design. Of course you can do it like nitram_cero, but I'd rather give that some thought again.

Quote from: "nitram_cero"
if not, knowing that an enum is an int, you could call:
Code: [Select]
reinterpret_cast<sf::Key::Code>(static_cast<int>(doubleValue))
No. ;)
reinterpret_cast can only be used for conversions between two pointers or between a pointer and an integral type.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

forrestcupp

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
[COMPLICATED:] Dynamic Input Manager
« Reply #4 on: August 14, 2009, 08:57:14 pm »
I've done a lot since then, so I may be wrong.  But I'm pretty sure I tried something like
Code: [Select]
sf::Key::Code(297)and it worked.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
[COMPLICATED:] Dynamic Input Manager
« Reply #5 on: August 14, 2009, 10:40:11 pm »
Quote from: "forrestcupp"
I've done a lot since then, so I may be wrong.  But I'm pretty sure I tried something like
Code: [Select]
sf::Key::Code(297)and it worked.
Because it's legal. Like
Code: [Select]
int(297)
SFML / OS X developer

forrestcupp

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
[COMPLICATED:] Dynamic Input Manager
« Reply #6 on: August 15, 2009, 10:56:24 pm »
Quote from: "Hiura"
Because it's legal. Like
Code: [Select]
int(297)
Well, that's what I'm saying.  If sf::Key::Code(297) is the up key, why not just do something like:

Code: [Select]
m_actionlist[whatever].second = sf::Key::Code(myxmlfile.GetValue());