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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Chikubi

Pages: [1]
1
Feature requests / Use last frame state of keys to extend sf::Input
« on: September 24, 2010, 09:55:20 pm »
What I propose, is to have the ability to get the Event::KeyPressed and Event::KeyReleased out of the sf::Input.

Because sometimes you want to get just the state, and sometimes you want to know if it was just pressed or just released. With this extension I could have all the input-related checks in the same place, and event-specific stuff in another.

This thing worked really well when I was using SDL in my own engine. I coded a little InputManager class to handle that stuff, it was really easy.

After I have switched over to SFML (I liked it a lot and it suited for my needs better than SDL too), I searched for similar feature but never found it, so, naturally, I decided to code it on my own.

I tried to do it the elegant way, by inheriting from sf::Input and sf::RenderWindow, overloading a couple of functions and such, but to my disappointment I found that all members of both of these classes were kept private.

Long story short I just messed with the source code and got it to work this way.

array of bools became array of Uint8 (same in memory afaik anyway)

here are the states I used

Code: [Select]
enum KeyStates{
NOKEY      = 1,
KEYPRESSED = 2,
//modifiers
KEYCHANGED = 4,
KEYDOWN    = KEYPRESSED | KEYCHANGED,
KEYUP      = NOKEY | KEYCHANGED
};


Don't ask me why NOKEY isn't 0 and KEYPRESSED isn't 1 so they could fit in the same bit. This code is a bit old, and I remember when I designed it there was some kind of reason for this but I don't remember it now.

Honestly I don't really care if I gain anything by saving 1 bit :)

The design of the enums doesn't matter anyway. What does matter is the KEYCHANGED bit; it indicates that the state of the key has changed from the last frame.

Finally I can get the info about pressing and releasing of the keys AND their state WITH the modifier keys(shift,alt,ctrl) in one line of code.

Well at the current time it does require one little call from the Window::Display() method so I can flush the KEYCHANGED states, but it works.

So, this topic has actually two feature requests:
  • Extend the Input class
  • Give up the private crap


I mean, what is the point of using OOP in designing a library if the user can't subclass and overload a couple of methods to suit his needs without recompiling everything?

It's either me missing some vital point behind making members private or it's just a thing that was overlooked or something.

Anyway, to keep haters off my tail I want to make one thing clear: I love SFML and I think it is awesome. However if I'm not mistaken, some parts of it could be improved a little.

What I changed to make this work:

I added methods to sf::Input:
Uint8 GetKeyState(Key::Code KeyCode) const;
void FlushKeychangedStates();

This goes in Input::OnEvent:
Code: [Select]
case Event::KeyPressed :
if(myKeys[EventReceived.Key.Code] == NOKEY) {
myKeys[EventReceived.Key.Code] = KEYDOWN;
}
else {
myKeys[EventReceived.Key.Code] = KEYPRESSED;
}
break;

case Event::KeyReleased :
if(myKeys[EventReceived.Key.Code] == KEYPRESSED) {
myKeys[EventReceived.Key.Code] = KEYUP;
}
else {
myKeys[EventReceived.Key.Code] = NOKEY;
}
break;


This in Input::ResetStates
Code: [Select]
for (int i = 0; i < Key::Count; ++i) {
        myKeys[i] = NOKEY;
//myKeysCurrent[i] = NOKEY;
//myKeysLast[i] = NOKEY;
}


and

Code: [Select]
void Input::FlushKeychangedStates()
{
for (int i = 0; i < Key::Count; ++i) {
if(myKeys[i] & KEYPRESSED) {
myKeys[i] = KEYPRESSED;
}
else if(myKeys[i] & NOKEY) {
myKeys[i] = NOKEY;
}
//myKeysCurrent[i] = NOKEY;
//myKeysLast[i] = NOKEY;
}
}


and this goes at the end of Window::Display():
myInput.FlushKeychangedStates();

Now I didn't test this extensively (yet), but it seems like it's working. The same concept however was working really good with SDL.

So, what are your thoughts about this?

BTW, the code is specific to 1.6. I looked in the latest 2.0 but it's almost the same there, private and just the key states.

Also, I implemented this only for keyboard(and mouse, later), because I don't really need that functionality for joystick currently. But it seems pretty simple to do the same for the joystick.

Edit: Didn't seem to notice this thread http://www.sfml-dev.org/forum/viewtopic.php?t=2719 *facepalm*
But... What does it change? The features are so simple to implement and are very useful IMO.

Pages: [1]
anything