1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use super::{ButtplugDeviceResultFuture, ButtplugProtocol, ButtplugProtocolCommandHandler};
use crate::{
core::{
errors::ButtplugMessageError,
messages::{self, ButtplugDeviceCommandMessageUnion, DeviceMessageAttributesMap},
},
device::{
protocol::{generic_command_manager::GenericCommandManager, ButtplugProtocolProperties},
DeviceImpl,
DeviceWriteCmd,
Endpoint,
},
};
use byteorder::{LittleEndian, WriteBytesExt};
use std::sync::Arc;
super::default_protocol_definition!(XInput);
impl ButtplugProtocol for XInput {
fn try_create(
device_impl: Arc<crate::device::DeviceImpl>,
config: crate::device::protocol::DeviceProtocolConfiguration,
) -> futures::future::BoxFuture<
'static,
Result<Box<dyn ButtplugProtocol>, crate::core::errors::ButtplugError>,
> {
Box::pin(async move {
let (mut name, attrs) =
crate::device::protocol::get_protocol_features(device_impl.clone(), None, config)?;
name = format!(
"{} {}",
name,
device_impl
.address()
.chars()
.last()
.expect("We already set the address before getting here")
);
Ok(Box::new(Self::new(&name, attrs)) as Box<dyn ButtplugProtocol>)
})
}
}
impl ButtplugProtocolCommandHandler for XInput {
fn handle_vibrate_cmd(
&self,
device: Arc<DeviceImpl>,
msg: messages::VibrateCmd,
) -> ButtplugDeviceResultFuture {
let manager = self.manager.clone();
Box::pin(async move {
let result = manager.lock().await.update_vibration(&msg, true);
match result {
Ok(cmds_option) => {
let mut fut_vec = vec![];
if let Some(cmds) = cmds_option {
let mut cmd = vec![];
if cmd
.write_u16::<LittleEndian>(
cmds[1].expect("GCM uses match_all, we'll always get 2 values") as u16,
)
.is_err()
|| cmd
.write_u16::<LittleEndian>(
cmds[0].expect("GCM uses match_all, we'll always get 2 values") as u16,
)
.is_err()
{
return Err(
ButtplugMessageError::MessageConversionError(
"Cannot convert XInput value for processing".to_owned(),
)
.into(),
);
}
fut_vec.push(device.write_value(DeviceWriteCmd::new(Endpoint::Tx, cmd, false)));
}
for fut in fut_vec {
fut.await?;
}
Ok(messages::Ok::default().into())
}
Err(e) => Err(e),
}
})
}
}