class Fusuma::Plugin::Detectors::PinchDetector

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/pinch_detector.rb, line 108
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/pinch_detector.rb, line 93
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, skippable: true),
      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/pinch_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?

  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

  prev_event, event = if status == 'end'
                        [
                          gesture_buffer.events[-3],
                          gesture_buffer.events[-2]
                        ]
                      else
                        [
                          gesture_buffer.events[-2],
                          gesture_buffer.events[-1]
                        ]
                      end
  delta = event.record.delta
  prev_delta = prev_event.record.delta

  repeat_direction = Direction.new(target: delta.zoom, base: (prev_delta&.zoom || 1.0)).to_s
  # repeat_quantity = Quantity.new(target: delta.zoom, base: (prev_delta&.zoom || 1.0)).to_f

  repeat_index = create_repeat_index(gesture: type, finger: finger,
                                     direction: repeat_direction,
                                     status: status)
  if status == 'update'
    return unless moved?(prev_event, event)

    avg_zoom = gesture_buffer.avg_attrs(:zoom)
    first_zoom = updating_events.first.record.delta.zoom

    oneshot_quantity = Quantity.new(target: avg_zoom, base: first_zoom).to_f
    oneshot_direction = Direction.new(target: avg_zoom, base: first_zoom).to_s
    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/pinch_detector.rb, line 126
def enough_oneshot_threshold?(index:, quantity:)
  quantity >= threshold(index: index)
end
moved?(prev_event, event) click to toggle source
# File lib/fusuma/plugin/detectors/pinch_detector.rb, line 120
def moved?(prev_event, event)
  zoom_delta = (event.record.delta.zoom - prev_event.record.delta.zoom).abs
  updating_time = (event.time - prev_event.time) * 100
  zoom_delta / updating_time > 0.01
end
threshold(index:) click to toggle source
# File lib/fusuma/plugin/detectors/pinch_detector.rb, line 130
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