iliak's picture

[Input] : Detect a new keypress and a constant key press

Project:The Open Toolkit library
Version:all versions
Component:Code
Category:support request
Priority:normal
Assigned:Unassigned
Status:by design
Description

It's a nice (not to say important feature) to detect the difference between a new key press (just pressed key) and a constant key press (key down for several frames) events. You can have a look here to know how I handle the case. The main idea is to poll keyboard state at each frame and store the previous / current states in an array. To detect a constant key press, both value in the array are true, and to detect a new keypress, only the current array is true, and the previous is false.

You can extented this technique for more input device (mouse and gamepad).


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

#1

Status:open» by design

This has been requested a few times in the past. The situation is as follows:

  • The event-based interface in NativeWindow already supports this: you only get a KeyDown/KeyUp event on a "fresh" press/release of a key (unless you set KeyRepeat to true, where holding a key down will generate KeyDown+KeyUp events continuously).
  • However, the polled interface will not support this feature. The reason is that it introduces all kinds of concurrency issues:
    1. Thread 1 calls GetKeyState
    2. Thread 2 calls GetKeyState
    3. Thread 1 calls GetKeyState and receives garbage

The solution is trivial: have the user compare states and find their differences:

using OpenTK.Input;
...
KeyboardState previous_state, current_state;
...
previous_state = current_state;
current_state = Keyboard.GetState();
for (int i = 0; i < (int)Key.Last; i++)
{
    Key key = (Key)i;
    bool current = current_state.IsKeyDown(key);
    bool previous = previous_state.IsKeyDown(key);
    if (current && !previous)
        NewKeyDownDetected(key);
    else if (!current && previous)
        NewKeyUpDetected(key);
    else
        // Whatever
}

I was thinking about reusing the event-based interface (KeyboardDevice) to simplify this process, but I don't think I can implement this in time for OpenTK 1.0.