class Buttplug::Device
This class creates a Wrapper for your various devices you fetched from listDevices for your controlling pleasure!
Public Class Methods
Creates our Device
wrapper for our client
Note: This does create a few functions on the fly. you should check to see if they are available using .methods.include
Arguments:
-
client (
Buttplug::Client
) - Our buttplugrb client that we are gonna use to control our device -
deviceInfo (Hash) - Our information that we should have fetched from the list_devices() instance method β¦ should look like:
{"DeviceName"=>"XBox Compatible Gamepad (XInput)", "DeviceIndex"=>1, "DeviceMessages"=>{"SingleMotorVibrateCmd"=>{}, "VibrateCmd"=>{"FeatureCount"=>2}, "StopDeviceCmd"=>{}}}
Returns:
-
Our nicely bundled up device ready to be domminated~
# File lib/buttplugrb.rb, line 217 def initialize(client, deviceInfo) #Ok we are gonna expect our deviceInfo to be a Hash so we can do some ... fun things ... #{"DeviceName"=>"XBox Compatible Gamepad (XInput)", "DeviceIndex"=>1, "DeviceMessages"=>{"SingleMotorVibrateCmd"=>{}, "VibrateCmd"=>{"FeatureCount"=>2} @deviceName=deviceInfo["DeviceName"] @deviceIndex=deviceInfo["DeviceIndex"] @client=client #Ok so we are starting our weird metaProgramming BS here if(deviceInfo["DeviceMessages"].keys.include? "VibrateCmd") @vibeMotors=deviceInfo["DeviceMessages"]["VibrateCmd"]["FeatureCount"] define_singleton_method(:vibrate){|speeds| #And now the real fun, we are gonna craft our message! id=client.generateID() cmd=[{"VibrateCmd"=>{"Id"=>id,"DeviceIndex"=>@deviceIndex,"Speeds"=>[]}}] #Ok we arn't gonna really care about how many speeds we are fed in here, we are gonna make sure that our total array isn't empty. (0..@vibeMotors-1).each{|i| if speeds[i].nil? speeds[i]=0 end cmd[0]["VibrateCmd"]["Speeds"]<<{"Index"=>i,"Speed"=>speeds[i]} } client.sendMessage([id,cmd.to_json]) } generateActivateAllCommand(:vibrate,@vibeMotors,:vibrateAll) end if(deviceInfo["DeviceMessages"].keys.include? "LinearCmd") @linearActuators=deviceInfo["DeviceMessages"]["LinearCmd"]["FeatureCount"] generateArrayedHashCommand({"Duration"=>0, "Position"=>0.0},@linearActuators,"LinearCmd","Vectors",:stroke) generateActivateAllCommand(:stroke,@linearActuators,:strokeAll) end if(deviceInfo["DeviceMessages"].keys.include? "RotateCmd") @rotationMotors=deviceInfo["DeviceMessages"]["RotateCmd"]["FeatureCount"] generateArrayedHashCommand({"Speed"=>0.0,"Clockwise"=>true},@rotationMotors,"RotateCmd","Rotations",:rotate) generateActivateAllCommand(:rotate,@rotationMotors,:rotateAll) end if(deviceInfo["DeviceMessages"].keys.include? "RawCmd") #TODO: Do some stuff here with RawCmd? ... Honestly I don't know what devices would support this ... possibly estim but at the moment π€· I have no idea. π€· #To implement: https://metafetish.github.io/buttplug/generic.html#rawcmd end end
Public Instance Methods
Spins whatever feature rotates right round β¦ baby right round~ (γ*Β°β½Β°*)
Arguments:
-
rotations (Array - Hash) - Array of Vectors, any extra will be dropped, and any ommited will be set to a duration of 0 and a posision of 0.0.
example:
device.rotate([{"Speed"=>0.5,"Clockwise"=>true},{"Speed=>1, "Clockwise"=>false}])
# File lib/buttplugrb.rb, line 309
Spins All the features Right round like a record, baby Right round round round (*οΎΟοΎ)
Arguments:
-
rotation (Hash) - Our single rotation we are sending to all the features
example:
device.rotateAll({"Speed"=>0.5,"Clockwise"=>true})
# File lib/buttplugrb.rb, line 319
Stops the Device
from any current actions that it might be taking.
# File lib/buttplugrb.rb, line 260 def stopDevice id=@client.generateID() cmd="[{\"StopDeviceCmd\": {\"ID\":#{id},\"DeviceIndex\":#{@deviceIndex}}}]" @client.sendMessage([id,cmd]) end
Sends a command to well β¦ Actuate the linear motors of the device (β಑Ο಑β)
Arguments:
-
vectors (Array - Hash) - Array of Vectors, any extra will be dropped, and any ommited will be set to a duration of 0 and a posision of 0.0.
example:
device.stroke([{"Duration"=>300, "Position"=>0.2},{"Duration"=>1000, "Position"=>0.8}])
# File lib/buttplugrb.rb, line 288
Sends a command to all linear actuators to respond to a vector (ΰΈ ΰΈ·βΏ ΰΈ·)ΰΈ§
Arguments:
-
vector (Hash) - A single vector.
example:
device.strokeAll({"Duration"=>300, "Position"=>0.2})
# File lib/buttplugrb.rb, line 298
Vibrates the motors on the device! (β ββ’βΟββ’β β)
Arguments:
-
speeds (Array - Float) - Array of speeds, any extra speeds will be dropped, and any ommitted speeds will be set to 0
example:
device.vibrate([0.2,0.3,1])
# File lib/buttplugrb.rb, line 266
Vibrates all motors on the device (β β>β β½ β<β β)
Arguments:
-
speed (Float) - The speed that all motors on the device to be set to
example:
device.vibrateAll(0.2)
# File lib/buttplugrb.rb, line 277
Protected Instance Methods
Helper Function to generate Metaprogrammed methods to set all instances of a feature to the same value
Arguments:
-
cmdToAll (Method) - The command we are gonna call when we want to send our DO ALL THE THINGS signal
-
featureCount (Int) - How many features are we controlling?
-
cmdName (Method) - Annnnd what are we gonna call our newly minted command?
# File lib/buttplugrb.rb, line 366 def generateActivateAllCommand(cmdToAll, featureCount, cmdName) define_singleton_method(cmdName){|var| vars=[] (0..featureCount-1).each{|i| vars<<var } self.public_send(cmdToAll, vars) } end
Helper Function to generate Metaprogrammed Methods for various buttplug stuff
Arguments:
-
blankHash (Hash) - An example of a Nilled out hash so the newly minted function knows what 0 looks like
-
featureCount (Int) - How many features are we talking about here? I've heard rumors of a dildo with 10 vibrators~
-
controlName (String) - And what command are we exactly sending to our server?
# arrayName (String) - What Buttplug.io is expecting the array to be called
-
cmdName (Method) - Annnnd what are we gonna call our newly minted method?
example:
generateArrayedHashCommand({"Speed"=>0.0,"Clockwise"=>true},@rotationMotors,"RotateCmd",:rotate)
# File lib/buttplugrb.rb, line 344 def generateArrayedHashCommand(blankHash, featureCount, controlName, arrayName ,cmdName) #AKA I have a feeling that if we get a dedicated function for estim boxes I feel like I'd have to rewrite this code again... so let's dry it the fuck up! define_singleton_method(cmdName){|hash| id=@client.generateID() cmd=[{controlName=>{"Id"=>id,"DeviceIndex"=>@deviceIndex,arrayName=>[]}}] (0..featureCount-1).each{|i| if hash[i].nil? hash[i]=blankHash end hash[i]["Index"]=i cmd[0][controlName][arrayName]<<hash[i] } @client.sendMessage([id,cmd.to_json]) } end