From 0c8028c0a8b42e846035bd879a6ae21e0b87bd85 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Wed, 30 May 2018 23:53:56 +0200 Subject: [PATCH] Mono-threading to be compatible with unity --- Program.cs | 12 +-- SpaceNav.cs | 193 +++++++++++++++++------------------- SpaceNavEvent.cs | 17 ++-- spnav-csharp-wrapper.csproj | 2 +- 4 files changed, 110 insertions(+), 114 deletions(-) diff --git a/Program.cs b/Program.cs index 4e58fe1..769c0a0 100644 --- a/Program.cs +++ b/Program.cs @@ -14,7 +14,7 @@ namespace SpaceNavWrapper // var ev = spnavwrapper.SpaceNav.Instance.WaitEvent(100); // Console.WriteLine(ev); //} - SpaceNavDriver navDriver = new SpaceNavDriver(); + SpaceNav navDriver = new SpaceNav(); navDriver.InitDevice(); navDriver.Button += OnButton; navDriver.Motion += OnMotion; @@ -22,10 +22,10 @@ namespace SpaceNavWrapper Console.CancelKeyPress += delegate { navDriver.Dispose(); }; - - for (; ; ) - { - } + for (; ; ) + { + navDriver.WaitEvent(); + } } private static void OnMotion(object sender, MotionEventArgs e) @@ -35,7 +35,7 @@ namespace SpaceNavWrapper private static void OnButton(object sender, EventArgs e) { - Console.WriteLine("Button pressed"); + Console.WriteLine(e); } } } diff --git a/SpaceNav.cs b/SpaceNav.cs index 09f83b6..658d342 100644 --- a/SpaceNav.cs +++ b/SpaceNav.cs @@ -1,110 +1,101 @@ using System; using System.Runtime.InteropServices; -using System.Threading; namespace SpaceNavWrapper { - public class SpaceNavDriver : IDisposable - { + public class SpaceNav : IDisposable + { const string DLL_NAME = "spnavhdi"; - - #region Constants - private const int SPNAV_EVENT_MOTION = 1; - private const int SPNAV_EVENT_BUTTON = 2; - private const ushort SPNAV_VENDOR_ID = 0x046d; - private const ushort SPNAV_PRODUCT_ID = 0x0c627; - #endregion + + #region Constants + private const int SPNAV_EVENT_MOTION = 1; + private const int SPNAV_EVENT_BUTTON = 2; + private const ushort SPNAV_VENDOR_ID = 0x046d; + private const ushort SPNAV_PRODUCT_ID = 0x0c627; + #endregion public event EventHandler Motion; - public event EventHandler Button; - - private Thread eventThread; - private bool deviceReady; - private double _sensitivity = 1.0; - private int _threshold = 5; + public event EventHandler Button; + + private double _sensitivity = 1.0; + private int _threshold = 5; private bool isDisposed; #region Structures private struct SpNavEventMotion - { - public int type; - public int x, y, z; - public int rx, ry, rz; - public uint period; - public IntPtr data; - } + { + public int type; + public int x, y, z; + public int rx, ry, rz; + public uint period; + public IntPtr data; + } - private struct SpNavEventButton - { - public int type; - public int press; - public int bnum; - } + private struct SpNavEventButton + { + public int type; + [MarshalAs(UnmanagedType.Bool)] + public bool press; + public int bnum; + } - [StructLayout(LayoutKind.Explicit)] - private struct SpNavEvent - { - [FieldOffset(0)] public int type; - [FieldOffset(0)] public SpNavEventMotion motion; - [FieldOffset(0)] public SpNavEventButton button; - } - #endregion - - #region DLL Imports - [DllImport(DLL_NAME)] - private static extern int spnav_open(ushort vendor_id, ushort product_id); - [DllImport(DLL_NAME)] - private static extern int spnav_close(); - [DllImport(DLL_NAME)] - private static extern int spnav_wait_event(ref SpNavEvent ev); - [DllImport(DLL_NAME)] - private static extern int spnav_wait_event_timeout(ref SpNavEvent ev, int timeout); - [DllImport(DLL_NAME)] - private static extern int spnav_sensitivity(double sens); - [DllImport(DLL_NAME)] - private static extern int spnav_deadzone(int threshold); - #endregion - - public SpaceNavDriver() - { - eventThread = new Thread(HandleEvents) - { - IsBackground = true, - Name = "3Dconnexion-Event-Dispatcher" - }; - eventThread.Start(); - } - - public void InitDevice() - { + [StructLayout(LayoutKind.Explicit)] + private struct SpNavEvent + { + [FieldOffset(0)] public int type; + [FieldOffset(0)] public SpNavEventMotion motion; + [FieldOffset(0)] public SpNavEventButton button; + } + #endregion + + #region DLL Imports + [DllImport(DLL_NAME)] + private static extern int spnav_open(ushort vendor_id, ushort product_id); + [DllImport(DLL_NAME)] + private static extern int spnav_close(); + [DllImport(DLL_NAME)] + private static extern int spnav_wait_event(ref SpNavEvent ev); + [DllImport(DLL_NAME)] + private static extern int spnav_wait_event_timeout(ref SpNavEvent ev, int timeout); + [DllImport(DLL_NAME)] + private static extern int spnav_sensitivity(double sens); + [DllImport(DLL_NAME)] + private static extern int spnav_deadzone(int threshold); + #endregion + + public void InitDevice() + { + // TODO handle retcode and errors spnav_open(SPNAV_VENDOR_ID, SPNAV_PRODUCT_ID); - spnav_deadzone(5); - deviceReady = true; - } + } - private void HandleEvents(object obj) - { - // Block while the device isn't ready - while (!deviceReady) {} - Console.WriteLine("Device ready !"); - while (!isDisposed) - { - SpNavEvent sev = new SpNavEvent(); - int ev_type = spnav_wait_event(ref sev); - Console.WriteLine("Event type : {0}", sev.type); - switch (ev_type) - { - case SPNAV_EVENT_BUTTON: - //return new SpaceNavButtonEvent(Convert.ToBoolean(sev.button.press), sev.button.bnum); - Button(this, new EventArgs()); - break; - case SPNAV_EVENT_MOTION: - var ev = sev.motion; - Motion(this, new MotionEventArgs(ev.x, ev.y, ev.z, ev.rx, ev.ry, ev.rz)); - break; - } - } + public void WaitEvent(int millis = -1) + { + SpNavEvent sev = new SpNavEvent(); + int ev_type; + if (millis == -1) + { + ev_type = spnav_wait_event(ref sev); + } + else + { + ev_type = spnav_wait_event_timeout(ref sev, (int)millis); + } + + switch (ev_type) + { + case SPNAV_EVENT_BUTTON: + var e = sev.button; + Button(this, new ButtonEventArgs(e.press, e.bnum)); + break; + case SPNAV_EVENT_MOTION: + var ev = sev.motion; + Motion(this, new MotionEventArgs(ev.x, ev.y, ev.z, ev.rx, ev.ry, ev.rz)); + break; + default: + break; + } } public double Sensitivity @@ -126,17 +117,17 @@ namespace SpaceNavWrapper spnav_deadzone(value); } } - - public void Dispose() - { - if (!isDisposed) - { - CloseDevice(); - Button = null; - Motion = null; - } - isDisposed = true; - } + + public void Dispose() + { + if (!isDisposed) + { + CloseDevice(); + Button = null; + Motion = null; + } + isDisposed = true; + } private void CloseDevice() { diff --git a/SpaceNavEvent.cs b/SpaceNavEvent.cs index fd3ec4b..bfb7515 100644 --- a/SpaceNavEvent.cs +++ b/SpaceNavEvent.cs @@ -25,13 +25,18 @@ namespace SpaceNavWrapper } public class ButtonEventArgs : EventArgs - { - public readonly int button; - public readonly bool pressed; + { + public readonly bool Pressed; + public readonly int Button; - public override string ToString() + public ButtonEventArgs(bool pressed, int button) { - return string.Format("[ButtonEventArgs: button={0}, pressed={1}]", button, pressed); + Pressed = pressed; + Button = button; } - } + public override string ToString() + { + return string.Format("[ButtonEventArgs: button={0}, pressed={1}]", Button, Pressed); + } + } } diff --git a/spnav-csharp-wrapper.csproj b/spnav-csharp-wrapper.csproj index ae1abf0..bd3a22b 100644 --- a/spnav-csharp-wrapper.csproj +++ b/spnav-csharp-wrapper.csproj @@ -27,9 +27,9 @@ x86 - + \ No newline at end of file