This will probably sound strange for some of you, but I can not figure out right way to read joystick input without blocking my UI form. I have found this example on internet:
static void Main()
{
// Initialize DirectInput
var directInput = new DirectInput();
// Find a Joystick Guid
var joystickGuid = Guid.Empty;
foreach (var deviceInstance in directInput.GetDevices(DeviceType.Gamepad,
DeviceEnumerationFlags.AllDevices))
joystickGuid = deviceInstance.InstanceGuid;
// If Gamepad not found, look for a Joystick
if (joystickGuid == Guid.Empty)
foreach (var deviceInstance in directInput.GetDevices(DeviceType.Joystick,
DeviceEnumerationFlags.AllDevices))
joystickGuid = deviceInstance.InstanceGuid;
// If Joystick not found, throws an error
if (joystickGuid == Guid.Empty)
{
Console.WriteLine("No joystick/Gamepad found.");
Console.ReadKey();
Environment.Exit(1);
}
// Instantiate the joystick
var joystick = new Joystick(directInput, joystickGuid);
Console.WriteLine("Found Joystick/Gamepad with GUID: {0}", joystickGuid);
//Query all suported ForceFeedback effects
var allEffects = joystick.GetEffects();
foreach (var effectInfo in allEffects)
Console.WriteLine("Effect available {0}", effectInfo.Name);
//Set BufferSize in order to use buffered data.
joystick.Properties.BufferSize = 128;
// Acquire the joystick
joystick.Acquire();
// Poll events from joystick
while (true)
{
joystick.Poll();
var datas = joystick.GetBufferedData();
foreach (var state in datas)
Console.WriteLine(state);
}
}
I have installed sharpdx and I can see joystick axis output in console.
Now I want to display each axis data in separate textbox on my UI. So I changed few lines of code:
joystick.Poll();
var data = joystick.GetBufferedData();
foreach (var state in data)
{
if (state.Offset == JoystickOffset.X)
{
textBox1.Text = state.Value.ToString();
}
}
So this should pass data to textbox. If I write here Console.Writeline(state.Value)
I will get data I want to display. Problem is, that this while loop
blocks UI.
I would like to put this while loop in private void timer_tick
and set maybe 10 milliseconds refresh rate. But I don't know how to access variables like var joystick
in separate function. I have also read that this can be done with asynchronous programming. Sadly I am stuck now.
Can anybody help me with as simple solution as possible to this problem? Code example would be great.
Suppose you code with WinForm (deduced from
blocking my UI form
in your question).Add a timer to your Form from the designer.
And add these lines in the Form's .ctor:
Explanations:
A refreshing rate of 100 times per second is unnecessarily fast, remember the refreshing rate of most monitors is about 60 Hz. I set it as 100 ms (10 refreshes per second), which is acceptable.
Using lambda expression, you have access to the variables like
var joystick
from the timer's tick handler.In each freshing, only the last state in the data is displayed to the
TextBox
.