Rewrite event system using delegates and threads
This commit is contained in:
parent
b48f5b33ad
commit
d98210a403
35
Program.cs
35
Program.cs
@ -1,20 +1,41 @@
|
|||||||
using System;
|
using System;
|
||||||
using spnavwrapper;
|
|
||||||
|
|
||||||
namespace spnavcsharpwrapper
|
namespace SpaceNavWrapper
|
||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
SpaceNav.Instance.Threshold = 5;
|
//spnavwrapper.SpaceNav.Instance.Threshold = 5;
|
||||||
SpaceNav.Instance.Sensitivity = 0.1;
|
//spnavwrapper.SpaceNav.Instance.Sensitivity = 0.1;
|
||||||
|
|
||||||
|
//for (; ; )
|
||||||
|
//{
|
||||||
|
// var ev = spnavwrapper.SpaceNav.Instance.WaitEvent(100);
|
||||||
|
// Console.WriteLine(ev);
|
||||||
|
//}
|
||||||
|
SpaceNavDriver navDriver = new SpaceNavDriver();
|
||||||
|
navDriver.InitDevice();
|
||||||
|
navDriver.Button += OnButton;
|
||||||
|
navDriver.Motion += OnMotion;
|
||||||
|
|
||||||
|
Console.CancelKeyPress += delegate {
|
||||||
|
navDriver.Dispose();
|
||||||
|
};
|
||||||
|
|
||||||
for (; ; )
|
for (; ; )
|
||||||
{
|
{
|
||||||
var ev = SpaceNav.Instance.WaitEvent(100);
|
}
|
||||||
Console.WriteLine(ev);
|
}
|
||||||
}
|
|
||||||
|
private static void OnMotion(object sender, MotionEventArgs e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnButton(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Button pressed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
143
SpaceNav.cs
143
SpaceNav.cs
@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace spnavwrapper
|
namespace SpaceNavWrapper
|
||||||
{
|
{
|
||||||
public sealed class SpaceNav : IDisposable
|
public class SpaceNavDriver : IDisposable
|
||||||
{
|
{
|
||||||
|
|
||||||
const string DLL_NAME = "spnavhdi";
|
const string DLL_NAME = "spnavhdi";
|
||||||
|
|
||||||
#region Constants
|
#region Constants
|
||||||
@ -14,9 +16,14 @@ namespace spnavwrapper
|
|||||||
private const ushort SPNAV_PRODUCT_ID = 0x0c627;
|
private const ushort SPNAV_PRODUCT_ID = 0x0c627;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public event EventHandler<MotionEventArgs> Motion;
|
||||||
|
public event EventHandler<EventArgs> Button;
|
||||||
|
|
||||||
|
private Thread eventThread;
|
||||||
|
private bool deviceReady;
|
||||||
private double _sensitivity = 1.0;
|
private double _sensitivity = 1.0;
|
||||||
private int _threshold = 5;
|
private int _threshold = 5;
|
||||||
private static SpaceNav instance;
|
private bool isDisposed;
|
||||||
|
|
||||||
#region Structures
|
#region Structures
|
||||||
private struct SpNavEventMotion
|
private struct SpNavEventMotion
|
||||||
@ -59,118 +66,82 @@ namespace spnavwrapper
|
|||||||
private static extern int spnav_deadzone(int threshold);
|
private static extern int spnav_deadzone(int threshold);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private SpaceNav()
|
public SpaceNavDriver()
|
||||||
|
{
|
||||||
|
eventThread = new Thread(HandleEvents)
|
||||||
|
{
|
||||||
|
IsBackground = true,
|
||||||
|
Name = "3Dconnexion-Event-Dispatcher"
|
||||||
|
};
|
||||||
|
eventThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitDevice()
|
||||||
{
|
{
|
||||||
// TODO : handle retcode
|
|
||||||
spnav_open(SPNAV_VENDOR_ID, SPNAV_PRODUCT_ID);
|
spnav_open(SPNAV_VENDOR_ID, SPNAV_PRODUCT_ID);
|
||||||
|
spnav_deadzone(5);
|
||||||
|
deviceReady = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IDisposable Support
|
private void HandleEvents(object obj)
|
||||||
private bool disposedValue = false; // To detect redundant calls
|
|
||||||
|
|
||||||
private void Dispose(bool disposing)
|
|
||||||
{
|
{
|
||||||
if (!disposedValue)
|
// Block while the device isn't ready
|
||||||
{
|
while (!deviceReady) {}
|
||||||
// Free unmanaged resources
|
Console.WriteLine("Device ready !");
|
||||||
spnav_close();
|
while (!isDisposed)
|
||||||
disposedValue = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~SpaceNav()
|
|
||||||
{
|
|
||||||
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This code added to correctly implement the disposable pattern.
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public static SpaceNav Instance
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (instance == null)
|
|
||||||
{
|
|
||||||
instance = new SpaceNav();
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CloseDevice()
|
|
||||||
{
|
|
||||||
spnav_close();
|
|
||||||
instance = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SpaceNavEvent WaitEvent()
|
|
||||||
{
|
{
|
||||||
SpNavEvent sev = new SpNavEvent();
|
SpNavEvent sev = new SpNavEvent();
|
||||||
spnav_wait_event(ref sev);
|
int ev_type = spnav_wait_event(ref sev);
|
||||||
switch (sev.type)
|
Console.WriteLine("Event type : {0}", sev.type);
|
||||||
{
|
|
||||||
case SPNAV_EVENT_BUTTON:
|
|
||||||
return new SpaceNavButtonEvent(Convert.ToBoolean(sev.button.press), sev.button.bnum);
|
|
||||||
case SPNAV_EVENT_MOTION:
|
|
||||||
var ev = sev.motion;
|
|
||||||
return new SpaceNavMotionEvent(ev.x, ev.y, ev.z, ev.rx, ev.ry, ev.rz);
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SpaceNavEvent WaitEvent(int milliseconds)
|
|
||||||
{
|
|
||||||
SpNavEvent sev = new SpNavEvent();
|
|
||||||
int ev_type = spnav_wait_event_timeout(ref sev, milliseconds);
|
|
||||||
switch (ev_type)
|
switch (ev_type)
|
||||||
{
|
{
|
||||||
case SPNAV_EVENT_BUTTON:
|
case SPNAV_EVENT_BUTTON:
|
||||||
return new SpaceNavButtonEvent(Convert.ToBoolean(sev.button.press), sev.button.bnum);
|
//return new SpaceNavButtonEvent(Convert.ToBoolean(sev.button.press), sev.button.bnum);
|
||||||
|
Button(this, new EventArgs());
|
||||||
|
break;
|
||||||
case SPNAV_EVENT_MOTION:
|
case SPNAV_EVENT_MOTION:
|
||||||
var ev = sev.motion;
|
var ev = sev.motion;
|
||||||
return new SpaceNavMotionEvent(ev.x, ev.y, ev.z, ev.rx, ev.ry, ev.rz);
|
Motion(this, new MotionEventArgs(ev.x, ev.y, ev.z, ev.rx, ev.ry, ev.rz));
|
||||||
default:
|
break;
|
||||||
return null;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double Sensitivity
|
public double Sensitivity
|
||||||
{
|
{
|
||||||
get
|
get => _sensitivity;
|
||||||
{
|
|
||||||
return _sensitivity;
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
// TODO : handle retcode
|
|
||||||
spnav_sensitivity(value);
|
|
||||||
_sensitivity = value;
|
_sensitivity = value;
|
||||||
|
spnav_sensitivity(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Threshold
|
public int Threshold
|
||||||
{
|
{
|
||||||
get
|
get => _threshold;
|
||||||
{
|
|
||||||
return _threshold;
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
// TODO : handle retcode
|
|
||||||
spnav_deadzone(value);
|
|
||||||
_threshold = value;
|
_threshold = value;
|
||||||
|
spnav_deadzone(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (!isDisposed)
|
||||||
|
{
|
||||||
|
CloseDevice();
|
||||||
|
Button = null;
|
||||||
|
Motion = null;
|
||||||
|
}
|
||||||
|
isDisposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseDevice()
|
||||||
|
{
|
||||||
|
// TODO : handle retcode and errors
|
||||||
|
spnav_close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,13 @@
|
|||||||
namespace spnavwrapper
|
using System;
|
||||||
{
|
|
||||||
public abstract class SpaceNavEvent
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SpaceNavButtonEvent : SpaceNavEvent
|
namespace SpaceNavWrapper
|
||||||
{
|
{
|
||||||
public bool Pressed { get; }
|
public class MotionEventArgs : EventArgs
|
||||||
public int Button { get; }
|
|
||||||
|
|
||||||
public SpaceNavButtonEvent(bool pressed, int button)
|
|
||||||
{
|
{
|
||||||
Pressed = pressed;
|
public readonly int X, Y, Z;
|
||||||
Button = button;
|
public readonly int Rx, Ry, Rz;
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
public MotionEventArgs(int x, int y, int z, int rx, int ry, int rz)
|
||||||
{
|
|
||||||
return "pressed=" + Pressed + " button=" + Button;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SpaceNavMotionEvent : SpaceNavEvent
|
|
||||||
{
|
|
||||||
public int X { get; }
|
|
||||||
public int Y { get; }
|
|
||||||
public int Z { get; }
|
|
||||||
public int Rx { get; }
|
|
||||||
public int Ry { get; }
|
|
||||||
public int Rz { get; }
|
|
||||||
|
|
||||||
public SpaceNavMotionEvent(int x, int y, int z, int rx, int ry, int rz)
|
|
||||||
{
|
{
|
||||||
X = x;
|
X = x;
|
||||||
Y = y;
|
Y = y;
|
||||||
@ -46,4 +23,15 @@
|
|||||||
" rx=" + Rz + " ry=" + Ry + " rz=" + Rz;
|
" rx=" + Rz + " ry=" + Ry + " rz=" + Rz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ButtonEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public readonly int button;
|
||||||
|
public readonly bool pressed;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("[ButtonEventArgs: button={0}, pressed={1}]", button, pressed);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user