From d68acd609d268516f2ea2b593e221b7e92d97f6f Mon Sep 17 00:00:00 2001 From: chrisv Date: Sat, 28 Feb 2009 20:23:32 +0000 Subject: [PATCH] MAINTENANCE Moved destruction logic to finalizers, and added ObjectDisposedException when accessing a dead object. Moved anonymous namespace objects to Vrpn.Internal. --- VrpnNet/AnalogOutputRemote.cpp | 16 +++++++ VrpnNet/AnalogOutputRemote.h | 2 + VrpnNet/AnalogRemote.cpp | 23 ++++++++-- VrpnNet/AnalogRemote.h | 2 + VrpnNet/AnalogServer.cpp | 18 +++++++- VrpnNet/AnalogServer.h | 2 + VrpnNet/ButtonRemote.cpp | 27 +++++++++--- VrpnNet/ButtonRemote.h | 2 + VrpnNet/ButtonServer.cpp | 16 ++++++- VrpnNet/ButtonServer.h | 2 + VrpnNet/Connection.cpp | 11 +++++ VrpnNet/Connection.h | 2 + VrpnNet/DialRemote.cpp | 24 ++++++++--- VrpnNet/DialRemote.h | 2 + VrpnNet/ForceDeviceRemote.cpp | 76 ++++++++++++++++++++++++++++++---- VrpnNet/ForceDeviceRemote.h | 2 + VrpnNet/MutexRemote.cpp | 29 ++++++++++--- VrpnNet/MutexRemote.h | 2 + VrpnNet/MutexServer.cpp | 11 ++++- VrpnNet/MutexServer.h | 2 + VrpnNet/PoserRemote.cpp | 18 +++++++- VrpnNet/PoserRemote.h | 2 + VrpnNet/Stdafx.h | 6 ++- VrpnNet/Text.h | 4 ++ VrpnNet/TextReceiver.cpp | 24 ++++++++--- VrpnNet/TextSender.cpp | 15 ++++++- VrpnNet/TrackerRemote.cpp | 44 +++++++++++++++----- VrpnNet/TrackerRemote.h | 2 + 28 files changed, 336 insertions(+), 50 deletions(-) diff --git a/VrpnNet/AnalogOutputRemote.cpp b/VrpnNet/AnalogOutputRemote.cpp index 4bbf374..4755cc6 100644 --- a/VrpnNet/AnalogOutputRemote.cpp +++ b/VrpnNet/AnalogOutputRemote.cpp @@ -38,8 +38,14 @@ AnalogOutputRemote::AnalogOutputRemote(String ^name, Connection ^c) } AnalogOutputRemote::~AnalogOutputRemote() +{ + this->!AnalogOutputRemote(); +} + +AnalogOutputRemote::!AnalogOutputRemote() { delete m_analogOut; + m_disposed = true; } void AnalogOutputRemote::Initialize(String ^name, vrpn_Connection *lpConn) @@ -50,35 +56,43 @@ void AnalogOutputRemote::Initialize(String ^name, vrpn_Connection *lpConn) m_analogOut = new ::vrpn_Analog_Output_Remote(ansiName, lpConn); Marshal::FreeHGlobal(hAnsiName); + + m_disposed = false; } void AnalogOutputRemote::Update() { + CHECK_DISPOSAL_STATUS(); m_analogOut->mainloop(); } void AnalogOutputRemote::MuteWarnings::set(Boolean shutUp) { + CHECK_DISPOSAL_STATUS(); m_analogOut->shutup = shutUp; } Boolean AnalogOutputRemote::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_analogOut->shutup; } Connection^ AnalogOutputRemote::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_analogOut->connectionPtr()); } Boolean AnalogOutputRemote::RequestChannelChange(Int64 channel, Double value) { + CHECK_DISPOSAL_STATUS(); return RequestChannelChange(channel, value, ServiceClass::Reliable); } Boolean AnalogOutputRemote::RequestChannelChange(Int64 channel, Double value, ServiceClass sc) { + CHECK_DISPOSAL_STATUS(); if (channel > 0xFFFFFFFFUL) throw gcnew ArgumentOutOfRangeException("channel", "Value must fit in a vrpn_uint32 type"); @@ -89,11 +103,13 @@ Boolean AnalogOutputRemote::RequestChannelChange(Int64 channel, Double value, Se Boolean AnalogOutputRemote::RequestChannelChange(array ^channels) { + CHECK_DISPOSAL_STATUS(); return RequestChannelChange(channels, ServiceClass::Reliable); } Boolean AnalogOutputRemote::RequestChannelChange(array ^channels, ServiceClass sc) { + CHECK_DISPOSAL_STATUS(); if (channels->LongLength > 0xFFFFFFFFUL) throw gcnew ArgumentException( "VRPN AnalogOutput class supports only 2^32-1 channels", "channels"); diff --git a/VrpnNet/AnalogOutputRemote.h b/VrpnNet/AnalogOutputRemote.h index cd658da..9f4a36b 100644 --- a/VrpnNet/AnalogOutputRemote.h +++ b/VrpnNet/AnalogOutputRemote.h @@ -31,6 +31,7 @@ namespace Vrpn { AnalogOutputRemote(System::String ^name); AnalogOutputRemote(System::String ^name, Vrpn::Connection ^connection); ~AnalogOutputRemote(); + !AnalogOutputRemote(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -54,6 +55,7 @@ namespace Vrpn { private: ::vrpn_Analog_Output_Remote *m_analogOut; + System::Boolean m_disposed; void Initialize(System::String ^name, vrpn_Connection *lpConn); }; diff --git a/VrpnNet/AnalogRemote.cpp b/VrpnNet/AnalogRemote.cpp index 0053e0d..57c2ae2 100644 --- a/VrpnNet/AnalogRemote.cpp +++ b/VrpnNet/AnalogRemote.cpp @@ -23,13 +23,16 @@ #include "stdafx.h" #include "AnalogRemote.h" +namespace Vrpn { + namespace Internal { + delegate void AnalogChangeCallback(void *userData, const vrpn_ANALOGCB info); + } +} + using namespace System; using namespace System::Runtime::InteropServices; using namespace Vrpn; - -namespace { - delegate void AnalogChangeCallback(void *userData, const vrpn_ANALOGCB info); -} +using namespace Vrpn::Internal; AnalogRemote::AnalogRemote(String ^name) { @@ -57,32 +60,44 @@ void AnalogRemote::Initialize(System::String ^name, vrpn_Connection *lpConn) static_cast(pAnalogChange.ToPointer()); m_analog->register_change_handler(0, pCallbackFunc); + + m_disposed = false; } AnalogRemote::~AnalogRemote() +{ + this->!AnalogRemote(); +} + +AnalogRemote::!AnalogRemote() { delete m_analog; gc_callback.Free(); + m_disposed = true; } void AnalogRemote::Update() { + CHECK_DISPOSAL_STATUS(); m_analog->mainloop(); } void AnalogRemote::MuteWarnings::set(Boolean shutUp) { + CHECK_DISPOSAL_STATUS(); m_analog->shutup = shutUp; } Boolean AnalogRemote::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_analog->shutup; } Connection^ AnalogRemote::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_analog->connectionPtr()); } diff --git a/VrpnNet/AnalogRemote.h b/VrpnNet/AnalogRemote.h index e5f252c..9d74027 100644 --- a/VrpnNet/AnalogRemote.h +++ b/VrpnNet/AnalogRemote.h @@ -42,6 +42,7 @@ namespace Vrpn { AnalogRemote(System::String ^name); AnalogRemote(System::String ^name, Vrpn::Connection ^connection); ~AnalogRemote(); + !AnalogRemote(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -55,6 +56,7 @@ namespace Vrpn { private: ::vrpn_Analog_Remote *m_analog; + System::Boolean m_disposed; void Initialize(System::String ^name, vrpn_Connection *lpConn); void onAnalogChange(void *userData, const vrpn_ANALOGCB info); diff --git a/VrpnNet/AnalogServer.cpp b/VrpnNet/AnalogServer.cpp index 540b689..4caf8d8 100644 --- a/VrpnNet/AnalogServer.cpp +++ b/VrpnNet/AnalogServer.cpp @@ -52,11 +52,19 @@ void AnalogServer::Initialize(System::String ^name, Vrpn::Connection ^connection m_channels = gcnew cli::array(numChannels); for (int i = 0; i < numChannels; i++) m_channels[i] = gcnew AnalogServerChannel(); + + m_disposed = false; } -AnalogServer::~AnalogServer() +AnalogServer::!AnalogServer() { delete m_server; + m_disposed = true; +} + +AnalogServer::~AnalogServer() +{ + this->!AnalogServer(); } void AnalogServer::UpdateChannels() @@ -75,36 +83,43 @@ void AnalogServer::UpdateChannels() void AnalogServer::Update() { + CHECK_DISPOSAL_STATUS(); m_server->mainloop(); } Connection^ AnalogServer::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_server->connectionPtr()); } void AnalogServer::MuteWarnings::set(bool shutUp) { + CHECK_DISPOSAL_STATUS(); m_server->shutup = shutUp; } bool AnalogServer::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_server->shutup; } void AnalogServer::Report() { + CHECK_DISPOSAL_STATUS(); Report(ServiceClass::LowLatency, DateTime::Now); } void AnalogServer::ReportChanges() { + CHECK_DISPOSAL_STATUS(); Report(ServiceClass::LowLatency, DateTime::Now); } void AnalogServer::Report(Vrpn::ServiceClass classOfService, System::DateTime time) { + CHECK_DISPOSAL_STATUS(); timeval tm; VrpnUtils::CreateTimeval(time, &tm); @@ -114,6 +129,7 @@ void AnalogServer::Report(Vrpn::ServiceClass classOfService, System::DateTime ti void AnalogServer::ReportChanges(Vrpn::ServiceClass classOfService, System::DateTime time) { + CHECK_DISPOSAL_STATUS(); timeval tm; VrpnUtils::CreateTimeval(time, &tm); diff --git a/VrpnNet/AnalogServer.h b/VrpnNet/AnalogServer.h index 6e854c5..50e9db0 100644 --- a/VrpnNet/AnalogServer.h +++ b/VrpnNet/AnalogServer.h @@ -35,6 +35,7 @@ namespace Vrpn { AnalogServer(System::String ^name, Vrpn::Connection ^connection); AnalogServer(System::String ^name, Vrpn::Connection ^connection, System::Int32 numChannels); ~AnalogServer(); + !AnalogServer(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -58,5 +59,6 @@ namespace Vrpn { ::vrpn_Analog_Server *m_server; cli::array ^m_channels; + System::Boolean m_disposed; }; } \ No newline at end of file diff --git a/VrpnNet/ButtonRemote.cpp b/VrpnNet/ButtonRemote.cpp index 7c649d0..8ef7b5a 100644 --- a/VrpnNet/ButtonRemote.cpp +++ b/VrpnNet/ButtonRemote.cpp @@ -23,13 +23,16 @@ #include "stdafx.h" #include "ButtonRemote.h" +namespace Vrpn { + namespace Internal { + delegate void ButtonChangeCallback(void *userData, const vrpn_BUTTONCB info); + } +} + using namespace System; using namespace System::Runtime::InteropServices; using namespace Vrpn; - -namespace { - delegate void ButtonChangeCallback(void *userData, const vrpn_BUTTONCB info); -} +using namespace Vrpn::Internal; ButtonRemote::ButtonRemote(String ^name) { @@ -41,6 +44,8 @@ ButtonRemote::ButtonRemote(String ^name) Marshal::FreeHGlobal(hAnsiName); RegisterHandler(); + + m_disposed = false; } ButtonRemote::ButtonRemote(System::String ^name, Vrpn::Connection ^connection) @@ -53,32 +58,44 @@ ButtonRemote::ButtonRemote(System::String ^name, Vrpn::Connection ^connection) Marshal::FreeHGlobal(hAnsiName); RegisterHandler(); + + m_disposed = false; } -ButtonRemote::~ButtonRemote() +ButtonRemote::!ButtonRemote() { delete m_button; gc_callback.Free(); + m_disposed = true; +} + +ButtonRemote::~ButtonRemote() +{ + this->!ButtonRemote(); } void ButtonRemote::Update() { + CHECK_DISPOSAL_STATUS(); m_button->mainloop(); } void ButtonRemote::MuteWarnings::set(Boolean shutUp) { + CHECK_DISPOSAL_STATUS(); m_button->shutup = shutUp; } Boolean ButtonRemote::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_button->shutup; } Connection^ ButtonRemote::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_button->connectionPtr()); } diff --git a/VrpnNet/ButtonRemote.h b/VrpnNet/ButtonRemote.h index 67bc586..f55c155 100644 --- a/VrpnNet/ButtonRemote.h +++ b/VrpnNet/ButtonRemote.h @@ -45,6 +45,7 @@ namespace Vrpn { ButtonRemote(System::String ^name); ButtonRemote(System::String ^name, Vrpn::Connection ^connection); ~ButtonRemote(); + !ButtonRemote(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -63,5 +64,6 @@ namespace Vrpn { void onButtonChange(void *userData, const vrpn_BUTTONCB info); System::Runtime::InteropServices::GCHandle gc_callback; + System::Boolean m_disposed; }; } \ No newline at end of file diff --git a/VrpnNet/ButtonServer.cpp b/VrpnNet/ButtonServer.cpp index 2419770..b56a520 100644 --- a/VrpnNet/ButtonServer.cpp +++ b/VrpnNet/ButtonServer.cpp @@ -47,6 +47,8 @@ bool ButtonServer::ButtonCollection::default::get(int index) void ButtonServer::ButtonCollection::default::set(int index, bool state) { + if (m_parent->m_disposed) + throw gcnew ObjectDisposedException("VRPN Object"); m_parent->m_server->set_button(index, state ? 1 : 0); m_array[index] = state; } @@ -73,36 +75,46 @@ void ButtonServer::Initialize(System::String ^name, Vrpn::Connection ^connection Marshal::FreeHGlobal(hName); m_buttons = gcnew ButtonCollection(this, numButtons); + m_disposed = false; } -ButtonServer::~ButtonServer() +ButtonServer::!ButtonServer() { delete m_server; - m_server = 0; m_buttons = nullptr; } +ButtonServer::~ButtonServer() +{ + this->!ButtonServer(); +} + Connection ^ButtonServer::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_server->connectionPtr()); } bool ButtonServer::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_server->shutup; } void ButtonServer::MuteWarnings::set(bool shutUp) { + CHECK_DISPOSAL_STATUS(); m_server->shutup = shutUp; } void ButtonServer::Update() { + CHECK_DISPOSAL_STATUS(); m_server->mainloop(); } ButtonServer::ButtonCollection ^ButtonServer::Buttons::get() { + CHECK_DISPOSAL_STATUS(); return m_buttons; } \ No newline at end of file diff --git a/VrpnNet/ButtonServer.h b/VrpnNet/ButtonServer.h index f38c7c6..0777362 100644 --- a/VrpnNet/ButtonServer.h +++ b/VrpnNet/ButtonServer.h @@ -33,6 +33,7 @@ namespace Vrpn { ButtonServer(System::String ^name, Vrpn::Connection ^connection); ButtonServer(System::String ^name, Vrpn::Connection ^connection, System::Int32 numButtons); ~ButtonServer(); + !ButtonServer(); virtual void Update(); // from IVrpnObject virtual Vrpn::Connection ^GetConnection(); // from IVrpnObject @@ -69,6 +70,7 @@ namespace Vrpn { private: ::vrpn_Button_Server *m_server; ButtonCollection ^m_buttons; + System::Boolean m_disposed; void Initialize(System::String ^name, Vrpn::Connection ^connection, System::Int32 numButtons); }; diff --git a/VrpnNet/Connection.cpp b/VrpnNet/Connection.cpp index 5ec5649..b2b198a 100644 --- a/VrpnNet/Connection.cpp +++ b/VrpnNet/Connection.cpp @@ -42,20 +42,29 @@ using namespace Vrpn; Connection::Connection(vrpn_Connection *connection) { m_connection = connection; + m_disposed = false; } Connection::~Connection() +{ + this->!Connection(); +} + +Connection::!Connection() { m_connection->removeReference(); + m_disposed = true; } vrpn_Connection* Connection::ToPointer() { + CHECK_DISPOSAL_STATUS(); return m_connection; } void Connection::Update() { + CHECK_DISPOSAL_STATUS(); m_connection->mainloop(); } @@ -212,10 +221,12 @@ Connection^ Connection::CreateServerConnection(System::Int32 port, Boolean Connection::DoingOkay::get() { + CHECK_DISPOSAL_STATUS(); return m_connection->doing_okay() != 0; } Boolean Connection::Connected::get() { + CHECK_DISPOSAL_STATUS(); return m_connection->connected() != 0; } \ No newline at end of file diff --git a/VrpnNet/Connection.h b/VrpnNet/Connection.h index 0f8f65c..4f90f3b 100644 --- a/VrpnNet/Connection.h +++ b/VrpnNet/Connection.h @@ -67,6 +67,7 @@ namespace Vrpn { ::vrpn_Connection *pointer); ~Connection(); + !Connection(); void Update(); @@ -86,5 +87,6 @@ namespace Vrpn { Connection(::vrpn_Connection *connection); ::vrpn_Connection *m_connection; + System::Boolean m_disposed; }; } \ No newline at end of file diff --git a/VrpnNet/DialRemote.cpp b/VrpnNet/DialRemote.cpp index e268a1f..5a1a686 100644 --- a/VrpnNet/DialRemote.cpp +++ b/VrpnNet/DialRemote.cpp @@ -23,13 +23,16 @@ #include "stdafx.h" #include "DialRemote.h" +namespace Vrpn { + namespace Internal { + delegate void DialChangeCallback(void *userData, const vrpn_DIALCB info); + } +} + using namespace System; using namespace System::Runtime::InteropServices; using namespace Vrpn; - -namespace { - delegate void DialChangeCallback(void *userData, const vrpn_DIALCB info); -} +using namespace Vrpn::Internal; DialRemote::DialRemote(String ^name) { @@ -57,32 +60,43 @@ void DialRemote::Initialize(System::String ^name, vrpn_Connection *lpConn) static_cast(pDialChange.ToPointer()); m_dial->register_change_handler(0, pCallbackFunc); + m_disposed = false; } -DialRemote::~DialRemote() +DialRemote::!DialRemote() { delete m_dial; gc_callback.Free(); + m_disposed = true; +} + +DialRemote::~DialRemote() +{ + this->!DialRemote(); } void DialRemote::Update() { + CHECK_DISPOSAL_STATUS(); m_dial->mainloop(); } void DialRemote::MuteWarnings::set(Boolean shutUp) { + CHECK_DISPOSAL_STATUS(); m_dial->shutup = shutUp; } Boolean DialRemote::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_dial->shutup; } Connection^ DialRemote::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_dial->connectionPtr()); } diff --git a/VrpnNet/DialRemote.h b/VrpnNet/DialRemote.h index e190339..3933b71 100644 --- a/VrpnNet/DialRemote.h +++ b/VrpnNet/DialRemote.h @@ -44,6 +44,7 @@ namespace Vrpn { DialRemote(System::String ^name); DialRemote(System::String ^name, Vrpn::Connection ^connection); ~DialRemote(); + !DialRemote(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -57,6 +58,7 @@ namespace Vrpn { private: ::vrpn_Dial_Remote *m_dial; + System::Boolean m_disposed; void Initialize(System::String ^name, vrpn_Connection *lpConn); void onDialChange(void *userData, const vrpn_DIALCB info); diff --git a/VrpnNet/ForceDeviceRemote.cpp b/VrpnNet/ForceDeviceRemote.cpp index 60b6316..468d806 100644 --- a/VrpnNet/ForceDeviceRemote.cpp +++ b/VrpnNet/ForceDeviceRemote.cpp @@ -23,15 +23,18 @@ #include "stdafx.h" #include "ForceDeviceRemote.h" +namespace Vrpn { + namespace Internal { + delegate void ForceChangeCallback(void *, const vrpn_FORCECB); + delegate void ForceSurfaceContactCallback(void *, const vrpn_FORCESCPCB); + delegate void ForceErrorCallback(void *, const vrpn_FORCEERRORCB); + } +} + using namespace System; using namespace System::Runtime::InteropServices; using namespace Vrpn; - -namespace { - delegate void ForceChangeCallback(void *, const vrpn_FORCECB); - delegate void ForceSurfaceContactCallback(void *, const vrpn_FORCESCPCB); - delegate void ForceErrorCallback(void *, const vrpn_FORCEERRORCB); -} +using namespace Vrpn::Internal; ForceDeviceRemote::ForceDeviceRemote(System::String ^name) { @@ -43,13 +46,20 @@ ForceDeviceRemote::ForceDeviceRemote(System::String ^name, Vrpn::Connection ^con Initialize(name, connection->ToPointer()); } -ForceDeviceRemote::~ForceDeviceRemote() +ForceDeviceRemote::!ForceDeviceRemote() { delete m_force; gc_forceScp.Free(); gc_forceChange.Free(); gc_error.Free(); + + m_disposed = true; +} + +ForceDeviceRemote::~ForceDeviceRemote() +{ + this->!ForceDeviceRemote(); } void ForceDeviceRemote::Initialize(System::String ^name, ::vrpn_Connection *lpConn) @@ -88,25 +98,31 @@ void ForceDeviceRemote::Initialize(System::String ^name, ::vrpn_Connection *lpCo if (m_force->register_error_handler(0, pErrorCallback)) throw gcnew VrpnException(); + + m_disposed = false; } void ForceDeviceRemote::Update() { + CHECK_DISPOSAL_STATUS(); m_force->mainloop(); } Connection^ ForceDeviceRemote::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_force->connectionPtr()); } void ForceDeviceRemote::MuteWarnings::set(Boolean shutUp) { + CHECK_DISPOSAL_STATUS(); m_force->shutup = shutUp; } Boolean ForceDeviceRemote::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_force->shutup; } @@ -121,21 +137,25 @@ Boolean ForceDeviceRemote::SpringsAreForceFields::get() void ForceDeviceRemote::SendSurface() { + CHECK_DISPOSAL_STATUS(); m_force->sendSurface(); } void ForceDeviceRemote::StartSurface() { + CHECK_DISPOSAL_STATUS(); m_force->startSurface(); } void ForceDeviceRemote::StopSurface() { + CHECK_DISPOSAL_STATUS(); m_force->stopSurface(); } void ForceDeviceRemote::SetVertex(int vertexNumber, Vrpn::Vector3 point) { + CHECK_DISPOSAL_STATUS(); m_force->setVertex(vertexNumber, static_cast(point.X), static_cast(point.Y), @@ -144,6 +164,7 @@ void ForceDeviceRemote::SetVertex(int vertexNumber, Vrpn::Vector3 point) void ForceDeviceRemote::SetNormal(int normalNumber, Vrpn::Vector3 normal) { + CHECK_DISPOSAL_STATUS(); m_force->setNormal(normalNumber, static_cast(normal.X), static_cast(normal.Y), @@ -152,27 +173,32 @@ void ForceDeviceRemote::SetNormal(int normalNumber, Vrpn::Vector3 normal) void ForceDeviceRemote::SetTriangle(int triangleNumber, int vertex1, int vertex2, int vertex3) { + CHECK_DISPOSAL_STATUS(); SetTriangle(triangleNumber, vertex1, vertex2, vertex3, -1, -1, -1); } void ForceDeviceRemote::SetTriangle(int triangleNumber, int vertex1, int vertex2, int vertex3, int normal1, int normal2, int normal3) { + CHECK_DISPOSAL_STATUS(); m_force->setTriangle(triangleNumber, vertex1, vertex2, vertex3, normal1, normal2, normal3); } void ForceDeviceRemote::RemoveTriangle(int triangleNumber) { + CHECK_DISPOSAL_STATUS(); m_force->removeTriangle(triangleNumber); } void ForceDeviceRemote::UpdateTrimeshChanges() { + CHECK_DISPOSAL_STATUS(); m_force->updateTrimeshChanges(); } void ForceDeviceRemote::SetTrimeshTransform(cli::array ^matrix) { + CHECK_DISPOSAL_STATUS(); if (matrix->GetLength(0) != 16) throw gcnew System::ArgumentException("Value must be a 16-element homogenous transform matrix in row-major order.", "matrix"); @@ -183,26 +209,31 @@ void ForceDeviceRemote::SetTrimeshTransform(cli::array ^matrix) void ForceDeviceRemote::ClearTrimesh() { + CHECK_DISPOSAL_STATUS(); m_force->clearTrimesh(); } void ForceDeviceRemote::AddObject(int objectNumber) { + CHECK_DISPOSAL_STATUS(); AddObject(objectNumber, -1); } void ForceDeviceRemote::AddObject(int objectNumber, int parentNumber) { + CHECK_DISPOSAL_STATUS(); m_force->addObject(objectNumber, parentNumber); } void ForceDeviceRemote::AddObjectExScene(int objectNumber) { + CHECK_DISPOSAL_STATUS(); m_force->addObjectExScene(objectNumber); } void ForceDeviceRemote::SetObjectVertex(int objectNumber, int vertexNumber, Vrpn::Vector3 point) { + CHECK_DISPOSAL_STATUS(); m_force->setObjectVertex(objectNumber, vertexNumber, static_cast(point.X), static_cast(point.Y), @@ -211,6 +242,7 @@ void ForceDeviceRemote::SetObjectVertex(int objectNumber, int vertexNumber, Vrpn void ForceDeviceRemote::SetObjectNormal(int objectNumber, int normalNumber, Vrpn::Vector3 normal) { + CHECK_DISPOSAL_STATUS(); m_force->setObjectNormal(objectNumber, normalNumber, static_cast(normal.X), static_cast(normal.Y), @@ -219,28 +251,33 @@ void ForceDeviceRemote::SetObjectNormal(int objectNumber, int normalNumber, Vrpn void ForceDeviceRemote::SetObjectTriangle(int objectNumber, int triangleNumber, int vertex1, int vertex2, int vertex3) { + CHECK_DISPOSAL_STATUS(); SetObjectTriangle(objectNumber, triangleNumber, vertex1, vertex2, vertex3, -1, -1, -1); } void ForceDeviceRemote::SetObjectTriangle(int objectNumber, int triangleNumber, int vertex1, int vertex2, int vertex3, int normal1, int normal2, int normal3) { + CHECK_DISPOSAL_STATUS(); m_force->setObjectTriangle(objectNumber, triangleNumber, vertex1, vertex2, vertex3, normal1, normal2, normal3); } void ForceDeviceRemote::RemoveObjectTriangle(int objectNumber, int triangleNumber) { + CHECK_DISPOSAL_STATUS(); m_force->removeObjectTriangle(objectNumber, triangleNumber); } void ForceDeviceRemote::UpdateObjectTrimeshChanges(int objectNumber) { + CHECK_DISPOSAL_STATUS(); m_force->updateObjectTrimeshChanges(objectNumber); } void ForceDeviceRemote::SetObjectTrimeshTransform(int objectNumber, cli::array ^matrix) { + CHECK_DISPOSAL_STATUS(); if (matrix->GetLength(0) != 16) throw gcnew System::ArgumentException("Value must be a 16-element homogenous transform matrix in row-major order.", "matrix"); @@ -252,6 +289,7 @@ void ForceDeviceRemote::SetObjectTrimeshTransform(int objectNumber, cli::arrayremoveObject(objectNumber); } void ForceDeviceRemote::ClearObjectTrimesh(int objectNumber) { + CHECK_DISPOSAL_STATUS(); m_force->clearObjectTrimesh(objectNumber); } void ForceDeviceRemote::MoveToParent(int objectNumber, int parentNumber) { + CHECK_DISPOSAL_STATUS(); m_force->moveToParent(objectNumber, parentNumber); } void ForceDeviceRemote::SetHapticOrigin(Vrpn::Vector3 position, Vrpn::Vector3 axis, float angle) { + CHECK_DISPOSAL_STATUS(); float cPos[3], cAxis[3]; VrpnUtils::CreateVector(position, cPos); VrpnUtils::CreateVector(axis, cAxis); @@ -300,11 +344,13 @@ void ForceDeviceRemote::SetHapticOrigin(Vrpn::Vector3 position, Vrpn::Vector3 ax void ForceDeviceRemote::SetHapticScale(float scale) { + CHECK_DISPOSAL_STATUS(); m_force->setHapticScale(scale); } void ForceDeviceRemote::SetSceneOrigin(Vrpn::Vector3 position, Vrpn::Vector3 axis, float angle) { + CHECK_DISPOSAL_STATUS(); float cPos[3], cAxis[3]; VrpnUtils::CreateVector(position, cPos); VrpnUtils::CreateVector(axis, cAxis); @@ -314,16 +360,19 @@ void ForceDeviceRemote::SetSceneOrigin(Vrpn::Vector3 position, Vrpn::Vector3 axi int ForceDeviceRemote::GetNewObjectId() { + CHECK_DISPOSAL_STATUS(); return m_force->getNewObjectID(); } void ForceDeviceRemote::SetObjectIsTouchable(int objectNumber, bool isTouchable) { + CHECK_DISPOSAL_STATUS(); m_force->setObjectIsTouchable(objectNumber, isTouchable); } void ForceDeviceRemote::SetMeshPacking(Vrpn::ForceDeviceMeshPacking api) { + CHECK_DISPOSAL_STATUS(); switch (api) { case ForceDeviceMeshPacking::Hcollide: @@ -341,16 +390,19 @@ void ForceDeviceRemote::SetMeshPacking(Vrpn::ForceDeviceMeshPacking api) void ForceDeviceRemote::EnableConstraints(bool enable) { + CHECK_DISPOSAL_STATUS(); m_force->enableConstraint(enable); } void ForceDeviceRemote::SetConstraintMode(ConstraintGeometry mode) { + CHECK_DISPOSAL_STATUS(); m_force->setConstraintMode(static_cast<::vrpn_ForceDevice::ConstraintGeometry>(mode)); } void ForceDeviceRemote::SetConstraintPoint(Vrpn::Vector3 point) { + CHECK_DISPOSAL_STATUS(); float cPoint[3]; VrpnUtils::CreateVector(point, cPoint); m_force->setConstraintPoint(cPoint); @@ -358,6 +410,7 @@ void ForceDeviceRemote::SetConstraintPoint(Vrpn::Vector3 point) void ForceDeviceRemote::SetConstraintLinePoint(Vrpn::Vector3 point) { + CHECK_DISPOSAL_STATUS(); float cPoint[3]; VrpnUtils::CreateVector(point, cPoint); m_force->setConstraintLinePoint(cPoint); @@ -365,6 +418,7 @@ void ForceDeviceRemote::SetConstraintLinePoint(Vrpn::Vector3 point) void ForceDeviceRemote::SetConstraintLineDirection(Vrpn::Vector3 direction) { + CHECK_DISPOSAL_STATUS(); float cDir[3]; VrpnUtils::CreateVector(direction, cDir); m_force->setConstraintLineDirection(cDir); @@ -372,6 +426,7 @@ void ForceDeviceRemote::SetConstraintLineDirection(Vrpn::Vector3 direction) void ForceDeviceRemote::SetConstraintPlanePoint(Vrpn::Vector3 point) { + CHECK_DISPOSAL_STATUS(); float cPoint[3]; VrpnUtils::CreateVector(point, cPoint); m_force->setConstraintPlanePoint(cPoint); @@ -379,6 +434,7 @@ void ForceDeviceRemote::SetConstraintPlanePoint(Vrpn::Vector3 point) void ForceDeviceRemote::SetConstraintPlaneNormal(Vrpn::Vector3 normal) { + CHECK_DISPOSAL_STATUS(); float cNormal[3]; VrpnUtils::CreateVector(normal, cNormal); m_force->setConstraintPlaneNormal(cNormal); @@ -386,16 +442,19 @@ void ForceDeviceRemote::SetConstraintPlaneNormal(Vrpn::Vector3 normal) void ForceDeviceRemote::SetConstraintKSpring(float k) { + CHECK_DISPOSAL_STATUS(); m_force->setConstraintKSpring(k); } void ForceDeviceRemote::SendForceField() { + CHECK_DISPOSAL_STATUS(); m_force->sendForceField(); } void ForceDeviceRemote::SendForceField(Vrpn::Vector3 origin, Vrpn::Vector3 force, cli::array ^jacobian, float radius) { + CHECK_DISPOSAL_STATUS(); if (jacobian->GetLength(0) != 3 || jacobian->GetLength(1) != 3) throw gcnew ArgumentException("jacobian", "Value must be a 3*3 matrix."); @@ -413,16 +472,19 @@ void ForceDeviceRemote::SendForceField(Vrpn::Vector3 origin, Vrpn::Vector3 force void ForceDeviceRemote::StopForceField() { + CHECK_DISPOSAL_STATUS(); m_force->stopForceField(); } void ForceDeviceRemote::StartEffect() { + CHECK_DISPOSAL_STATUS(); m_force->startEffect(); } void ForceDeviceRemote::StopEffect() { + CHECK_DISPOSAL_STATUS(); m_force->stopEffect(); } diff --git a/VrpnNet/ForceDeviceRemote.h b/VrpnNet/ForceDeviceRemote.h index 1e3726b..e29c85c 100644 --- a/VrpnNet/ForceDeviceRemote.h +++ b/VrpnNet/ForceDeviceRemote.h @@ -87,6 +87,7 @@ namespace Vrpn { ForceDeviceRemote(System::String ^name); ForceDeviceRemote(System::String ^name, Vrpn::Connection ^connection); ~ForceDeviceRemote(); + !ForceDeviceRemote(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -171,6 +172,7 @@ namespace Vrpn { private: ::vrpn_ForceDevice_Remote *m_force; + System::Boolean m_disposed; void Initialize(System::String ^name, ::vrpn_Connection *lpConn); void onSurfaceContact(void *userData, const ::vrpn_FORCESCPCB info); diff --git a/VrpnNet/MutexRemote.cpp b/VrpnNet/MutexRemote.cpp index f06ea50..54da779 100644 --- a/VrpnNet/MutexRemote.cpp +++ b/VrpnNet/MutexRemote.cpp @@ -24,16 +24,18 @@ #include "MutexRemote.h" #include "MutexRemoteNative.h" +namespace Vrpn { + namespace Internal { + typedef void (*MutexCallback)(int); + delegate void MutexEventHandler(int event); + } +} + using namespace System; using namespace System::Runtime::InteropServices; using namespace Vrpn; using namespace Vrpn::Internal; -namespace { - typedef void (*MutexCallback)(int); - delegate void MutexEventHandler(int event); -} - MutexRemote::MutexRemote(System::String ^name) { Initialize(name, 0); @@ -57,17 +59,26 @@ void MutexRemote::Initialize(System::String ^name, vrpn_Connection *lpConn) gc_vrpnCallback = GCHandle::Alloc(callback); IntPtr pVrpnCallback = Marshal::GetFunctionPointerForDelegate(callback); m_mutex->setCallback(static_cast(pVrpnCallback.ToPointer())); + + m_disposed = false; } -MutexRemote::~MutexRemote() +MutexRemote::!MutexRemote() { delete m_mutex; gc_vrpnCallback.Free(); + m_disposed = true; +} + +MutexRemote::~MutexRemote() +{ + this->!MutexRemote(); } void MutexRemote::Update() { + CHECK_DISPOSAL_STATUS(); m_mutex->mainloop(); } @@ -83,31 +94,37 @@ Boolean MutexRemote::MuteWarnings::get() Connection^ MutexRemote::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_mutex->connectionPtr()); } Boolean MutexRemote::Available::get() { + CHECK_DISPOSAL_STATUS(); return m_mutex->isAvailable() != 0; } Boolean MutexRemote::HeldLocally::get() { + CHECK_DISPOSAL_STATUS(); return m_mutex->isHeldLocally() != 0; } Boolean MutexRemote::HeldRemotely::get() { + CHECK_DISPOSAL_STATUS(); return m_mutex->isHeldRemotely() != 0; } void MutexRemote::Request() { + CHECK_DISPOSAL_STATUS(); m_mutex->request(); } void MutexRemote::Release() { + CHECK_DISPOSAL_STATUS(); m_mutex->release(); } diff --git a/VrpnNet/MutexRemote.h b/VrpnNet/MutexRemote.h index 8f1810b..f21a984 100644 --- a/VrpnNet/MutexRemote.h +++ b/VrpnNet/MutexRemote.h @@ -33,6 +33,7 @@ namespace Vrpn { MutexRemote(System::String ^name); MutexRemote(System::String ^name, Vrpn::Connection ^connection); ~MutexRemote(); + !MutexRemote(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -67,6 +68,7 @@ namespace Vrpn { private: Vrpn::Internal::MutexRemoteNative *m_mutex; + System::Boolean m_disposed; void Initialize(System::String ^name, ::vrpn_Connection *lpConn); diff --git a/VrpnNet/MutexServer.cpp b/VrpnNet/MutexServer.cpp index 99bae7c..6c6d0a3 100644 --- a/VrpnNet/MutexServer.cpp +++ b/VrpnNet/MutexServer.cpp @@ -35,21 +35,30 @@ MutexServer::MutexServer(System::String ^name, Vrpn::Connection ^connection) m_server = new ::vrpn_Mutex_Server(cName, connection->ToPointer()); m_connection = connection; Marshal::FreeHGlobal(hName); + + m_disposed = false; } -MutexServer::~MutexServer() +MutexServer::!MutexServer() { delete m_server; m_server = 0; } +MutexServer::~MutexServer() +{ + this->!MutexServer(); +} + void MutexServer::Update() { + CHECK_DISPOSAL_STATUS(); m_server->mainloop(); } Connection ^MutexServer::GetConnection() { + CHECK_DISPOSAL_STATUS(); return m_connection; } diff --git a/VrpnNet/MutexServer.h b/VrpnNet/MutexServer.h index 0b81ddd..e0f4d48 100644 --- a/VrpnNet/MutexServer.h +++ b/VrpnNet/MutexServer.h @@ -32,6 +32,7 @@ namespace Vrpn { public: MutexServer(System::String ^name, Vrpn::Connection ^connection); ~MutexServer(); + !MutexServer(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -44,5 +45,6 @@ namespace Vrpn { private: ::vrpn_Mutex_Server *m_server; Vrpn::Connection ^m_connection; + System::Boolean m_disposed; }; } \ No newline at end of file diff --git a/VrpnNet/PoserRemote.cpp b/VrpnNet/PoserRemote.cpp index 58141eb..45880e4 100644 --- a/VrpnNet/PoserRemote.cpp +++ b/VrpnNet/PoserRemote.cpp @@ -37,9 +37,15 @@ PoserRemote::PoserRemote(System::String ^name, Vrpn::Connection ^connection) Initialize(name, connection->ToPointer()); } -PoserRemote::~PoserRemote() +PoserRemote::!PoserRemote() { delete m_poser; + m_disposed = true; +} + +PoserRemote::~PoserRemote() +{ + this->!PoserRemote(); } void PoserRemote::Initialize(System::String ^name, vrpn_Connection *lpConn) @@ -50,30 +56,37 @@ void PoserRemote::Initialize(System::String ^name, vrpn_Connection *lpConn) m_poser = new ::vrpn_Poser_Remote(ansiName, lpConn); Marshal::FreeHGlobal(hAnsiName); + + m_disposed = false; } void PoserRemote::Update() { + CHECK_DISPOSAL_STATUS(); m_poser->mainloop(); } Connection^ PoserRemote::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_poser->connectionPtr()); } void PoserRemote::MuteWarnings::set(Boolean shutUp) { + CHECK_DISPOSAL_STATUS(); m_poser->shutup = shutUp; } Boolean PoserRemote::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_poser->shutup; } void PoserRemote::RequestPose(System::DateTime time, Vrpn::Vector3 position, Vrpn::Quaternion quaternion) { + CHECK_DISPOSAL_STATUS(); struct timeval cTime = {0, 0}; VrpnUtils::CreateTimeval(time, &cTime); @@ -88,6 +101,7 @@ void PoserRemote::RequestPose(System::DateTime time, Vrpn::Vector3 position, Vrp void PoserRemote::RequestPoseRelative(System::DateTime time, Vrpn::Vector3 positionDelta, Vrpn::Quaternion quaternion) { + CHECK_DISPOSAL_STATUS(); struct timeval cTime = {0, 0}; VrpnUtils::CreateTimeval(time, &cTime); @@ -102,6 +116,7 @@ void PoserRemote::RequestPoseRelative(System::DateTime time, Vrpn::Vector3 posit void PoserRemote::RequestPoseVelocity(System::DateTime time, Vrpn::Vector3 velocity, Vrpn::Quaternion quaternion, double interval) { + CHECK_DISPOSAL_STATUS(); struct timeval cTime = {0, 0}; VrpnUtils::CreateTimeval(time, &cTime); @@ -116,6 +131,7 @@ void PoserRemote::RequestPoseVelocity(System::DateTime time, Vrpn::Vector3 veloc void PoserRemote::RequestPoseVelocityRelative(System::DateTime time, Vrpn::Vector3 velocityDelta, Vrpn::Quaternion quaternion, double intervalDelta) { + CHECK_DISPOSAL_STATUS(); struct timeval cTime = {0, 0}; VrpnUtils::CreateTimeval(time, &cTime); diff --git a/VrpnNet/PoserRemote.h b/VrpnNet/PoserRemote.h index 975c586..3775809 100644 --- a/VrpnNet/PoserRemote.h +++ b/VrpnNet/PoserRemote.h @@ -33,6 +33,7 @@ namespace Vrpn { PoserRemote(System::String ^name); PoserRemote(System::String ^name, Vrpn::Connection ^connection); ~PoserRemote(); + !PoserRemote(); virtual void Update(); virtual Vrpn::Connection^ GetConnection(); @@ -62,6 +63,7 @@ namespace Vrpn { private: ::vrpn_Poser_Remote *m_poser; + System::Boolean m_disposed; void Initialize(System::String ^name, vrpn_Connection *lpConn); }; diff --git a/VrpnNet/Stdafx.h b/VrpnNet/Stdafx.h index 7180e57..31cc42b 100644 --- a/VrpnNet/Stdafx.h +++ b/VrpnNet/Stdafx.h @@ -24,4 +24,8 @@ #pragma once -// We don't have anything interesting in the precompiled headers yet. \ No newline at end of file +#define CHECK_DISPOSAL_STATUS() \ + { \ + if (m_disposed) \ + throw gcnew ObjectDisposedException("VRPN Object"); \ + } \ No newline at end of file diff --git a/VrpnNet/Text.h b/VrpnNet/Text.h index ea86103..565b7b5 100644 --- a/VrpnNet/Text.h +++ b/VrpnNet/Text.h @@ -53,6 +53,7 @@ namespace Vrpn { TextSender(System::String ^name); TextSender(System::String ^name, Vrpn::Connection ^connection); ~TextSender(); + !TextSender(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -78,6 +79,7 @@ namespace Vrpn { private: ::vrpn_Text_Sender *m_sender; + System::Boolean m_disposed; void Initialize(System::String ^name, vrpn_Connection *lpConn); }; @@ -88,6 +90,7 @@ namespace Vrpn { TextReceiver(System::String ^name); TextReceiver(System::String ^name, Vrpn::Connection ^connection); ~TextReceiver(); + !TextReceiver(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -101,6 +104,7 @@ namespace Vrpn { private: ::vrpn_Text_Receiver *m_receiver; + System::Boolean m_disposed; System::Runtime::InteropServices::GCHandle gc_callback; void onTextReceived(void *userData, const vrpn_TEXTCB info); diff --git a/VrpnNet/TextReceiver.cpp b/VrpnNet/TextReceiver.cpp index 890f08a..4b8c257 100644 --- a/VrpnNet/TextReceiver.cpp +++ b/VrpnNet/TextReceiver.cpp @@ -23,13 +23,16 @@ #include "stdafx.h" #include "Text.h" +namespace Vrpn { + namespace Internal { + delegate void TextReceivedCallback(void *userData, const vrpn_TEXTCB info); + } +} + using namespace System; using namespace System::Runtime::InteropServices; using namespace Vrpn; - -namespace { - delegate void TextReceivedCallback(void *userData, const vrpn_TEXTCB info); -} +using namespace Vrpn::Internal; TextReceiver::TextReceiver(String ^name) { @@ -57,32 +60,43 @@ void TextReceiver::Initialize(System::String ^name, vrpn_Connection *lpConn) static_cast(pTextReceipt.ToPointer()); m_receiver->register_message_handler(0, pCallbackFunc); + m_disposed = false; } -TextReceiver::~TextReceiver() +TextReceiver::!TextReceiver() { delete m_receiver; gc_callback.Free(); + m_disposed = true; +} + +TextReceiver::~TextReceiver() +{ + this->!TextReceiver(); } void TextReceiver::Update() { + CHECK_DISPOSAL_STATUS(); m_receiver->mainloop(); } void TextReceiver::MuteWarnings::set(Boolean shutUp) { + CHECK_DISPOSAL_STATUS(); m_receiver->shutup = shutUp; } Boolean TextReceiver::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_receiver->shutup; } Connection^ TextReceiver::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_receiver->connectionPtr()); } diff --git a/VrpnNet/TextSender.cpp b/VrpnNet/TextSender.cpp index 042b566..849259f 100644 --- a/VrpnNet/TextSender.cpp +++ b/VrpnNet/TextSender.cpp @@ -37,9 +37,15 @@ TextSender::TextSender(System::String ^name, Vrpn::Connection ^connection) Initialize(name, connection->ToPointer()); } -TextSender::~TextSender() +TextSender::!TextSender() { delete m_sender; + m_disposed = true; +} + +TextSender::~TextSender() +{ + this->!TextSender(); } void TextSender::Initialize(System::String ^name, vrpn_Connection *lpConn) @@ -50,25 +56,31 @@ void TextSender::Initialize(System::String ^name, vrpn_Connection *lpConn) m_sender = new ::vrpn_Text_Sender(ansiName, lpConn); Marshal::FreeHGlobal(hAnsiName); + + m_disposed = false; } void TextSender::Update() { + CHECK_DISPOSAL_STATUS(); m_sender->mainloop(); } void TextSender::MuteWarnings::set(Boolean shutUp) { + CHECK_DISPOSAL_STATUS(); m_sender->shutup = shutUp; } Boolean TextSender::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_sender->shutup; } Connection^ TextSender::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_sender->connectionPtr()); } @@ -89,6 +101,7 @@ Int32 TextSender::SendMessage(System::String ^message, Vrpn::TextSeverity type, Int32 TextSender::SendMessage(System::String ^message, Vrpn::TextSeverity type, unsigned int level, System::DateTime time) { + CHECK_DISPOSAL_STATUS(); IntPtr hAnsiMessage = Marshal::StringToHGlobalAnsi(message); const char *ansiMessage = static_cast(hAnsiMessage.ToPointer()); diff --git a/VrpnNet/TrackerRemote.cpp b/VrpnNet/TrackerRemote.cpp index 5662c8a..e74fd7f 100644 --- a/VrpnNet/TrackerRemote.cpp +++ b/VrpnNet/TrackerRemote.cpp @@ -25,19 +25,21 @@ #include "quat.h" #include "TrackerRemote.h" +namespace Vrpn { + namespace Internal { + delegate void TrackerChangeCallback(void *userData, const vrpn_TRACKERCB info); + delegate void TrackerVelocityCallback(void *userData, const vrpn_TRACKERVELCB info); + delegate void TrackerAccelCallback(void *userData, const vrpn_TRACKERACCCB info); + delegate void TrackerToRoomCallback(void *userData, const vrpn_TRACKERTRACKER2ROOMCB info); + delegate void TrackerUnitToSensorCallback(void *userData, const vrpn_TRACKERUNIT2SENSORCB info); + delegate void TrackerWorkspaceCallback(void *userData, const vrpn_TRACKERWORKSPACECB info); + } +} + using namespace System; using namespace System::Runtime::InteropServices; - using namespace Vrpn; - -namespace { - delegate void TrackerChangeCallback(void *userData, const vrpn_TRACKERCB info); - delegate void TrackerVelocityCallback(void *userData, const vrpn_TRACKERVELCB info); - delegate void TrackerAccelCallback(void *userData, const vrpn_TRACKERACCCB info); - delegate void TrackerToRoomCallback(void *userData, const vrpn_TRACKERTRACKER2ROOMCB info); - delegate void TrackerUnitToSensorCallback(void *userData, const vrpn_TRACKERUNIT2SENSORCB info); - delegate void TrackerWorkspaceCallback(void *userData, const vrpn_TRACKERWORKSPACECB info); -} +using namespace Vrpn::Internal; TrackerRemote::TrackerRemote(String ^name) { @@ -49,6 +51,8 @@ TrackerRemote::TrackerRemote(String ^name) Marshal::FreeHGlobal(hAnsiName); RegisterHandlers(); + + m_disposed = false; } TrackerRemote::TrackerRemote(String ^name, Connection ^connection) @@ -61,9 +65,11 @@ TrackerRemote::TrackerRemote(String ^name, Connection ^connection) Marshal::FreeHGlobal(hAnsiName); RegisterHandlers(); + + m_disposed = false; } -TrackerRemote::~TrackerRemote() +TrackerRemote::!TrackerRemote() { delete m_tracker; @@ -73,54 +79,70 @@ TrackerRemote::~TrackerRemote() gc_t2rChange.Free(); gc_u2sChange.Free(); gc_boundsChange.Free(); + + m_disposed = true; +} + +TrackerRemote::~TrackerRemote() +{ + this->!TrackerRemote(); } void TrackerRemote::Update() { + CHECK_DISPOSAL_STATUS(); m_tracker->mainloop(); } void TrackerRemote::MuteWarnings::set(Boolean shutUp) { + CHECK_DISPOSAL_STATUS(); m_tracker->shutup = shutUp; } Boolean TrackerRemote::MuteWarnings::get() { + CHECK_DISPOSAL_STATUS(); return m_tracker->shutup; } Connection^ TrackerRemote::GetConnection() { + CHECK_DISPOSAL_STATUS(); return Connection::FromPointer(m_tracker->connectionPtr()); } void TrackerRemote::RequestTrackerToRoomXform() { + CHECK_DISPOSAL_STATUS(); if (m_tracker->request_t2r_xform()) throw gcnew VrpnException(); } void TrackerRemote::RequestUnitToSensorXform() { + CHECK_DISPOSAL_STATUS(); if (m_tracker->request_u2s_xform()) throw gcnew VrpnException(); } void TrackerRemote::RequestWorkspaceBounds() { + CHECK_DISPOSAL_STATUS(); if (m_tracker->request_workspace()) throw gcnew VrpnException(); } void TrackerRemote::UpdateRate::set(Double samplesPerSecond) { + CHECK_DISPOSAL_STATUS(); if (m_tracker->set_update_rate(samplesPerSecond)) throw gcnew VrpnException(); } void TrackerRemote::ResetOrigin() { + CHECK_DISPOSAL_STATUS(); if (m_tracker->reset_origin()) throw gcnew VrpnException(); } diff --git a/VrpnNet/TrackerRemote.h b/VrpnNet/TrackerRemote.h index 2b1c77a..93eac59 100644 --- a/VrpnNet/TrackerRemote.h +++ b/VrpnNet/TrackerRemote.h @@ -95,6 +95,7 @@ namespace Vrpn { TrackerRemote(System::String ^name); TrackerRemote(System::String ^name, Vrpn::Connection ^connection); ~TrackerRemote(); + !TrackerRemote(); virtual void Update(); // from IVrpnObject virtual Connection^ GetConnection(); // from IVrpnObject @@ -124,6 +125,7 @@ namespace Vrpn { private: ::vrpn_Tracker_Remote *m_tracker; + System::Boolean m_disposed; void RegisterHandlers();