summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--proto-simconnect/ftnoir_protocol_sc.cpp82
-rw-r--r--proto-simconnect/ftnoir_protocol_sc.h9
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;