11#include " DeviceManager.hpp"
22#include " ../../../common/Logger.hpp"
3+ #include < thread>
4+ #include < chrono>
35
46namespace StayPutVR {
57 bool DeviceManager::Initialize () {
6- // Connect to IPC server
7- if (!ipc_client_.Connect ()) {
8- if (Logger::IsInitialized ()) {
9- Logger::Error (" Failed to connect to driver IPC server" );
10- }
11- return false ;
12- }
13-
14- // Set device update callback
8+ // Set device update callback first
159 ipc_client_.SetDeviceUpdateCallback ([this ](const std::vector<DevicePositionData>& devices) {
1610 this ->OnDeviceUpdate (devices);
1711 });
1812
19- return true ;
13+ // Try initial connection
14+ if (ipc_client_.Connect ()) {
15+ if (Logger::IsInitialized ()) {
16+ Logger::Info (" DeviceManager: Successfully connected to driver IPC server" );
17+ }
18+ return true ;
19+ }
20+
21+ // If initial connection fails, start auto-reconnection if enabled
22+ if (auto_reconnect_enabled_) {
23+ if (Logger::IsInitialized ()) {
24+ Logger::Warning (" DeviceManager: Initial connection failed, starting auto-reconnection" );
25+ }
26+ StartReconnectThread ();
27+ // Return true to allow application to continue running
28+ return true ;
29+ } else {
30+ if (Logger::IsInitialized ()) {
31+ Logger::Error (" DeviceManager: Failed to connect to driver IPC server and auto-reconnect is disabled" );
32+ }
33+ return false ;
34+ }
2035 }
2136
2237 void DeviceManager::Shutdown () {
38+ StopReconnectThread ();
2339 ipc_client_.Disconnect ();
2440 }
2541
@@ -30,6 +46,14 @@ namespace StayPutVR {
3046 void DeviceManager::Update () {
3147 // Process IPC messages
3248 ipc_client_.ProcessMessages ();
49+
50+ // Check for connection loss and start reconnection if needed
51+ if (auto_reconnect_enabled_ && !ipc_client_.IsConnected () && !reconnect_thread_running_) {
52+ if (Logger::IsInitialized ()) {
53+ Logger::Warning (" DeviceManager: Connection lost, starting auto-reconnection" );
54+ }
55+ StartReconnectThread ();
56+ }
3357 }
3458
3559 const std::vector<DevicePositionData>& DeviceManager::GetDevices () const {
@@ -52,4 +76,111 @@ namespace StayPutVR {
5276 device_map_[devices_[i].serial ] = i;
5377 }
5478 }
79+
80+ void DeviceManager::StartReconnectThread () {
81+ if (reconnect_thread_running_) {
82+ return ; // Already running
83+ }
84+
85+ // Ensure any previous thread is fully cleaned up
86+ if (reconnect_thread_.joinable ()) {
87+ reconnect_thread_.join ();
88+ }
89+
90+ reconnect_thread_running_ = true ;
91+ last_reconnect_attempt_ = std::chrono::steady_clock::now ();
92+ reconnect_thread_ = std::thread (&DeviceManager::ReconnectThreadFunction, this );
93+
94+ if (Logger::IsInitialized ()) {
95+ Logger::Info (" DeviceManager: Auto-reconnection thread started" );
96+ }
97+ }
98+
99+ void DeviceManager::StopReconnectThread () {
100+ if (!reconnect_thread_running_) {
101+ return ; // Not running
102+ }
103+
104+ reconnect_thread_running_ = false ;
105+
106+ if (reconnect_thread_.joinable ()) {
107+ reconnect_thread_.join ();
108+ }
109+
110+ if (Logger::IsInitialized ()) {
111+ Logger::Info (" DeviceManager: Auto-reconnection thread stopped" );
112+ }
113+ }
114+
115+ void DeviceManager::ReconnectThreadFunction () {
116+ if (Logger::IsInitialized ()) {
117+ Logger::Info (" DeviceManager: Reconnection thread started" );
118+ }
119+
120+ // Wait initial delay before first reconnection attempt
121+ std::this_thread::sleep_for (INITIAL_RECONNECT_DELAY);
122+
123+ while (reconnect_thread_running_ && auto_reconnect_enabled_) {
124+ if (!ipc_client_.IsConnected ()) {
125+ auto now = std::chrono::steady_clock::now ();
126+ if (now - last_reconnect_attempt_ >= RECONNECT_INTERVAL) {
127+ if (TryReconnect ()) {
128+ if (Logger::IsInitialized ()) {
129+ Logger::Info (" DeviceManager: Successfully reconnected to driver" );
130+ }
131+ break ; // Exit thread on successful connection
132+ }
133+ last_reconnect_attempt_ = now;
134+ }
135+ } else {
136+ // Already connected, exit thread
137+ break ;
138+ }
139+
140+ // Sleep briefly before next check
141+ std::this_thread::sleep_for (std::chrono::milliseconds (500 ));
142+ }
143+
144+ reconnect_thread_running_ = false ;
145+ if (Logger::IsInitialized ()) {
146+ Logger::Info (" DeviceManager: Reconnection thread exiting" );
147+ }
148+ }
149+
150+ bool DeviceManager::TryReconnect () {
151+ if (Logger::IsInitialized ()) {
152+ Logger::Debug (" DeviceManager: Attempting to reconnect to driver..." );
153+ }
154+
155+ // Ensure clean state before reconnecting
156+ if (ipc_client_.IsConnected ()) {
157+ ipc_client_.Disconnect ();
158+ // Brief delay to ensure cleanup completes
159+ std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
160+ }
161+
162+ return ipc_client_.Connect ();
163+ }
164+
165+ bool DeviceManager::ManualReconnect () {
166+ if (Logger::IsInitialized ()) {
167+ Logger::Info (" DeviceManager: Manual reconnection requested" );
168+ }
169+
170+ // Stop auto-reconnection thread to avoid conflicts
171+ StopReconnectThread ();
172+
173+ // Try to reconnect
174+ bool success = TryReconnect ();
175+
176+ // If manual reconnection fails and auto-reconnect is enabled, restart the thread
177+ if (!success && auto_reconnect_enabled_) {
178+ if (Logger::IsInitialized ()) {
179+ Logger::Info (" DeviceManager: Manual reconnection failed, restarting auto-reconnection" );
180+ }
181+ StartReconnectThread ();
182+ }
183+
184+ return success;
185+ }
55186}
0 commit comments