<commit_before>begin
  require 'pi_piper'
rescue LoadError
  require 'whipped-cream/pi_piper'
end

module WhippedCream
  # Actor that manages all interaction with a plugin
  class Runner
    def self.instance
      @instance
    end

    def self.create_instance(plugin)
      @instance = new(plugin)
    end

    attr_reader :plugin

    def initialize(plugin)
      @plugin = plugin

      configure
    end

    def name
      plugin.name
    end

    def pins
      @pins ||= {}
    end

    private

    def configure
      configure_buttons
      configure_sensors
      configure_switches
    end

    def configure_buttons
      plugin.buttons.each do |button|
        create_pin button, direction: :out

        define_singleton_method button.id do
          pin = pins[button.id]

          pin.on

          Thread.new {
            sleep 0.25
            pin.off
          }
        end
      end
    end

    def configure_sensors
      plugin.sensors.each do |sensor|
        if sensor.pin
          define_sensor_method_with_pin sensor
        else
          define_sensor_method_with_block sensor
        end
      end
    end

    def define_sensor_method_with_pin(sensor)
      create_pin sensor, direction: :in

      define_singleton_method sensor.id do
        pin = pins[sensor.id]

        pin.read == 1 ? sensor.high : sensor.low
      end
    end

    def define_sensor_method_with_block(sensor)
      define_singleton_method sensor.id do
        sensor.block.call
      end
    end

    def configure_switches
      plugin.switches.each do |switch|
        create_pin switch, direction: :out

        define_singleton_method switch.id do
          pin = pins[switch.id]

          pin.read == 1 ? pin.off : pin.on
        end
      end
    end

    def create_pin(control, options = {})
      return unless control.pin

      options[:pin] = control.pin

      pins[control.id] = PiPiper::Pin.new(options)
    end
  end
end
<commit_msg>Extract out pin tapping and toggling<commit_after>begin
  require 'pi_piper'
rescue LoadError
  require 'whipped-cream/pi_piper'
end

module WhippedCream
  # Actor that manages all interaction with a plugin
  class Runner
    def self.instance
      @instance
    end

    def self.create_instance(plugin)
      @instance = new(plugin)
    end

    attr_reader :plugin

    def initialize(plugin)
      @plugin = plugin

      configure
    end

    def name
      plugin.name
    end

    def pins
      @pins ||= {}
    end

    private

    def configure
      configure_buttons
      configure_sensors
      configure_switches
    end

    def configure_buttons
      plugin.buttons.each do |button|
        create_pin button, direction: :out

        define_singleton_method button.id do
          tap_pin(pins[button.id])
        end
      end
    end

    def configure_sensors
      plugin.sensors.each do |sensor|
        if sensor.pin
          define_sensor_method_with_pin sensor
        else
          define_sensor_method_with_block sensor
        end
      end
    end

    def define_sensor_method_with_pin(sensor)
      create_pin sensor, direction: :in

      define_singleton_method sensor.id do
        pin = pins[sensor.id]

        pin.read == 1 ? sensor.high : sensor.low
      end
    end

    def define_sensor_method_with_block(sensor)
      define_singleton_method sensor.id do
        sensor.block.call
      end
    end

    def configure_switches
      plugin.switches.each do |switch|
        create_pin switch, direction: :out

        define_singleton_method switch.id do
          toggle_pin(pins[switch.id])
        end
      end
    end

    def create_pin(control, options = {})
      return unless control.pin

      options[:pin] = control.pin

      pins[control.id] = PiPiper::Pin.new(options)
    end

    def tap_pin(pin)
      pin.on

      Thread.new {
        sleep 0.25
        pin.off
      }
    end

    def toggle_pin(pin)
      if pin.read.nonzero?
        pin.off
      else
        pin.on
      end
    end
  end
end

{'fraction_non_alphanumeric': 0.05851723282915944, 'fraction_numerical': 0.0022315893875526904, 'mean_word_length': 1.9105339105339105, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6583672', 'n_tokens_mistral': 1246, 'n_tokens_neox': 1169, 'n_words': 307}