- Home /
Multithreaded Input Detection
I'm working on a project that uses a Bluetooth signal sending data on the amount of force detected by a sensor. We're using that to move our character. We pushed all of the reading from the sensor to another thread to significantly cut down on a bottleneck in our code.
An issue came up where if other developers didn't have the sensor attached they wouldn't be able to test their changes to the project. So, I wrote up a mock object that gets used when no sensor is available. The only thing is I'd prefer to be able to use keypresses to simulate different input speeds, without needing the sensor. The only thing is Input.GetKey
can only be called on the main thread. Since this is only used in the editor, and it wouldn't make sense to chanage the ReadData()
interface just for debugging is there anyway to just use plain C# to detect keypresses on other threads?
Everything I've found on it seems to require Windows Forms, and I don't think it's the best idea to add that assembly to the project.
Answer by Bunny83 · Feb 17, 2016 at 02:38 AM
Well, when you are on windows you can always use the win API directly. Either GetKeyState or GetKeyboardState. If you don't know how to use an external native code method, take a look at pinvoke.net(GetKeyState) (GetKeyboardState).
If you are on a different system, i doubt there's a general solution without using Windows Forms of something like that. So for Mac and Linux you have to find equivalent native methods.
@Bunny83 One thing I noticed is that even works outside of the window. Is there another API available for trapping the key to a window?
Well, you can use the OnApplicationFocus callback to set a boolean flag if the application has the focus or not.
Answer by zerophase · Feb 17, 2016 at 03:40 AM
This is the code I ended up using, in case anyone else needs a quick reference.
[DllImport("USER32.dll")]
static extern short GetKeyState(VirtualKeyStates nVirtKey);
public bool IsKeyPressed(VirtualKeyStates testKey)
{
bool keyPressed;
short result = GetKeyState(testKey);
switch (result)
{
case 0:
// Not pressed and not toggled on.
keyPressed = false;
break;
case 1:
// Not pressed, but toggled on
keyPressed = false;
break;
default:
// Pressed (and may be toggled on)
keyPressed = true;
break;
}
return keyPressed;
}
This would do the same ^^:
public bool Is$$anonymous$$eyPressed(Virtual$$anonymous$$eyStates test$$anonymous$$ey)
{
return (Get$$anonymous$$eyState(test$$anonymous$$ey) & 0x8000) != 0;
}
Get$$anonymous$$eyState returns a bitflag where the lowest bit indicates if the key is toggled and the highest bit if the key is currently down.
// 0000 0000 0000 0000 -- a short value has 16 bits
// | |
// | \_____ toggle bit 0x1
// \_______________________ down bit 0x8000
Please help, i need this but "The type or namespace name "Virtual$$anonymous$$eyStates" could not be found. are you missing a assembly refrence?" i don't know which assembly refrence i need, please help :C thanks
If you just read my answer you should find this link. Virtual$$anonymous$$eyStates is just an enum. It's part of the win API but not shipped with .NET so you have to define it yourself.