class Buttplug::Device

This class creates a Wrapper for your various devices you fetched from listDevices for your controlling pleasure!

Public Class Methods

new(client, deviceInfo) click to toggle source

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

rotate() click to toggle source

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
rotateAll() click to toggle source

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
stopDevice() click to toggle source

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
stroke() click to toggle source

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
strokeAll() click to toggle source

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
vibrate() click to toggle source

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
vibrateAll() click to toggle source

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

generateActivateAllCommand(cmdToAll, featureCount, cmdName) click to toggle source

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
generateArrayedHashCommand(blankHash, featureCount, controlName, arrayName ,cmdName) click to toggle source

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