class Fusuma::Plugin::Detectors::RotateDetector

Constants

BASE_THERESHOLD
BUFFER_TYPE
FINGERS
GESTURE_RECORD_TYPE
SOURCES

Public Instance Methods

create_oneshot_index(gesture:, finger:, direction:) click to toggle source

@param [String] gesture @param [Integer] finger @param [String] direction @return [Config::Index]

# File lib/fusuma/plugin/detectors/rotate_detector.rb, line 103
def create_oneshot_index(gesture:, finger:, direction:)
  Config::Index.new(
    [
      Config::Index::Key.new(gesture),
      Config::Index::Key.new(finger.to_i, skippable: true),
      Config::Index::Key.new(direction)
    ]
  )
end
create_repeat_index(gesture:, finger:, direction:, status:) click to toggle source

@param [String] gesture @param [Integer] finger @param [String] direction @param [String] status @return [Config::Index]

# File lib/fusuma/plugin/detectors/rotate_detector.rb, line 88
def create_repeat_index(gesture:, finger:, direction:, status:)
  Config::Index.new(
    [
      Config::Index::Key.new(gesture),
      Config::Index::Key.new(finger.to_i),
      Config::Index::Key.new(direction),
      Config::Index::Key.new(status)
    ]
  )
end
detect(buffers) click to toggle source

@param buffers [Array<Buffer>] @return [Events::Event] if event is detected @return [NilClass] if event is NOT detected

# File lib/fusuma/plugin/detectors/rotate_detector.rb, line 19
def detect(buffers)
  gesture_buffer = buffers.find { |b| b.type == BUFFER_TYPE }
                          .select_from_last_begin
                          .select_by_events { |e| e.record.gesture == GESTURE_RECORD_TYPE }

  updating_events = gesture_buffer.updating_events
  return if updating_events.empty?

  updating_time = 100 * (updating_events.last.time - updating_events.first.time)
  oneshot_angle = gesture_buffer.sum_attrs(:rotate) / updating_time

  return if updating_events.empty?

  finger = gesture_buffer.finger

  status = case gesture_buffer.events.last.record.status
           when 'end'
             'end'
           when 'update'
             if updating_events.length == 1
               'begin'
             else
               'update'
             end
           else
             gesture_buffer.events.last.record.status
           end

  delta = if status == 'end'
            gesture_buffer.events[-2].record.delta
          else
            gesture_buffer.events.last.record.delta
          end

  repeat_direction = Direction.new(angle: delta.rotate).to_s
  repeat_quantity = Quantity.new(angle: delta.rotate).to_f

  repeat_index = create_repeat_index(gesture: type, finger: finger,
                                     direction: repeat_direction,
                                     status: status)

  if status == 'update'
    return unless moved?(repeat_quantity)

    oneshot_direction = Direction.new(angle: oneshot_angle).to_s
    oneshot_quantity = Quantity.new(angle: oneshot_angle).to_f
    oneshot_index = create_oneshot_index(gesture: type, finger: finger,
                                         direction: oneshot_direction)
    if enough_oneshot_threshold?(index: oneshot_index, quantity: oneshot_quantity)
      return [
        create_event(record: Events::Records::IndexRecord.new(
          index: oneshot_index, trigger: :oneshot, args: delta.to_h
        )),
        create_event(record: Events::Records::IndexRecord.new(
          index: repeat_index, trigger: :repeat, args: delta.to_h
        ))
      ]
    end
  end
  create_event(record: Events::Records::IndexRecord.new(
    index: repeat_index, trigger: :repeat, args: delta.to_h
  ))
end

Private Instance Methods

enough_oneshot_threshold?(index:, quantity:) click to toggle source
# File lib/fusuma/plugin/detectors/rotate_detector.rb, line 119
def enough_oneshot_threshold?(index:, quantity:)
  quantity > threshold(index: index)
end
moved?(repeat_quantity) click to toggle source
# File lib/fusuma/plugin/detectors/rotate_detector.rb, line 115
def moved?(repeat_quantity)
  repeat_quantity > 0.2
end
threshold(index:) click to toggle source
# File lib/fusuma/plugin/detectors/rotate_detector.rb, line 123
def threshold(index:)
  @threshold ||= {}
  @threshold[index.cache_key] ||= begin
    keys_specific = Config::Index.new [*index.keys, 'threshold']
    keys_global   = Config::Index.new ['threshold', type]
    config_value  = Config.search(keys_specific) ||
                    Config.search(keys_global) || 1
    BASE_THERESHOLD * config_value
  end
end