diff options
-rw-r--r-- | proto-simconnect/ftnoir_protocol_sc.cpp | 82 | ||||
-rw-r--r-- | proto-simconnect/ftnoir_protocol_sc.h | 9 |
2 files changed, 72 insertions, 19 deletions
diff --git a/proto-simconnect/ftnoir_protocol_sc.cpp b/proto-simconnect/ftnoir_protocol_sc.cpp index c8df0443..9c0f1a5b 100644 --- a/proto-simconnect/ftnoir_protocol_sc.cpp +++ b/proto-simconnect/ftnoir_protocol_sc.cpp @@ -12,8 +12,9 @@ #include "ftnoir_protocol_sc.h" #include "api/plugin-api.hpp" #include "opentrack-library-path.h" +#include "compat/timer.hpp" -simconnect::simconnect() : should_stop(false), hSimConnect(nullptr) +simconnect::simconnect() : hSimConnect(nullptr), should_stop(false), should_reconnect(false) { } @@ -35,21 +36,57 @@ void simconnect::run() while (!should_stop) { - if (SUCCEEDED(simconnect_open(&hSimConnect, "opentrack", NULL, 0, event, 0))) + HRESULT hr; + + qDebug() << "simconnect: starting"; + + if (SUCCEEDED(hr = simconnect_open(&hSimConnect, "opentrack", nullptr, 0, event, 0))) { - simconnect_subscribetosystemevent(hSimConnect, 0, "Frame"); + if (!SUCCEEDED(hr = simconnect_subscribetosystemevent(hSimConnect, 0, "Frame"))) + { + qDebug() << "simconnect: can't subscribe to frame event:" << hr; + + should_reconnect = true; // will free simconnect handle and continue the loop + } + + Timer tm; + int idle_seconds = 0; while (!should_stop) { + if (should_reconnect) + { + should_reconnect = false; + break; + } + if (WaitForSingleObject(event, 10) == WAIT_OBJECT_0) { - if (FAILED(simconnect_calldispatch(hSimConnect, processNextSimconnectEvent, reinterpret_cast<void*>(this)))) + tm.start(); + idle_seconds = 0; + + if (!SUCCEEDED(hr = simconnect_calldispatch(hSimConnect, processNextSimconnectEvent, reinterpret_cast<void*>(this)))) + { + qDebug() << "simconnect: calldispatch failed:" << hr; break; + } + } + else + { + if (int(tm.elapsed_seconds()) > idle_seconds) + { + idle_seconds++; + qDebug() << "simconnect: can't process event for" << int(tm.elapsed_seconds()) << "seconds"; + } } } (void) simconnect_close(hSimConnect); } + else + { + qDebug() << "simconnect: can't open handle:" << hr; + } if (!should_stop) Sleep(100); @@ -74,9 +111,12 @@ void simconnect::pose( const double *headpose ) { # pragma GCC diagnostic ignored "-Wmissing-field-initializers" #endif -class ActivationContext { +class ActivationContext +{ public: - ActivationContext(const int resid) : ok(false) { + ActivationContext(const int resid) : + ok(false) + { hactctx = INVALID_HANDLE_VALUE; actctx_cookie = 0; ACTCTXA actx = {0}; @@ -94,16 +134,18 @@ public: actx.lpSource = name.constData(); hactctx = CreateActCtxA(&actx); actctx_cookie = 0; - if (hactctx != INVALID_HANDLE_VALUE) { - if (!ActivateActCtx(hactctx, &actctx_cookie)) { - qDebug() << "SC: can't set win32 activation context" << GetLastError(); + if (hactctx != INVALID_HANDLE_VALUE) + { + if (!ActivateActCtx(hactctx, &actctx_cookie)) + { + qDebug() << "simconnect: can't set win32 activation context" << GetLastError(); ReleaseActCtx(hactctx); hactctx = INVALID_HANDLE_VALUE; } else ok = true; } else { - qDebug() << "SC: can't create win32 activation context" << GetLastError(); + qDebug() << "simconnect: can't create win32 activation context" << GetLastError(); } } ~ActivationContext() { @@ -113,7 +155,8 @@ public: ReleaseActCtx(hactctx); } } - bool is_ok() { return ok; } + bool is_ok() const { return ok; } + private: ULONG_PTR actctx_cookie; HANDLE hactctx; @@ -130,7 +173,7 @@ bool simconnect::correct() { SCClientLib.setFileName("SimConnect.dll"); if (!SCClientLib.load()) { - qDebug() << "SC load" << SCClientLib.errorString(); + qDebug() << "simconnect: dll load failed --" << SCClientLib.errorString(); return false; } } @@ -140,29 +183,29 @@ bool simconnect::correct() simconnect_open = (importSimConnect_Open) SCClientLib.resolve("SimConnect_Open"); if (simconnect_open == NULL) { - qDebug() << "simconnect::correct() says: SimConnect_Open function not found in DLL!"; + qDebug() << "simconnect: SimConnect_Open function not found in DLL!"; return false; } simconnect_set6DOF = (importSimConnect_CameraSetRelative6DOF) SCClientLib.resolve("SimConnect_CameraSetRelative6DOF"); if (simconnect_set6DOF == NULL) { - qDebug() << "simconnect::correct() says: SimConnect_CameraSetRelative6DOF function not found in DLL!"; + qDebug() << "simconnect: SimConnect_CameraSetRelative6DOF function not found in DLL!"; return false; } simconnect_close = (importSimConnect_Close) SCClientLib.resolve("SimConnect_Close"); if (simconnect_close == NULL) { - qDebug() << "simconnect::correct() says: SimConnect_Close function not found in DLL!"; + qDebug() << "simconnect: SimConnect_Close function not found in DLL!"; return false; } simconnect_calldispatch = (importSimConnect_CallDispatch) SCClientLib.resolve("SimConnect_CallDispatch"); if (simconnect_calldispatch == NULL) { - qDebug() << "simconnect::correct() says: SimConnect_CallDispatch function not found in DLL!"; + qDebug() << "simconnect: SimConnect_CallDispatch function not found in DLL!"; return false; } simconnect_subscribetosystemevent = (importSimConnect_SubscribeToSystemEvent) SCClientLib.resolve("SimConnect_SubscribeToSystemEvent"); if (simconnect_subscribetosystemevent == NULL) { - qDebug() << "simconnect::correct() says: SimConnect_SubscribeToSystemEvent function not found in DLL!"; + qDebug() << "simconnect: SimConnect_SubscribeToSystemEvent function not found in DLL!"; return false; } @@ -184,6 +227,11 @@ void CALLBACK simconnect::processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWO { default: break; + case SIMCONNECT_RECV_ID_EXCEPTION: + case SIMCONNECT_RECV_ID_QUIT: + self.should_reconnect = true; + qDebug() << "simconnect: received ID_QUIT event"; + break; case SIMCONNECT_RECV_ID_EVENT_FRAME: self.handle(); break; diff --git a/proto-simconnect/ftnoir_protocol_sc.h b/proto-simconnect/ftnoir_protocol_sc.h index ff664351..270d922d 100644 --- a/proto-simconnect/ftnoir_protocol_sc.h +++ b/proto-simconnect/ftnoir_protocol_sc.h @@ -44,7 +44,12 @@ public: return "FS2004/FSX"; } private: - enum { SIMCONNECT_RECV_ID_EVENT_FRAME = 7 }; + enum { + SIMCONNECT_RECV_ID_NULL, + SIMCONNECT_RECV_ID_EXCEPTION = 2, + SIMCONNECT_RECV_ID_QUIT = 3, + SIMCONNECT_RECV_ID_EVENT_FRAME = 7, + }; #pragma pack(push, 1) struct SIMCONNECT_RECV @@ -64,7 +69,6 @@ private: typedef HRESULT (WINAPI *importSimConnect_SubscribeToSystemEvent)(HANDLE hSimConnect, DWORD EventID, const char * SystemEventName); void run() override; - volatile bool should_stop; volatile float virtSCPosX; volatile float virtSCPosY; @@ -80,6 +84,7 @@ private: importSimConnect_SubscribeToSystemEvent simconnect_subscribetosystemevent; HANDLE hSimConnect; + volatile bool should_stop, should_reconnect; static void CALLBACK processNextSimconnectEvent(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext); settings s; QLibrary SCClientLib; |