Class: Fusuma::Plugin::Buffers::TouchBuffer

Inherits:
Buffer
  • Object
show all
Defined in:
lib/fusuma/plugin/buffers/touch_buffer.rb

Constant Summary collapse

DEFAULT_SOURCE =
"libinput_touch_parser"
DEFAULT_SECONDS_TO_KEEP =
100

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ TouchBuffer

Returns a new instance of TouchBuffer.



15
16
17
18
19
20
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 15

def initialize(*args)
  super()
  @finger_events_map = {}
  @mem = {}
  @last_event_time = nil
end

Instance Attribute Details

#finger_events_mapObject (readonly)

Returns the value of attribute finger_events_map.



13
14
15
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 13

def finger_events_map
  @finger_events_map
end

Instance Method Details

#began?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 73

def began?
  @mem[:began] ||= @finger_events_map.any? && @finger_events_map.all? { |_, events| events.first&.record.status == "begin" }
end

#begin_timeObject



96
97
98
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 96

def begin_time
  @mem[:begin_time] ||= @finger_events_map.values.map { |events| events.first.time }.min
end

#buffer(event) ⇒ Object



29
30
31
32
33
34
35
36
37
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 29

def buffer(event)
  return if event&.tag != source

  @finger_events_map[event.record.finger] ||= []
  @finger_events_map[event.record.finger].push(event)
  reset_memoized

  self
end

#clearObject



59
60
61
62
63
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 59

def clear
  super
  @finger_events_map = {}
  reset_memoized
end

#clear_expired(current_time: Time.now) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 43

def clear_expired(current_time: Time.now)
  @seconds_to_keep ||= (config_params(:seconds_to_keep) || DEFAULT_SECONDS_TO_KEEP)

  clear if ended?
  @finger_events_map.each do |finger, events|
    next if events.empty?

    @finger_events_map[finger].select! do |e|
      current_time - e.time < @seconds_to_keep
    end
  end
  @finger_events_map.delete_if { |_, events| events.empty? }

  reset_memoized
end

#config_param_typesObject



22
23
24
25
26
27
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 22

def config_param_types
  {
    source: [String],
    seconds_to_keep: [Float, Integer]
  }
end

#durationObject



86
87
88
89
90
91
92
93
94
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 86

def duration
  @mem[:duration] ||= if @finger_events_map.empty?
                        0
                      elsif ended?
                        end_time - begin_time
                      else
                        Time.now - begin_time
                      end
end

#empty?Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 65

def empty?
  @finger_events_map.empty?
end

#end_timeObject



100
101
102
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 100

def end_time
  @mem[:end_time] ||= @finger_events_map.values.map { |events| events.last.time }.max
end

#ended?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 77

def ended?
  @mem[:ended] ||= @finger_events_map.any? && @finger_events_map.all? { |_, events| events.last&.record.status == "end" }
end

#eventsObject

Raises:

  • (NoMethodError)


39
40
41
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 39

def events
  raise NoMethodError, "Not supported, use finger_events_map instead"
end

#fingerObject



69
70
71
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 69

def finger
  @mem[:finger] ||= @finger_events_map.keys.count
end

#finger_movementsObject



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 104

def finger_movements
  @mem[:finger_movements] ||= @finger_events_map.map do |finger, events|
    position_events = events.select { |e| e.record.position? }
    next if position_events.size < 2 # we need at least first and last position

    first_position = { x: position_events.first.record.x_mm, y: position_events.first.record.y_mm }
    last_position = { x: position_events.last.record.x_mm, y: position_events.last.record.y_mm }
    distance = Touchscreen::Math.distance(first_position, last_position)
    next if distance < movement_threshold

    # TODO: check if there were trajectory changes in between?

    [finger, { first_position: first_position, last_position: last_position }]
  end.compact.to_h
end

#moved?Boolean

Returns:

  • (Boolean)


81
82
83
84
# File 'lib/fusuma/plugin/buffers/touch_buffer.rb', line 81

def moved?
  # TODO: a quicker way to do this?
  @mem[:moved] ||= @finger_events_map.any? && @finger_events_map.keys.all? { |finger| finger_movements.key?(finger) }
end