···11+mod command;
12mod device;
23mod feature;
33-mod command;
4455+pub use command::*;
56pub use device::*;
67pub use feature::*;
77-pub use command::*;
+14-14
crates/buttplug_client/src/lib.rs
···1616 connector::{ButtplugConnector, ButtplugConnectorError, ButtplugConnectorFuture},
1717 errors::{ButtplugError, ButtplugHandshakeError},
1818 message::{
1919+ BUTTPLUG_CURRENT_API_MAJOR_VERSION,
2020+ BUTTPLUG_CURRENT_API_MINOR_VERSION,
1921 ButtplugClientMessageV4,
2022 ButtplugServerMessageV4,
2123 PingV0,
···2426 StartScanningV0,
2527 StopAllDevicesV0,
2628 StopScanningV0,
2727- BUTTPLUG_CURRENT_API_MAJOR_VERSION,
2828- BUTTPLUG_CURRENT_API_MINOR_VERSION,
2929 },
3030 util::{
3131 async_manager,
···3737use dashmap::DashMap;
3838pub use device::{ButtplugClientDevice, ButtplugClientDeviceEvent};
3939use futures::{
4040- future::{self, BoxFuture, FutureExt},
4140 Stream,
4141+ future::{self, BoxFuture, FutureExt},
4242};
4343use log::*;
4444+use std::{
4545+ collections::BTreeMap,
4646+ sync::{
4747+ Arc,
4848+ atomic::{AtomicBool, Ordering},
4949+ },
5050+};
4451use strum_macros::Display;
4545-use std::{collections::BTreeMap, sync::{
4646- atomic::{AtomicBool, Ordering},
4747- Arc,
4848-}};
4952use thiserror::Error;
5050-use tokio::sync::{broadcast, mpsc, Mutex};
5353+use tokio::sync::{Mutex, broadcast, mpsc};
5154use tracing_futures::Instrument;
52555356/// Result type used for public APIs.
···107110 #[error(transparent)]
108111 ButtplugError(#[from] ButtplugError),
109112 /// Error converting output command: {}
110110- ButtplugOutputCommandConversionError(String)
113113+ ButtplugOutputCommandConversionError(String),
111114}
112115113116/// Enum representing different events that can be emitted by a client.
···270273 client_name: name.to_owned(),
271274 server_name: Arc::new(Mutex::new(None)),
272275 event_stream,
273273- message_sender: ButtplugClientMessageSender::new(
274274- &message_sender,
275275- &connected,
276276- ),
276276+ message_sender: ButtplugClientMessageSender::new(&message_sender, &connected),
277277 connected,
278278 device_map: Arc::new(DashMap::new()),
279279 }
···431431 .send_message_expect_ok(StopAllDevicesV0::default().into())
432432 }
433433434434- pub fn event_stream(&self) -> impl Stream<Item = ButtplugClientEvent> + use<>{
434434+ pub fn event_stream(&self) -> impl Stream<Item = ButtplugClientEvent> + use<> {
435435 let stream = convert_broadcast_receiver_to_stream(self.event_stream.subscribe());
436436 // We can either Box::pin here or force the user to pin_mut!() on their
437437 // end. While this does end up with a dynamic dispatch on our end, it
+14-12
crates/buttplug_client/src/serializer/mod.rs
···11use buttplug_core::message::{
22+ ButtplugClientMessageV4,
33+ ButtplugMessage,
44+ ButtplugMessageFinalizer,
55+ ButtplugServerMessageV4,
26 serializer::{
33- json_serializer::{create_message_validator, deserialize_to_message, vec_to_protocol_json},
47 ButtplugMessageSerializer,
58 ButtplugSerializedMessage,
69 ButtplugSerializerError,
1010+ json_serializer::{create_message_validator, deserialize_to_message, vec_to_protocol_json},
711 },
88- ButtplugClientMessageV4,
99- ButtplugMessage,
1010- ButtplugMessageFinalizer,
1111- ButtplugServerMessageV4,
1212};
1313use jsonschema::Validator;
1414use serde::{Deserialize, Serialize};
···7474mod test {
7575 use super::*;
7676 use buttplug_core::message::{
7777- RequestServerInfoV4,
7877 BUTTPLUG_CURRENT_API_MAJOR_VERSION,
7978 BUTTPLUG_CURRENT_API_MINOR_VERSION,
7979+ RequestServerInfoV4,
8080 };
81818282 #[test]
···102102 "[{\"Ok\":{\"NotAField\":\"NotAValue\",\"Id\":1}}]",
103103 ];
104104 let serializer = ButtplugClientJSONSerializer::default();
105105- let _ = serializer.serialize(&vec![RequestServerInfoV4::new(
106106- "test client",
107107- BUTTPLUG_CURRENT_API_MAJOR_VERSION,
108108- BUTTPLUG_CURRENT_API_MINOR_VERSION,
109109- )
110110- .into()]);
105105+ let _ = serializer.serialize(&vec![
106106+ RequestServerInfoV4::new(
107107+ "test client",
108108+ BUTTPLUG_CURRENT_API_MAJOR_VERSION,
109109+ BUTTPLUG_CURRENT_API_MINOR_VERSION,
110110+ )
111111+ .into(),
112112+ ]);
111113 for msg in incorrect_incoming_messages {
112114 let res = serializer.deserialize(&ButtplugSerializedMessage::Text(msg.to_owned()));
113115 assert!(res.is_err(), "{} should be an error", msg);
···1111pub mod async_manager;
1212pub mod future;
1313pub mod json;
1414-pub mod stream;
1514pub mod range_serialize;
1515+pub mod stream;
16161717#[cfg(not(feature = "wasm"))]
1818pub use tokio::time::sleep;
···55// Licensed under the BSD 3-Clause license. See LICENSE file in the project root
66// for full license information.
7788-use crate::device::protocol::{generic_protocol_setup, ProtocolHandler};
88+use crate::device::protocol::{ProtocolHandler, generic_protocol_setup};
991010generic_protocol_setup!(RawProtocol, "raw");
1111
···99//! specific) Managers
10101111use crate::{
1212+ ButtplugServerError,
1313+ ButtplugServerResultFuture,
1214 device::{
1515+ ServerDevice,
1316 hardware::communication::{HardwareCommunicationManager, HardwareCommunicationManagerBuilder},
1417 server_device_manager_event_loop::ServerDeviceManagerEventLoop,
1515- ServerDevice,
1618 },
1719 message::{
1820 server_device_attributes::ServerDeviceAttributes,
···2224 ButtplugDeviceManagerMessageUnion,
2325 },
2426 },
2525- ButtplugServerError,
2626- ButtplugServerResultFuture,
2727};
2828use buttplug_core::{
2929 errors::{ButtplugDeviceError, ButtplugMessageError, ButtplugUnknownError},
···3333use buttplug_server_device_config::{DeviceConfigurationManager, UserDeviceIdentifier};
3434use dashmap::DashMap;
3535use futures::{
3636- future::{self, FutureExt},
3736 Stream,
3737+ future::{self, FutureExt},
3838};
3939use getset::Getters;
4040use std::{
4141 collections::HashMap,
4242 convert::TryFrom,
4343 sync::{
4444- atomic::{AtomicBool, Ordering},
4544 Arc,
4545+ atomic::{AtomicBool, Ordering},
4646 },
4747};
4848use tokio::sync::{broadcast, mpsc};
···131131 }
132132 }
133133 if colliding_dcms.len() > 1 {
134134- warn!("The following device connection methods may collide: {}. This may mean you have lovense dongles and bluetooth dongles connected at the same time. Please disconnect the lovense dongles or turn off the Lovense HID/Serial Dongle support in Intiface/Buttplug. Lovense devices will work with the Bluetooth dongle.", colliding_dcms.join(", "));
134134+ warn!(
135135+ "The following device connection methods may collide: {}. This may mean you have lovense dongles and bluetooth dongles connected at the same time. Please disconnect the lovense dongles or turn off the Lovense HID/Serial Dongle support in Intiface/Buttplug. Lovense devices will work with the Bluetooth dongle.",
136136+ colliding_dcms.join(", ")
137137+ );
135138 }
136139137140 let devices = Arc::new(DashMap::new());
···294297 pub fn device_info(&self, index: u32) -> Option<ServerDeviceInfo> {
295298 self.devices.get(&index).map(|device| ServerDeviceInfo {
296299 identifier: device.value().identifier().clone(),
297297- display_name: device
298298- .value()
299299- .definition()
300300- .display_name()
301301- .clone(),
300300+ display_name: device.value().definition().display_name().clone(),
302301 })
303302 }
304303
···1313use tracing::info_span;
14141515use crate::device::{
1616- hardware::communication::{HardwareCommunicationManager, HardwareCommunicationManagerEvent},
1716 ServerDevice,
1817 ServerDeviceEvent,
1919- protocol::ProtocolManager
1818+ hardware::communication::{HardwareCommunicationManager, HardwareCommunicationManagerEvent},
1919+ protocol::ProtocolManager,
2020};
2121use dashmap::{DashMap, DashSet};
2222-use futures::{future, pin_mut, FutureExt, StreamExt};
2323-use std::sync::{atomic::AtomicBool, Arc};
2222+use futures::{FutureExt, StreamExt, future, pin_mut};
2323+use std::sync::{Arc, atomic::AtomicBool};
2424use tokio::sync::{broadcast, mpsc};
2525use tokio_util::sync::CancellationToken;
2626use tracing_futures::Instrument;
···137137 "System signaled that scanning was finished, check to see if all managers are finished."
138138 );
139139 if self.scanning_bringup_in_progress {
140140- debug!("Hardware Comm Manager finished before scanning was fully started, continuing event loop.");
140140+ debug!(
141141+ "Hardware Comm Manager finished before scanning was fully started, continuing event loop."
142142+ );
141143 return;
142144 }
143145 // Only send scanning finished if we haven't requested a stop.
···194196 //
195197 // We used to do this in build_server_device, but we shouldn't mark devices as actually
196198 // connecting until after this happens, so we're moving it back here.
197197- let protocol_specializers = self
198198- .protocol_manager
199199- .protocol_specializers(
200200- &creator.specifier(),
201201- self.device_config_manager.base_communication_specifiers(),
202202- self.device_config_manager.user_communication_specifiers()
203203- );
199199+ let protocol_specializers = self.protocol_manager.protocol_specializers(
200200+ &creator.specifier(),
201201+ self.device_config_manager.base_communication_specifiers(),
202202+ self.device_config_manager.user_communication_specifiers(),
203203+ );
204204205205 // If we have no identifiers, then there's nothing to do here. Throw an error.
206206 if protocol_specializers.is_empty() {
···285285 // address), consider it disconnected and eject it from the map. This
286286 // should also trigger a disconnect event before our new DeviceAdded
287287 // message goes out, so timing matters here.
288288- match self.device_map.remove(&device_index) { Some((_, old_device)) => {
289289- info!("Device map contains key {}.", device_index);
290290- // After removing the device from the array, manually disconnect it to
291291- // make sure the event is thrown.
292292- if let Err(err) = old_device.disconnect().await {
293293- // If we throw an error during the disconnect, we can't really do
294294- // anything with it, but should at least log it.
295295- error!("Error during index collision disconnect: {:?}", err);
288288+ match self.device_map.remove(&device_index) {
289289+ Some((_, old_device)) => {
290290+ info!("Device map contains key {}.", device_index);
291291+ // After removing the device from the array, manually disconnect it to
292292+ // make sure the event is thrown.
293293+ if let Err(err) = old_device.disconnect().await {
294294+ // If we throw an error during the disconnect, we can't really do
295295+ // anything with it, but should at least log it.
296296+ error!("Error during index collision disconnect: {:?}", err);
297297+ }
298298+ }
299299+ _ => {
300300+ info!("Device map does not contain key {}.", device_index);
296301 }
297297- } _ => {
298298- info!("Device map does not contain key {}.", device_index);
299299- }}
302302+ }
300303301304 // Create event loop for forwarding device events into our selector.
302305 let event_listener = device.event_stream();
···341344 .remove(&device_index)
342345 .expect("Remove will always work.");
343346 let device_update_message: ButtplugServerMessageV4 = self.generate_device_list().into();
344344- if self
345345- .server_sender
346346- .send(device_update_message)
347347- .is_err()
348348- {
347347+ if self.server_sender.send(device_update_message).is_err() {
349348 debug!("Server not currently available, dropping Device Removed event.");
350349 }
351350 }
···55// Licensed under the BSD 3-Clause license. See LICENSE file in the project root
66// for full license information.
7788-use super::{device_message_info::DeviceMessageInfoV2, ClientDeviceMessageAttributesV2};
88+use super::{ClientDeviceMessageAttributesV2, device_message_info::DeviceMessageInfoV2};
99use crate::message::v1::{DeviceAddedV1, DeviceMessageInfoV1};
1010use buttplug_core::{
1111 errors::ButtplugMessageError,
···107107 if let Some(output_map) = feature.output() {
108108 let output_type = cmd.command().as_output_type();
109109 let value = cmd.command().value();
110110- let new_value = output_map.calculate_from_value(output_type, value as i32).map_err(|_| ButtplugDeviceError::DeviceStepRangeError(0, value))?;
110110+ let new_value = output_map
111111+ .calculate_from_value(output_type, value as i32)
112112+ .map_err(|_| ButtplugDeviceError::DeviceStepRangeError(0, value))?;
111113 let mut new_command = cmd.command();
112114 new_command.set_value(new_value as u32);
113115 // We can't make a private trait impl to turn a ValueCmd into a CheckedValueCmd, and this
···158158pub use endpoint::*;
159159use uuid::Uuid;
160160161161-162161use thiserror::Error;
163162164163#[derive(Error, Debug)]
···182181 #[error("Output type {0} not available on device")]
183182 InvalidOutput(OutputType),
184183 #[error("Float value {0} is not 0 < x < 1")]
185185- InvalidFloatConversion(f64)
184184+ InvalidFloatConversion(f64),
186185}
···1515use std::{
1616 collections::HashMap,
1717 sync::{
1818- atomic::{AtomicBool, Ordering},
1918 Arc,
1919+ atomic::{AtomicBool, Ordering},
2020 },
2121 time::Duration,
2222};
···206206 } else {
207207 if adapter_found {
208208 self.adapter_connected.store(false, Ordering::Relaxed);
209209- warn!("Bluetooth LE adapter not found, will not be using bluetooth scanning until found. Buttplug will continue polling for the adapter, but no more warning messages will be posted.");
209209+ warn!(
210210+ "Bluetooth LE adapter not found, will not be using bluetooth scanning until found. Buttplug will continue polling for the adapter, but no more warning messages will be posted."
211211+ );
210212 }
211213 continue;
212214 }
···11use std::collections::HashMap;
2233-use buttplug_client::{connector::ButtplugRemoteClientConnector, serializer::ButtplugClientJSONSerializer, ButtplugClient, ButtplugClientError};
33+use buttplug_client::{
44+ ButtplugClient,
55+ ButtplugClientError,
66+ connector::ButtplugRemoteClientConnector,
77+ serializer::ButtplugClientJSONSerializer,
88+};
49510use buttplug_core::message::OutputType;
611use buttplug_transport_websocket_tungstenite::ButtplugWebsocketClientTransport;
···4550 for (_, device) in client.devices() {
4651 println!("{} supports these outputs:", device.name());
4752 for output_type in OutputType::iter() {
4848- for (_, feature) in device.device_features() {
4949- if let Some(output) = feature.feature().output() && output.contains(output_type) {
5353+ for (_, feature) in device.device_features() {
5454+ if let Some(output) = feature.feature().output()
5555+ && output.contains(output_type)
5656+ {
5057 println!("- {}", output_type);
5158 }
5259 }
···6673 // We can use the convenience functions on ButtplugClientDevice to
6774 // send the message. This version sets all of the motors on a
6875 // vibrating device to the same speed.
6969- test_client_device
7070- .vibrate(10)
7171- .await?;
7676+ test_client_device.vibrate(10).await?;
72777378 // If we wanted to just set one motor on and the other off, we could
7479 // try this version that uses an array. It'll throw an exception if
···7782 //
7883 // You can get the vibrator count using the following code, though we
7984 // know it's 2 so we don't really have to use it.
8080- let vibrator_count = test_client_device
8181- .vibrate_features()
8282- .len();
8585+ let vibrator_count = test_client_device.vibrate_features().len();
83868487 println!(
8588 "{} has {} vibrators.",
···89929093 // Just set all of the vibrators to full speed.
9194 if vibrator_count > 0 {
9292- test_client_device
9393- .vibrate(10)
9494- .await?;
9595+ test_client_device.vibrate(10).await?;
9596 } else {
9697 println!("Device does not have > 1 vibrators, not running multiple vibrator test.");
9798 }
···103104 println!("Trying error");
104105 // If we try to send a command to a device after the client has
105106 // disconnected, we'll get an exception thrown.
106106- let vibrate_result = test_client_device
107107- .vibrate(30)
108108- .await;
107107+ let vibrate_result = test_client_device.vibrate(30).await;
109108 if let Err(ButtplugClientError::ButtplugConnectorError(error)) = vibrate_result {
110109 println!("Tried to send after disconnection! Error: ");
111110 println!("{}", error);
···11use buttplug_client::ButtplugClient;
22-use buttplug_server::{device::ServerDeviceManagerBuilder, ButtplugServerBuilder};
22+use buttplug_client_in_process::{ButtplugInProcessClientConnectorBuilder, in_process_client};
33+use buttplug_server::{ButtplugServerBuilder, device::ServerDeviceManagerBuilder};
34use buttplug_server_device_config::DeviceConfigurationManagerBuilder;
45use buttplug_server_hwmgr_btleplug::BtlePlugCommunicationManagerBuilder;
55-use buttplug_client_in_process::{ButtplugInProcessClientConnectorBuilder, in_process_client};
6677#[allow(dead_code)]
88async fn main_the_hard_way() -> anyhow::Result<()> {
···1414 device_manager_builder.comm_manager(BtlePlugCommunicationManagerBuilder::default());
15151616 // This is how we add Bluetooth manually. (We could also do this with any other communication manager.)
1717-1818- let server = ButtplugServerBuilder::new(device_manager_builder.finish().unwrap()).finish().unwrap();
1717+1818+ let server = ButtplugServerBuilder::new(device_manager_builder.finish().unwrap())
1919+ .finish()
2020+ .unwrap();
19212022 // First off, we'll set up our Embedded Connector.
2123 let connector = ButtplugInProcessClientConnectorBuilder::default()