Try to build a [ButtplugServer] using the parameters given.
(&self)
| 87 | |
| 88 | /// Try to build a [ButtplugServer] using the parameters given. |
| 89 | pub fn finish(&self) -> Result<ButtplugServer, ButtplugServerError> { |
| 90 | // Create the server |
| 91 | debug!("Creating server '{}'", self.name); |
| 92 | |
| 93 | // Set up our channels to different parts of the system. |
| 94 | let (output_sender, _) = broadcast::channel(256); |
| 95 | |
| 96 | // Connection state - starts in AwaitingHandshake |
| 97 | let state = Arc::new(RwLock::new(ConnectionState::default())); |
| 98 | |
| 99 | let ping_time = self.max_ping_time.unwrap_or(0); |
| 100 | |
| 101 | // Create the ping timeout callback if ping time is configured. |
| 102 | // The callback handles: updating state, stopping devices, and sending error. |
| 103 | let ping_timeout_callback = if ping_time > 0 { |
| 104 | let state_clone = state.clone(); |
| 105 | let device_manager_clone = self.device_manager.clone(); |
| 106 | let output_sender_clone = output_sender.clone(); |
| 107 | |
| 108 | Some(move || { |
| 109 | error!("Ping out signal received, stopping server"); |
| 110 | // Update connection state to PingedOut |
| 111 | { |
| 112 | let mut state_guard = state_clone.write().expect("State lock poisoned"); |
| 113 | *state_guard = ConnectionState::PingedOut; |
| 114 | } |
| 115 | // Stop all devices (spawn async task since callback is sync) |
| 116 | buttplug_core::spawn!("PingTimeoutStopDevices", async move { |
| 117 | if let Err(e) = device_manager_clone |
| 118 | .stop_devices(&StopCmdV4::default()) |
| 119 | .await |
| 120 | { |
| 121 | error!("Could not stop devices on ping timeout: {:?}", e); |
| 122 | } |
| 123 | }); |
| 124 | // Send error to output channel |
| 125 | if output_sender_clone |
| 126 | .send(ButtplugServerMessageV4::Error(message::ErrorV0::from( |
| 127 | ButtplugError::from(ButtplugPingError::PingedOut), |
| 128 | ))) |
| 129 | .is_err() |
| 130 | { |
| 131 | error!("Server disappeared, cannot update about ping out."); |
| 132 | }; |
| 133 | }) |
| 134 | } else { |
| 135 | None |
| 136 | }; |
| 137 | |
| 138 | let ping_timer = Arc::new(PingTimer::new(ping_time, ping_timeout_callback)); |
| 139 | |
| 140 | // Assuming everything passed, return the server. |
| 141 | Ok(ButtplugServer::new( |
| 142 | &self.name, |
| 143 | ping_time, |
| 144 | ping_timer, |
| 145 | self.device_manager.clone(), |
| 146 | state, |