diff --git a/SpaceNav.cs b/SpaceNav.cs index 62a955e..d31f55d 100644 --- a/SpaceNav.cs +++ b/SpaceNav.cs @@ -3,13 +3,12 @@ using System.Runtime.InteropServices; namespace spnavwrapper { - public sealed class SpaceNav + public sealed class SpaceNav : IDisposable { double _sensitivity = 1.0; int _threshold = 5; - static SpaceNav instance = null; - static readonly object padlock = new object(); + static SpaceNav instance; const int SPNAV_EVENT_MOTION = 1; const int SPNAV_EVENT_BUTTON = 2; @@ -53,7 +52,7 @@ namespace spnavwrapper [DllImport(DLL_NAME)] static extern int spnav_sensitivity(double sens); [DllImport(DLL_NAME)] - static extern int spnav_deadzone(int threshold); + static extern int spnav_deadzone(int threshold); SpaceNav() { @@ -61,107 +60,110 @@ namespace spnavwrapper spnav_open(SPNAV_VENDOR_ID, SPNAV_PRODUCT_ID); } - ~SpaceNav() - { - // TODO : handle retcode - spnav_close(); - } - public static SpaceNav Instance { get { - lock (padlock) + if (instance == null) { - if (instance == null) - { - instance = new SpaceNav(); - } - return instance; + instance = new SpaceNav(); } + return instance; } } public void CloseDevice() { - lock (padlock) - { - spnav_close(); - instance = null; - } + spnav_close(); + instance = null; } public SpaceNavEvent WaitEvent() { - lock (padlock) + SpNavEvent sev = new SpNavEvent(); + spnav_wait_event(ref sev); + switch (sev.type) { - SpNavEvent sev = new SpNavEvent(); - spnav_wait_event(ref sev); - switch (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; - } + 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) { - lock (padlock) + SpNavEvent sev = new SpNavEvent(); + int ev_type = spnav_wait_event_timeout(ref sev, milliseconds); + switch (ev_type) { - SpNavEvent sev = new SpNavEvent(); - int ev_type = spnav_wait_event_timeout(ref sev, milliseconds); - switch (ev_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; - } + 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 double Sensitivity - { - get + { + get { return _sensitivity; } set { - lock (padlock) - { - // TODO : handle retcode - spnav_sensitivity(value); - _sensitivity = value; - } + // TODO : handle retcode + spnav_sensitivity(value); + _sensitivity = value; } } public int Threshold - { + { get { return _threshold; } - set + set { - lock (padlock) - { - // TODO : handle retcode - spnav_deadzone(value); - _threshold = value; - } + // TODO : handle retcode + spnav_deadzone(value); + _threshold = value; } - } + } + + #region IDisposable Support + private bool disposedValue = false; // To detect redundant calls + + void Dispose(bool disposing) + { + if (!disposedValue) + { + // Free unmanaged resources + spnav_close(); + 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 } }