Buttplug sex toy control library
1// Buttplug Rust Source Code File - See https://buttplug.io for more info. 2// 3// Copyright 2016-2024 Nonpolynomial Labs LLC. All rights reserved. 4// 5// Licensed under the BSD 3-Clause license. See LICENSE file in the project root 6// for full license information. 7 8use std::sync::atomic::{AtomicU8, Ordering}; 9 10use uuid::{Uuid, uuid}; 11 12use crate::device::{ 13 hardware::{HardwareCommand, HardwareWriteCmd}, 14 protocol::{ProtocolHandler, generic_protocol_setup}, 15}; 16use buttplug_core::errors::ButtplugDeviceError; 17use buttplug_server_device_config::Endpoint; 18 19const JEJOUE_PROTOCOL_UUID: Uuid = uuid!("d3dd2bf5-b029-4bc1-9466-39f82c2e3258"); 20generic_protocol_setup!(JeJoue, "jejoue"); 21 22pub struct JeJoue { 23 speeds: [AtomicU8; 2], 24} 25 26impl Default for JeJoue { 27 fn default() -> Self { 28 Self { 29 speeds: [AtomicU8::new(0), AtomicU8::new(0)], 30 } 31 } 32} 33 34impl ProtocolHandler for JeJoue { 35 fn handle_output_vibrate_cmd( 36 &self, 37 feature_index: u32, 38 _feature_id: Uuid, 39 speed: u32, 40 ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 41 self.speeds[feature_index as usize].store(speed as u8, Ordering::Relaxed); 42 43 // Default to both vibes 44 let mut pattern: u8 = 1; 45 46 // Use vibe 1 as speed 47 let mut speed = self.speeds[0].load(Ordering::Relaxed); 48 let vibe1_running = speed > 0; 49 let mut vibe2_running = false; 50 // Unless it's zero, then give vibe 2 a chance 51 if !vibe1_running { 52 speed = self.speeds[1].load(Ordering::Relaxed); 53 54 // If we've vibing on 2 only, then change the pattern 55 if speed != 0 { 56 vibe2_running = true; 57 pattern = 3; 58 } 59 } 60 61 // If we've vibing on 1 only, then change the pattern 62 if pattern == 1 && speed != 0 && !vibe2_running { 63 pattern = 2; 64 } 65 66 Ok(vec![ 67 HardwareWriteCmd::new( 68 &[JEJOUE_PROTOCOL_UUID], 69 Endpoint::Tx, 70 vec![pattern, speed], 71 false, 72 ) 73 .into(), 74 ]) 75 } 76}