Make WiiMote consume less resources (do not run thread if not required)
This commit is contained in:
1 parent
44dceaed60
commit
668d72d3a7
3 files changed
+68
-124
No files matched your search
@@ -161,25 +161,25 @@ namespace Vocaluxe.Lib.Input
|
|||||||
public static int ReadTimeout(IntPtr device, ref byte[] data, int length, int milliseconds)
|
public static int ReadTimeout(IntPtr device, ref byte[] data, int length, int milliseconds)
|
||||||
{
|
{
|
||||||
IntPtr dataPtr = Marshal.AllocHGlobal(length);
|
IntPtr dataPtr = Marshal.AllocHGlobal(length);
|
||||||
int result;
|
int bytesRead;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = hid_read_timeout(device, dataPtr, length, milliseconds);
|
bytesRead = hid_read_timeout(device, dataPtr, length, milliseconds);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
result = -1;
|
bytesRead = -1;
|
||||||
CLog.LogError("Error CHIDAPI.ReadTimeout(): " + e);
|
CLog.LogError("Error CHIDAPI.ReadTimeout(): " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != -1)
|
if (bytesRead != -1)
|
||||||
Marshal.Copy(dataPtr, data, 0, result);
|
Marshal.Copy(dataPtr, data, 0, bytesRead);
|
||||||
else
|
else
|
||||||
data = null;
|
data = null;
|
||||||
|
|
||||||
Marshal.FreeHGlobal(dataPtr);
|
Marshal.FreeHGlobal(dataPtr);
|
||||||
|
|
||||||
return result;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(_HIDApiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_read", CharSet = CharSet.Unicode)]
|
[DllImport(_HIDApiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_read", CharSet = CharSet.Unicode)]
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ using VocaluxeLib;
|
|||||||
|
|
||||||
namespace Vocaluxe.Lib.Input.WiiMote
|
namespace Vocaluxe.Lib.Input.WiiMote
|
||||||
{
|
{
|
||||||
class CWiiMote : IController, IDisposable
|
class CWiiMote : IController
|
||||||
{
|
{
|
||||||
private CWiiMoteLib _WiiMote;
|
private CWiiMoteLib _WiiMote;
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
|||||||
_RumbleTimer = new CRumbleTimer();
|
_RumbleTimer = new CRumbleTimer();
|
||||||
_Gesture = new CGesture();
|
_Gesture = new CGesture();
|
||||||
|
|
||||||
_HandlerThread = new Thread(_MainLoop) {Priority = ThreadPriority.BelowNormal};
|
_HandlerThread = new Thread(_MainLoop) {Name = "WiiMote", Priority = ThreadPriority.BelowNormal};
|
||||||
|
|
||||||
_KeysPool = new List<SKeyEvent>();
|
_KeysPool = new List<SKeyEvent>();
|
||||||
_CurrentKeysPool = new List<SKeyEvent>();
|
_CurrentKeysPool = new List<SKeyEvent>();
|
||||||
@@ -151,8 +151,7 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
|||||||
|
|
||||||
if (startRumble)
|
if (startRumble)
|
||||||
_WiiMote.SetRumble(true);
|
_WiiMote.SetRumble(true);
|
||||||
|
else if (stopRumble)
|
||||||
if (stopRumble)
|
|
||||||
_WiiMote.SetRumble(false);
|
_WiiMote.SetRumble(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,15 +313,5 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
|||||||
_MousePool.Clear();
|
_MousePool.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_WiiMote != null)
|
|
||||||
{
|
|
||||||
_WiiMote.Dispose();
|
|
||||||
_WiiMote = null;
|
|
||||||
}
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
|||||||
}
|
}
|
||||||
#endregion Events
|
#endregion Events
|
||||||
|
|
||||||
public sealed class CWiiMoteLib : IDisposable
|
public sealed class CWiiMoteLib
|
||||||
{
|
{
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
private const ushort _VID = 0x057e;
|
private const ushort _VID = 0x057e;
|
||||||
@@ -178,8 +178,7 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
|||||||
private int _Address;
|
private int _Address;
|
||||||
private short _Size;
|
private short _Size;
|
||||||
|
|
||||||
private readonly Thread _Reader;
|
private Thread _Reader;
|
||||||
private bool _Active;
|
|
||||||
private readonly bool _Error;
|
private readonly bool _Error;
|
||||||
|
|
||||||
public bool Connected { get; private set; }
|
public bool Connected { get; private set; }
|
||||||
@@ -191,72 +190,63 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
|||||||
#region Interface
|
#region Interface
|
||||||
public CWiiMoteLib()
|
public CWiiMoteLib()
|
||||||
{
|
{
|
||||||
Connected = false;
|
|
||||||
_Active = true;
|
|
||||||
_Error = false;
|
|
||||||
_Reader = new Thread(_ReaderLoop);
|
|
||||||
_Reader.Start();
|
|
||||||
|
|
||||||
if (!CHIDApi.Init())
|
if (!CHIDApi.Init())
|
||||||
{
|
{
|
||||||
CLog.LogError("WiiMoteLib: Can't initialize HID API");
|
CLog.LogError("WiiMoteLib: Can't initialize HID API");
|
||||||
const string msg = "Please install the Visual C++ Redistributable Packages 2008!";
|
CLog.LogError("Please install the Visual C++ Redistributable Packages 2008!");
|
||||||
CLog.LogError(msg);
|
|
||||||
|
|
||||||
_Active = false;
|
|
||||||
_Error = true;
|
_Error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~CWiiMoteLib()
|
~CWiiMoteLib()
|
||||||
{
|
{
|
||||||
Dispose(false);
|
Disconnect();
|
||||||
|
//Wait for thread to finish (if any)
|
||||||
|
_WaitForReader();
|
||||||
|
CHIDApi.Exit();
|
||||||
|
_ReadDone.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _TryConnect(ushort pid)
|
private void _StartReader()
|
||||||
{
|
{
|
||||||
bool connected = CHIDApi.Open(_VID, pid, out _Handle);
|
_Reader = new Thread(_ReaderLoop) {Name = "WiiMoteLib"};
|
||||||
if (connected)
|
_Reader.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _WaitForReader()
|
||||||
|
{
|
||||||
|
if (_Reader == null)
|
||||||
|
return;
|
||||||
|
_Reader.Join();
|
||||||
|
_Reader = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _TryConnect(ushort pid)
|
||||||
|
{
|
||||||
|
//We might have had a reader thread, that is not finished yet, so let it finish and close it's handle first or it will close the new one
|
||||||
|
_WaitForReader();
|
||||||
|
Connected = CHIDApi.Open(_VID, pid, out _Handle);
|
||||||
|
if (Connected)
|
||||||
{
|
{
|
||||||
connected = _ReadCalibration();
|
_StartReader();
|
||||||
if (!connected)
|
if (!_ReadCalibration())
|
||||||
CHIDApi.Close(_Handle);
|
Connected = false;
|
||||||
}
|
}
|
||||||
return connected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Connect()
|
public bool Connect()
|
||||||
{
|
{
|
||||||
Connected = false;
|
if (Connected)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (_Error)
|
if (_Error)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Try WiiMotion
|
_TryConnect(_PID); //Try WiiMotion
|
||||||
Connected = CHIDApi.Open(_VID, _PID, out _Handle);
|
|
||||||
if (Connected)
|
|
||||||
{
|
|
||||||
Connected = _ReadCalibration();
|
|
||||||
if (!Connected)
|
|
||||||
CHIDApi.Close(_Handle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CHIDApi.Close(_Handle);
|
|
||||||
|
|
||||||
if (Connected)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
//Try WiiMotion Plus
|
|
||||||
Connected = CHIDApi.Open(_VID, _PIDPlus, out _Handle);
|
|
||||||
if (Connected)
|
|
||||||
{
|
|
||||||
Connected = _ReadCalibration();
|
|
||||||
if (!Connected)
|
|
||||||
CHIDApi.Close(_Handle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CHIDApi.Close(_Handle);
|
|
||||||
|
|
||||||
|
if (!Connected)
|
||||||
|
_TryConnect(_PIDPlus); //Try WiiMotion Plus
|
||||||
|
|
||||||
return Connected;
|
return Connected;
|
||||||
}
|
}
|
||||||
@@ -264,8 +254,6 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
|||||||
public void Disconnect()
|
public void Disconnect()
|
||||||
{
|
{
|
||||||
Connected = false;
|
Connected = false;
|
||||||
_Active = false;
|
|
||||||
CHIDApi.Exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetReportType(EInputReport type, EIRSensitivity irSensitivity, bool continuous)
|
public void SetReportType(EInputReport type, EIRSensitivity irSensitivity, bool continuous)
|
||||||
@@ -328,68 +316,54 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
|||||||
#region Private stuff
|
#region Private stuff
|
||||||
private void _ReaderLoop()
|
private void _ReaderLoop()
|
||||||
{
|
{
|
||||||
while (_Active)
|
var buff = new byte[_ReportLength];
|
||||||
|
while (Connected)
|
||||||
{
|
{
|
||||||
Thread.Sleep(5);
|
int bytesRead;
|
||||||
|
try
|
||||||
if (_Handle != IntPtr.Zero && Connected)
|
|
||||||
{
|
{
|
||||||
var buff = new byte[_ReportLength];
|
bytesRead = CHIDApi.ReadTimeout(_Handle, ref buff, _ReportLength, 400);
|
||||||
|
if (bytesRead == -1)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
CHIDApi.ReadTimeout(_Handle, ref buff, _ReportLength, 200);
|
Connected = false; //Disconnected
|
||||||
}
|
break;
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
CLog.LogError("(WiiMoteLib) Error reading from device: " + e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_ParseInputReport(buff))
|
|
||||||
{
|
|
||||||
if (WiiMoteChanged != null)
|
|
||||||
WiiMoteChanged(this, new CWiiMoteChangedEventArgs(_WiiMoteState));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
CLog.LogError("(WiiMoteLib) Error reading from device: " + e);
|
||||||
|
Connected = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytesRead > 0 && _ParseInputReport(buff))
|
||||||
|
{
|
||||||
|
if (WiiMoteChanged != null)
|
||||||
|
WiiMoteChanged(this, new CWiiMoteChangedEventArgs(_WiiMoteState));
|
||||||
|
}
|
||||||
|
Thread.Sleep(5);
|
||||||
}
|
}
|
||||||
|
CHIDApi.Close(_Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _ParseInputReport(byte[] buff)
|
private bool _ParseInputReport(byte[] buff)
|
||||||
{
|
{
|
||||||
if (buff == null)
|
|
||||||
{
|
|
||||||
Connected = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var type = (EInputReport)buff[0];
|
var type = (EInputReport)buff[0];
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case EInputReport.Buttons:
|
case EInputReport.Buttons:
|
||||||
_ParseButtons(buff);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EInputReport.ButtonsAccel:
|
|
||||||
_ParseButtons(buff);
|
|
||||||
_ParseAccel(buff);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EInputReport.IRAccel:
|
|
||||||
_ParseButtons(buff);
|
|
||||||
_ParseAccel(buff);
|
|
||||||
_ParseIR(buff);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EInputReport.ButtonsExtension:
|
case EInputReport.ButtonsExtension:
|
||||||
_ParseButtons(buff);
|
_ParseButtons(buff);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EInputReport.ButtonsAccel:
|
||||||
case EInputReport.ExtensionAccel:
|
case EInputReport.ExtensionAccel:
|
||||||
_ParseButtons(buff);
|
_ParseButtons(buff);
|
||||||
_ParseAccel(buff);
|
_ParseAccel(buff);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EInputReport.IRAccel:
|
||||||
case EInputReport.IRExtensionAccel:
|
case EInputReport.IRExtensionAccel:
|
||||||
_ParseButtons(buff);
|
_ParseButtons(buff);
|
||||||
_ParseAccel(buff);
|
_ParseAccel(buff);
|
||||||
@@ -693,24 +667,5 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
|||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
#endregion Private stuff
|
#endregion Private stuff
|
||||||
|
|
||||||
#region IDisposable Members
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReSharper disable InconsistentNaming
|
|
||||||
private void Dispose(bool disposing)
|
|
||||||
// ReSharper restore InconsistentNaming
|
|
||||||
{
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
Disconnect();
|
|
||||||
_ReadDone.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user