fusuma 2.5.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +55 -34
 - data/bin/console +2 -2
 - data/lib/fusuma/config/index.rb +19 -46
 - data/lib/fusuma/config/searcher.rb +14 -61
 - data/lib/fusuma/custom_process.rb +33 -1
 - data/lib/fusuma/device.rb +1 -0
 - data/lib/fusuma/multi_logger.rb +16 -0
 - data/lib/fusuma/plugin/base.rb +4 -1
 - data/lib/fusuma/plugin/buffers/gesture_buffer.rb +63 -6
 - data/lib/fusuma/plugin/detectors/detector.rb +10 -9
 - data/lib/fusuma/plugin/detectors/hold_detector.rb +24 -14
 - data/lib/fusuma/plugin/detectors/pinch_detector.rb +10 -10
 - data/lib/fusuma/plugin/detectors/rotate_detector.rb +4 -11
 - data/lib/fusuma/plugin/detectors/swipe_detector.rb +7 -15
 - data/lib/fusuma/plugin/events/records/gesture_record.rb +5 -2
 - data/lib/fusuma/plugin/events/records/index_record.rb +1 -1
 - data/lib/fusuma/plugin/executors/command_executor.rb +2 -2
 - data/lib/fusuma/plugin/executors/executor.rb +1 -4
 - data/lib/fusuma/plugin/filters/libinput_device_filter.rb +2 -1
 - data/lib/fusuma/plugin/inputs/input.rb +14 -36
 - data/lib/fusuma/plugin/inputs/timer_input.rb +36 -21
 - data/lib/fusuma/plugin/manager.rb +48 -22
 - data/lib/fusuma/version.rb +1 -1
 - data/lib/fusuma.rb +44 -34
 - metadata +3 -3
 
| 
         @@ -7,9 +7,25 @@ module Fusuma 
     | 
|
| 
       7 
7 
     | 
    
         
             
                module Buffers
         
     | 
| 
       8 
8 
     | 
    
         
             
                  # manage events and generate command
         
     | 
| 
       9 
9 
     | 
    
         
             
                  class GestureBuffer < Buffer
         
     | 
| 
      
 10 
     | 
    
         
            +
                    CacheEntry = Struct.new(:checked, :value)
         
     | 
| 
       10 
11 
     | 
    
         
             
                    DEFAULT_SOURCE = "libinput_gesture_parser"
         
     | 
| 
       11 
12 
     | 
    
         
             
                    DEFAULT_SECONDS_TO_KEEP = 100
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    def initialize(*args)
         
     | 
| 
      
 16 
     | 
    
         
            +
                      super(*args)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      @cache = {}
         
     | 
| 
      
 18 
     | 
    
         
            +
                      @cache_select_by = {}
         
     | 
| 
      
 19 
     | 
    
         
            +
                      @cache_sum10 = {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    def clear
         
     | 
| 
      
 23 
     | 
    
         
            +
                      super.clear
         
     | 
| 
      
 24 
     | 
    
         
            +
                      @cache = {}
         
     | 
| 
      
 25 
     | 
    
         
            +
                      @cache_select_by = {}
         
     | 
| 
      
 26 
     | 
    
         
            +
                      @cache_sum10 = {}
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       13 
29 
     | 
    
         
             
                    def config_param_types
         
     | 
| 
       14 
30 
     | 
    
         
             
                      {
         
     | 
| 
       15 
31 
     | 
    
         
             
                        source: [String],
         
     | 
| 
         @@ -40,6 +56,9 @@ module Fusuma 
     | 
|
| 
       40 
56 
     | 
    
         
             
                        MultiLogger.debug("#{self.class.name}##{__method__}")
         
     | 
| 
       41 
57 
     | 
    
         | 
| 
       42 
58 
     | 
    
         
             
                        @events.delete(e)
         
     | 
| 
      
 59 
     | 
    
         
            +
                        @cache = {}
         
     | 
| 
      
 60 
     | 
    
         
            +
                        @cache_select_by = {}
         
     | 
| 
      
 61 
     | 
    
         
            +
                        @cache_sum10 = {}
         
     | 
| 
       43 
62 
     | 
    
         
             
                      end
         
     | 
| 
       44 
63 
     | 
    
         
             
                    end
         
     | 
| 
       45 
64 
     | 
    
         | 
| 
         @@ -59,11 +78,35 @@ module Fusuma 
     | 
|
| 
       59 
78 
     | 
    
         
             
                    def sum_attrs(attr)
         
     | 
| 
       60 
79 
     | 
    
         
             
                      updating_events.map do |gesture_event|
         
     | 
| 
       61 
80 
     | 
    
         
             
                        gesture_event.record.delta[attr].to_f
         
     | 
| 
       62 
     | 
    
         
            -
                      end. 
     | 
| 
      
 81 
     | 
    
         
            +
                      end.reduce(:+)
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                    # @param attr [Symbol]
         
     | 
| 
      
 85 
     | 
    
         
            +
                    # @return [Float]
         
     | 
| 
      
 86 
     | 
    
         
            +
                    def sum_last10_attrs(attr) # sums last 10 values of attr (or all if length < 10)
         
     | 
| 
      
 87 
     | 
    
         
            +
                      cache_entry = ( @cache_sum10[attr] ||= CacheEntry.new(0, 0) )
         
     | 
| 
      
 88 
     | 
    
         
            +
                      upd_ev = updating_events
         
     | 
| 
      
 89 
     | 
    
         
            +
                      if upd_ev.length > cache_entry.checked + 1 then
         
     | 
| 
      
 90 
     | 
    
         
            +
                        cache_entry.value = upd_ev.last(10).map do |gesture_event|
         
     | 
| 
      
 91 
     | 
    
         
            +
                          gesture_event.record.delta[attr].to_f
         
     | 
| 
      
 92 
     | 
    
         
            +
                        end.reduce(:+)
         
     | 
| 
      
 93 
     | 
    
         
            +
                      elsif upd_ev.length > cache_entry.checked
         
     | 
| 
      
 94 
     | 
    
         
            +
                        cache_entry.value = cache_entry.value + upd_ev[-1].record.delta[attr].to_f - \
         
     | 
| 
      
 95 
     | 
    
         
            +
                          (upd_ev.length > 10 ? upd_ev[-11].record.delta[attr].to_f : 0)
         
     | 
| 
      
 96 
     | 
    
         
            +
                      else
         
     | 
| 
      
 97 
     | 
    
         
            +
                        return cache_entry.value
         
     | 
| 
      
 98 
     | 
    
         
            +
                      end
         
     | 
| 
      
 99 
     | 
    
         
            +
                      cache_entry.checked = upd_ev.length
         
     | 
| 
      
 100 
     | 
    
         
            +
                      cache_entry.value
         
     | 
| 
       63 
101 
     | 
    
         
             
                    end
         
     | 
| 
       64 
102 
     | 
    
         | 
| 
       65 
103 
     | 
    
         
             
                    def updating_events
         
     | 
| 
       66 
     | 
    
         
            -
                      @ 
     | 
| 
      
 104 
     | 
    
         
            +
                      cache_entry = ( @cache[:updating_events] ||= CacheEntry.new(0, []) )
         
     | 
| 
      
 105 
     | 
    
         
            +
                      cache_entry.checked.upto(@events.length - 1).each do |i|
         
     | 
| 
      
 106 
     | 
    
         
            +
                        (cache_entry.value << @events[i]) if @events[i].record.status == "update"
         
     | 
| 
      
 107 
     | 
    
         
            +
                      end
         
     | 
| 
      
 108 
     | 
    
         
            +
                      cache_entry.checked = @events.length
         
     | 
| 
      
 109 
     | 
    
         
            +
                      cache_entry.value
         
     | 
| 
       67 
110 
     | 
    
         
             
                    end
         
     | 
| 
       68 
111 
     | 
    
         | 
| 
       69 
112 
     | 
    
         
             
                    # @param attr [Symbol]
         
     | 
| 
         @@ -96,14 +139,28 @@ module Fusuma 
     | 
|
| 
       96 
139 
     | 
    
         
             
                      self.class.new events
         
     | 
| 
       97 
140 
     | 
    
         
             
                    end
         
     | 
| 
       98 
141 
     | 
    
         | 
| 
      
 142 
     | 
    
         
            +
                    def select_by_type(type)
         
     | 
| 
      
 143 
     | 
    
         
            +
                      cache_entry = ( @cache_select_by[type] ||= CacheEntry.new(0, self.class.new([])) )
         
     | 
| 
      
 144 
     | 
    
         
            +
                      cache_entry.checked.upto(@events.length - 1).each do |i|
         
     | 
| 
      
 145 
     | 
    
         
            +
                        (cache_entry.value.events << @events[i]) if @events[i].record.gesture == type
         
     | 
| 
      
 146 
     | 
    
         
            +
                      end
         
     | 
| 
      
 147 
     | 
    
         
            +
                      cache_entry.checked = @events.length
         
     | 
| 
      
 148 
     | 
    
         
            +
                      cache_entry.value
         
     | 
| 
      
 149 
     | 
    
         
            +
                    end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
       99 
151 
     | 
    
         
             
                    def select_from_last_begin
         
     | 
| 
       100 
152 
     | 
    
         
             
                      return self if empty?
         
     | 
| 
      
 153 
     | 
    
         
            +
                      cache_entry = ( @cache[:last_begin] ||= CacheEntry.new(0, nil) )
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                      cache_entry.value = (@events.length - 1).downto(cache_entry.checked).find do |i|
         
     | 
| 
      
 156 
     | 
    
         
            +
                        @events[i].record.status == "begin"
         
     | 
| 
      
 157 
     | 
    
         
            +
                      end || cache_entry.value
         
     | 
| 
      
 158 
     | 
    
         
            +
                      cache_entry.checked = @events.length
         
     | 
| 
       101 
159 
     | 
    
         | 
| 
       102 
     | 
    
         
            -
                       
     | 
| 
       103 
     | 
    
         
            -
                      return GestureBuffer.new([]) if  
     | 
| 
      
 160 
     | 
    
         
            +
                      return self if cache_entry.value == 0
         
     | 
| 
      
 161 
     | 
    
         
            +
                      return GestureBuffer.new([]) if cache_entry.value.nil?
         
     | 
| 
       104 
162 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
                       
     | 
| 
       106 
     | 
    
         
            -
                      GestureBuffer.new(@events[index_last_begin..-1])
         
     | 
| 
      
 163 
     | 
    
         
            +
                      GestureBuffer.new(@events[cache_entry.value..-1])
         
     | 
| 
       107 
164 
     | 
    
         
             
                    end
         
     | 
| 
       108 
165 
     | 
    
         
             
                  end
         
     | 
| 
       109 
166 
     | 
    
         
             
                end
         
     | 
| 
         @@ -8,9 +8,18 @@ module Fusuma 
     | 
|
| 
       8 
8 
     | 
    
         
             
                module Detectors
         
     | 
| 
       9 
9 
     | 
    
         
             
                  # Inherite this base
         
     | 
| 
       10 
10 
     | 
    
         
             
                  class Detector < Base
         
     | 
| 
      
 11 
     | 
    
         
            +
                    def initialize(*args)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      super(*args)
         
     | 
| 
      
 13 
     | 
    
         
            +
                      @tag = self.class.tag
         
     | 
| 
      
 14 
     | 
    
         
            +
                      @type = self.class.type
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    attr_reader :tag
         
     | 
| 
      
 18 
     | 
    
         
            +
                    attr_reader :type
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       11 
20 
     | 
    
         
             
                    # @return [Array<String>]
         
     | 
| 
       12 
21 
     | 
    
         
             
                    def sources
         
     | 
| 
       13 
     | 
    
         
            -
                      @ 
     | 
| 
      
 22 
     | 
    
         
            +
                      @sources ||= self.class.const_get(:SOURCES)
         
     | 
| 
       14 
23 
     | 
    
         
             
                    end
         
     | 
| 
       15 
24 
     | 
    
         | 
| 
       16 
25 
     | 
    
         
             
                    # Always watch buffers and detect them or not
         
     | 
| 
         @@ -43,14 +52,6 @@ module Fusuma 
     | 
|
| 
       43 
52 
     | 
    
         
             
                      @last_time.nil?
         
     | 
| 
       44 
53 
     | 
    
         
             
                    end
         
     | 
| 
       45 
54 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
                    def tag
         
     | 
| 
       47 
     | 
    
         
            -
                      self.class.tag
         
     | 
| 
       48 
     | 
    
         
            -
                    end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                    def type
         
     | 
| 
       51 
     | 
    
         
            -
                      self.class.type
         
     | 
| 
       52 
     | 
    
         
            -
                    end
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
55 
     | 
    
         
             
                    class << self
         
     | 
| 
       55 
56 
     | 
    
         
             
                      def tag
         
     | 
| 
       56 
57 
     | 
    
         
             
                        name.split("Detectors::").last.underscore
         
     | 
| 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require_relative "./detector"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "../inputs/timer_input"
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module Fusuma
         
     | 
| 
       6 
7 
     | 
    
         
             
              module Plugin
         
     | 
| 
         @@ -10,6 +11,7 @@ module Fusuma 
     | 
|
| 
       10 
11 
     | 
    
         
             
                    SOURCES = %w[gesture timer].freeze
         
     | 
| 
       11 
12 
     | 
    
         
             
                    BUFFER_TYPE = "gesture"
         
     | 
| 
       12 
13 
     | 
    
         
             
                    GESTURE_RECORD_TYPE = "hold"
         
     | 
| 
      
 14 
     | 
    
         
            +
                    Timer = Inputs::TimerInput.instance
         
     | 
| 
       13 
15 
     | 
    
         | 
| 
       14 
16 
     | 
    
         
             
                    BASE_THERESHOLD = 0.7
         
     | 
| 
       15 
17 
     | 
    
         | 
| 
         @@ -21,16 +23,15 @@ module Fusuma 
     | 
|
| 
       21 
23 
     | 
    
         
             
                      hold_buffer = find_hold_buffer(buffers)
         
     | 
| 
       22 
24 
     | 
    
         
             
                      return if hold_buffer.empty?
         
     | 
| 
       23 
25 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                       
     | 
| 
      
 26 
     | 
    
         
            +
                      last_hold = hold_buffer.events.last
         
     | 
| 
       25 
27 
     | 
    
         | 
| 
       26 
28 
     | 
    
         
             
                      timer_buffer = buffers.find { |b| b.type == "timer" }
         
     | 
| 
       27 
     | 
    
         
            -
                       
     | 
| 
      
 29 
     | 
    
         
            +
                      last_timer = timer_buffer.events.last
         
     | 
| 
       28 
30 
     | 
    
         | 
| 
       29 
31 
     | 
    
         
             
                      finger = hold_buffer.finger
         
     | 
| 
       30 
     | 
    
         
            -
                      holding_time = calc_holding_time(hold_events:  
     | 
| 
      
 32 
     | 
    
         
            +
                      holding_time = calc_holding_time(hold_events: hold_buffer.events, last_timer: last_timer)
         
     | 
| 
       31 
33 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                       
     | 
| 
       33 
     | 
    
         
            -
                      status = case hold_events.last.record.status
         
     | 
| 
      
 34 
     | 
    
         
            +
                      status = case last_hold.record.status
         
     | 
| 
       34 
35 
     | 
    
         
             
                      when "begin"
         
     | 
| 
       35 
36 
     | 
    
         
             
                        if holding_time.zero?
         
     | 
| 
       36 
37 
     | 
    
         
             
                          "begin"
         
     | 
| 
         @@ -42,16 +43,19 @@ module Fusuma 
     | 
|
| 
       42 
43 
     | 
    
         
             
                      when "end"
         
     | 
| 
       43 
44 
     | 
    
         
             
                        "end"
         
     | 
| 
       44 
45 
     | 
    
         
             
                      else
         
     | 
| 
       45 
     | 
    
         
            -
                        last_record =  
     | 
| 
      
 46 
     | 
    
         
            +
                        last_record = last_hold.record.status
         
     | 
| 
       46 
47 
     | 
    
         
             
                        raise "Unexpected Status:#{last_record.status} in #{last_record}"
         
     | 
| 
       47 
48 
     | 
    
         
             
                      end
         
     | 
| 
       48 
49 
     | 
    
         | 
| 
       49 
50 
     | 
    
         
             
                      repeat_index = create_repeat_index(finger: finger, status: status)
         
     | 
| 
       50 
51 
     | 
    
         
             
                      oneshot_index = create_oneshot_index(finger: finger)
         
     | 
| 
       51 
52 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                       
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
      
 53 
     | 
    
         
            +
                      if status == "begin" then
         
     | 
| 
      
 54 
     | 
    
         
            +
                        @timeout = nil
         
     | 
| 
      
 55 
     | 
    
         
            +
                        if threshold(index: oneshot_index) < Timer.interval then
         
     | 
| 
      
 56 
     | 
    
         
            +
                          Timer.wake_early(Time.now + threshold(index: oneshot_index))
         
     | 
| 
      
 57 
     | 
    
         
            +
                        end
         
     | 
| 
      
 58 
     | 
    
         
            +
                      elsif status == "timer"
         
     | 
| 
       55 
59 
     | 
    
         
             
                        return if @timeout
         
     | 
| 
       56 
60 
     | 
    
         | 
| 
       57 
61 
     | 
    
         
             
                        return unless enough?(index: oneshot_index, holding_time: holding_time)
         
     | 
| 
         @@ -97,12 +101,12 @@ module Fusuma 
     | 
|
| 
       97 
101 
     | 
    
         
             
                    def find_hold_buffer(buffers)
         
     | 
| 
       98 
102 
     | 
    
         
             
                      buffers.find { |b| b.type == BUFFER_TYPE }
         
     | 
| 
       99 
103 
     | 
    
         
             
                        .select_from_last_begin
         
     | 
| 
       100 
     | 
    
         
            -
                        . 
     | 
| 
      
 104 
     | 
    
         
            +
                        .select_by_type(GESTURE_RECORD_TYPE)
         
     | 
| 
       101 
105 
     | 
    
         
             
                    end
         
     | 
| 
       102 
106 
     | 
    
         | 
| 
       103 
     | 
    
         
            -
                    def calc_holding_time(hold_events:,  
     | 
| 
       104 
     | 
    
         
            -
                      last_time = if  
     | 
| 
       105 
     | 
    
         
            -
                         
     | 
| 
      
 107 
     | 
    
         
            +
                    def calc_holding_time(hold_events:, last_timer:)
         
     | 
| 
      
 108 
     | 
    
         
            +
                      last_time = if last_timer && (hold_events.last.time < last_timer.time)
         
     | 
| 
      
 109 
     | 
    
         
            +
                        last_timer.time
         
     | 
| 
       106 
110 
     | 
    
         
             
                      else
         
     | 
| 
       107 
111 
     | 
    
         
             
                        hold_events.last.time
         
     | 
| 
       108 
112 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -110,7 +114,13 @@ module Fusuma 
     | 
|
| 
       110 
114 
     | 
    
         
             
                    end
         
     | 
| 
       111 
115 
     | 
    
         | 
| 
       112 
116 
     | 
    
         
             
                    def enough?(index:, holding_time:)
         
     | 
| 
       113 
     | 
    
         
            -
                       
     | 
| 
      
 117 
     | 
    
         
            +
                      diff = threshold(index: index) - holding_time
         
     | 
| 
      
 118 
     | 
    
         
            +
                      if diff < 0 then
         
     | 
| 
      
 119 
     | 
    
         
            +
                        true
         
     | 
| 
      
 120 
     | 
    
         
            +
                      elsif diff < Timer.interval
         
     | 
| 
      
 121 
     | 
    
         
            +
                        Timer.wake_early(Time.now + diff)
         
     | 
| 
      
 122 
     | 
    
         
            +
                        false
         
     | 
| 
      
 123 
     | 
    
         
            +
                      end
         
     | 
| 
       114 
124 
     | 
    
         
             
                    end
         
     | 
| 
       115 
125 
     | 
    
         | 
| 
       116 
126 
     | 
    
         
             
                    def threshold(index:)
         
     | 
| 
         @@ -19,7 +19,7 @@ module Fusuma 
     | 
|
| 
       19 
19 
     | 
    
         
             
                    def detect(buffers)
         
     | 
| 
       20 
20 
     | 
    
         
             
                      gesture_buffer = buffers.find { |b| b.type == BUFFER_TYPE }
         
     | 
| 
       21 
21 
     | 
    
         
             
                        .select_from_last_begin
         
     | 
| 
       22 
     | 
    
         
            -
                        . 
     | 
| 
      
 22 
     | 
    
         
            +
                        .select_by_type(GESTURE_RECORD_TYPE)
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
                      updating_events = gesture_buffer.updating_events
         
     | 
| 
       25 
25 
     | 
    
         
             
                      return if updating_events.empty?
         
     | 
| 
         @@ -100,10 +100,10 @@ module Fusuma 
     | 
|
| 
       100 
100 
     | 
    
         
             
                    def create_repeat_index(gesture:, finger:, direction:, status:)
         
     | 
| 
       101 
101 
     | 
    
         
             
                      Config::Index.new(
         
     | 
| 
       102 
102 
     | 
    
         
             
                        [
         
     | 
| 
       103 
     | 
    
         
            -
                          Config::Index::Key.new(gesture),
         
     | 
| 
       104 
     | 
    
         
            -
                          Config::Index::Key.new(finger.to_i),
         
     | 
| 
       105 
     | 
    
         
            -
                          Config::Index::Key.new(direction, skippable: true),
         
     | 
| 
       106 
     | 
    
         
            -
                          Config::Index::Key.new(status)
         
     | 
| 
      
 103 
     | 
    
         
            +
                          Config::Index::Key.new(gesture), # 'pinch'
         
     | 
| 
      
 104 
     | 
    
         
            +
                          Config::Index::Key.new(finger.to_i), # 2, 3, 4
         
     | 
| 
      
 105 
     | 
    
         
            +
                          Config::Index::Key.new(direction, skippable: true), # 'in', 'out'
         
     | 
| 
      
 106 
     | 
    
         
            +
                          Config::Index::Key.new(status) # 'begin', 'update', 'end'
         
     | 
| 
       107 
107 
     | 
    
         
             
                        ]
         
     | 
| 
       108 
108 
     | 
    
         
             
                      )
         
     | 
| 
       109 
109 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -115,9 +115,9 @@ module Fusuma 
     | 
|
| 
       115 
115 
     | 
    
         
             
                    def create_oneshot_index(gesture:, finger:, direction:)
         
     | 
| 
       116 
116 
     | 
    
         
             
                      Config::Index.new(
         
     | 
| 
       117 
117 
     | 
    
         
             
                        [
         
     | 
| 
       118 
     | 
    
         
            -
                          Config::Index::Key.new(gesture),
         
     | 
| 
       119 
     | 
    
         
            -
                          Config::Index::Key.new(finger.to_i, skippable: true),
         
     | 
| 
       120 
     | 
    
         
            -
                          Config::Index::Key.new(direction)
         
     | 
| 
      
 118 
     | 
    
         
            +
                          Config::Index::Key.new(gesture), # 'pinch'
         
     | 
| 
      
 119 
     | 
    
         
            +
                          Config::Index::Key.new(finger.to_i, skippable: true), # 2, 3, 4
         
     | 
| 
      
 120 
     | 
    
         
            +
                          Config::Index::Key.new(direction) # 'in', 'out'
         
     | 
| 
       121 
121 
     | 
    
         
             
                        ]
         
     | 
| 
       122 
122 
     | 
    
         
             
                      )
         
     | 
| 
       123 
123 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -161,9 +161,9 @@ module Fusuma 
     | 
|
| 
       161 
161 
     | 
    
         | 
| 
       162 
162 
     | 
    
         
             
                      def calc
         
     | 
| 
       163 
163 
     | 
    
         
             
                        if @target > @base
         
     | 
| 
       164 
     | 
    
         
            -
                          IN
         
     | 
| 
       165 
     | 
    
         
            -
                        else
         
     | 
| 
       166 
164 
     | 
    
         
             
                          OUT
         
     | 
| 
      
 165 
     | 
    
         
            +
                        else
         
     | 
| 
      
 166 
     | 
    
         
            +
                          IN
         
     | 
| 
       167 
167 
     | 
    
         
             
                        end
         
     | 
| 
       168 
168 
     | 
    
         
             
                      end
         
     | 
| 
       169 
169 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -19,21 +19,14 @@ module Fusuma 
     | 
|
| 
       19 
19 
     | 
    
         
             
                    def detect(buffers)
         
     | 
| 
       20 
20 
     | 
    
         
             
                      gesture_buffer = buffers.find { |b| b.type == BUFFER_TYPE }
         
     | 
| 
       21 
21 
     | 
    
         
             
                        .select_from_last_begin
         
     | 
| 
       22 
     | 
    
         
            -
                        . 
     | 
| 
      
 22 
     | 
    
         
            +
                        .select_by_type(GESTURE_RECORD_TYPE)
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
                      updating_events = gesture_buffer.updating_events
         
     | 
| 
       25 
25 
     | 
    
         
             
                      return if updating_events.empty?
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                       
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                        last_10.sum_attrs(:rotate) / updating_time
         
     | 
| 
       31 
     | 
    
         
            -
                      else
         
     | 
| 
       32 
     | 
    
         
            -
                        updating_time = 100 * (updating_events.last.time - updating_events.first.time)
         
     | 
| 
       33 
     | 
    
         
            -
                        gesture_buffer.sum_attrs(:rotate) / updating_time
         
     | 
| 
       34 
     | 
    
         
            -
                      end
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                      return if updating_events.empty?
         
     | 
| 
      
 27 
     | 
    
         
            +
                      updating_time = 100 * (updating_events[-1].time -
         
     | 
| 
      
 28 
     | 
    
         
            +
                                             (updating_events[-10] || updating_events.first).time)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      oneshot_angle = gesture_buffer.sum_last10_attrs(:rotate) / updating_time
         
     | 
| 
       37 
30 
     | 
    
         | 
| 
       38 
31 
     | 
    
         
             
                      finger = gesture_buffer.finger
         
     | 
| 
       39 
32 
     | 
    
         | 
| 
         @@ -19,22 +19,15 @@ module Fusuma 
     | 
|
| 
       19 
19 
     | 
    
         
             
                    def detect(buffers)
         
     | 
| 
       20 
20 
     | 
    
         
             
                      gesture_buffer = buffers.find { |b| b.type == BUFFER_TYPE }
         
     | 
| 
       21 
21 
     | 
    
         
             
                        .select_from_last_begin
         
     | 
| 
       22 
     | 
    
         
            -
                        . 
     | 
| 
      
 22 
     | 
    
         
            +
                        .select_by_type(GESTURE_RECORD_TYPE)
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
                      updating_events = gesture_buffer.updating_events
         
     | 
| 
       25 
25 
     | 
    
         
             
                      return if updating_events.empty?
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                       
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                          last_10.sum_attrs(:move_y) / updating_time]
         
     | 
| 
       32 
     | 
    
         
            -
                      else
         
     | 
| 
       33 
     | 
    
         
            -
                        updating_time = 100 * (updating_events.last.time - updating_events.first.time)
         
     | 
| 
       34 
     | 
    
         
            -
                        [gesture_buffer.sum_attrs(:move_x) / updating_time,
         
     | 
| 
       35 
     | 
    
         
            -
                          gesture_buffer.sum_attrs(:move_y) / updating_time]
         
     | 
| 
       36 
     | 
    
         
            -
                      end
         
     | 
| 
       37 
     | 
    
         
            -
                      (gesture_buffer.sum_attrs(:move_x) / updating_time)
         
     | 
| 
      
 27 
     | 
    
         
            +
                      updating_time = 100 * (updating_events.last.time -
         
     | 
| 
      
 28 
     | 
    
         
            +
                                             (updating_events[-10] || updating_events.first).time)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      oneshot_move_x = gesture_buffer.sum_last10_attrs(:move_x) / updating_time
         
     | 
| 
      
 30 
     | 
    
         
            +
                      oneshot_move_y = gesture_buffer.sum_last10_attrs(:move_y) / updating_time
         
     | 
| 
       38 
31 
     | 
    
         | 
| 
       39 
32 
     | 
    
         
             
                      finger = gesture_buffer.finger
         
     | 
| 
       40 
33 
     | 
    
         
             
                      status = case gesture_buffer.events.last.record.status
         
     | 
| 
         @@ -67,8 +60,7 @@ module Fusuma 
     | 
|
| 
       67 
60 
     | 
    
         | 
| 
       68 
61 
     | 
    
         
             
                        oneshot_direction = Direction.new(move_x: oneshot_move_x, move_y: oneshot_move_y).to_s
         
     | 
| 
       69 
62 
     | 
    
         
             
                        oneshot_quantity = Quantity.new(move_x: oneshot_move_x, move_y: oneshot_move_y).to_f
         
     | 
| 
       70 
     | 
    
         
            -
                        oneshot_index = create_oneshot_index(gesture: type, finger: finger,
         
     | 
| 
       71 
     | 
    
         
            -
                          direction: oneshot_direction)
         
     | 
| 
      
 63 
     | 
    
         
            +
                        oneshot_index = create_oneshot_index(gesture: type, finger: finger, direction: oneshot_direction)
         
     | 
| 
       72 
64 
     | 
    
         
             
                        if enough_oneshot_threshold?(index: oneshot_index, quantity: oneshot_quantity)
         
     | 
| 
       73 
65 
     | 
    
         
             
                          return [
         
     | 
| 
       74 
66 
     | 
    
         
             
                            create_event(record: Events::Records::IndexRecord.new(
         
     | 
| 
         @@ -109,7 +101,7 @@ module Fusuma 
     | 
|
| 
       109 
101 
     | 
    
         
             
                      Config::Index.new(
         
     | 
| 
       110 
102 
     | 
    
         
             
                        [
         
     | 
| 
       111 
103 
     | 
    
         
             
                          Config::Index::Key.new(gesture),
         
     | 
| 
       112 
     | 
    
         
            -
                          Config::Index::Key.new(finger.to_i 
     | 
| 
      
 104 
     | 
    
         
            +
                          Config::Index::Key.new(finger.to_i),
         
     | 
| 
       113 
105 
     | 
    
         
             
                          Config::Index::Key.new(direction)
         
     | 
| 
       114 
106 
     | 
    
         
             
                        ]
         
     | 
| 
       115 
107 
     | 
    
         
             
                      )
         
     | 
| 
         @@ -11,9 +11,12 @@ module Fusuma 
     | 
|
| 
       11 
11 
     | 
    
         
             
                      # define gesture format
         
     | 
| 
       12 
12 
     | 
    
         
             
                      attr_reader :status, :gesture, :finger, :delta
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                      Delta = Struct.new( 
     | 
| 
      
 14 
     | 
    
         
            +
                      Delta = Struct.new(
         
     | 
| 
      
 15 
     | 
    
         
            +
                        :move_x, :move_y,
         
     | 
| 
       15 
16 
     | 
    
         
             
                        :unaccelerated_x, :unaccelerated_y,
         
     | 
| 
       16 
     | 
    
         
            -
                        :zoom, 
     | 
| 
      
 17 
     | 
    
         
            +
                        :zoom,
         
     | 
| 
      
 18 
     | 
    
         
            +
                        :rotate
         
     | 
| 
      
 19 
     | 
    
         
            +
                      )
         
     | 
| 
       17 
20 
     | 
    
         | 
| 
       18 
21 
     | 
    
         
             
                      # @param status [String]
         
     | 
| 
       19 
22 
     | 
    
         
             
                      # @param gesture [String]
         
     | 
| 
         @@ -39,14 +39,14 @@ module Fusuma 
     | 
|
| 
       39 
39 
     | 
    
         
             
                    # @return [String]
         
     | 
| 
       40 
40 
     | 
    
         
             
                    def search_command(event)
         
     | 
| 
       41 
41 
     | 
    
         
             
                      command_index = Config::Index.new([*event.record.index.keys, :command])
         
     | 
| 
       42 
     | 
    
         
            -
                      Config.search(command_index)
         
     | 
| 
      
 42 
     | 
    
         
            +
                      Config.instance.search(command_index)
         
     | 
| 
       43 
43 
     | 
    
         
             
                    end
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                    # @param event [Event]
         
     | 
| 
       46 
46 
     | 
    
         
             
                    # @return [Float]
         
     | 
| 
       47 
47 
     | 
    
         
             
                    def args_accel(event)
         
     | 
| 
       48 
48 
     | 
    
         
             
                      accel_index = Config::Index.new([*event.record.index.keys, :accel])
         
     | 
| 
       49 
     | 
    
         
            -
                      (Config.search(accel_index) || 1).to_f
         
     | 
| 
      
 49 
     | 
    
         
            +
                      (Config.instance.search(accel_index) || 1).to_f
         
     | 
| 
       50 
50 
     | 
    
         
             
                    end
         
     | 
| 
       51 
51 
     | 
    
         
             
                  end
         
     | 
| 
       52 
52 
     | 
    
         
             
                end
         
     | 
| 
         @@ -26,12 +26,9 @@ module Fusuma 
     | 
|
| 
       26 
26 
     | 
    
         
             
                    end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
                    # @param event [Events::Event]
         
     | 
| 
       29 
     | 
    
         
            -
                    # @param time [Time]
         
     | 
| 
       30 
29 
     | 
    
         
             
                    # @return [TrueClass, FalseClass]
         
     | 
| 
       31 
30 
     | 
    
         
             
                    def enough_interval?(event)
         
     | 
| 
       32 
     | 
    
         
            -
                       
     | 
| 
       33 
     | 
    
         
            -
                      #       Otherwise, a wrong index will cause invalid intervals.
         
     | 
| 
       34 
     | 
    
         
            -
                      return true if event.record.index.with_context.keys.any? { |key| key.symbol == :end }
         
     | 
| 
      
 31 
     | 
    
         
            +
                      return true if event.record.index.keys.any? { |key| key.symbol == :end }
         
     | 
| 
       35 
32 
     | 
    
         | 
| 
       36 
33 
     | 
    
         
             
                      return false if @wait_until && event.time < @wait_until
         
     | 
| 
       37 
34 
     | 
    
         | 
| 
         @@ -25,7 +25,8 @@ module Fusuma 
     | 
|
| 
       25 
25 
     | 
    
         
             
                        keep_device.reset
         
     | 
| 
       26 
26 
     | 
    
         
             
                        return false
         
     | 
| 
       27 
27 
     | 
    
         
             
                      end
         
     | 
| 
       28 
     | 
    
         
            -
                       
     | 
| 
      
 28 
     | 
    
         
            +
                      device_id = record.to_s.match(/\S*/, 1).to_s
         
     | 
| 
      
 29 
     | 
    
         
            +
                      keep_device.all.map(&:id).include?(device_id)
         
     | 
| 
       29 
30 
     | 
    
         
             
                    end
         
     | 
| 
       30 
31 
     | 
    
         | 
| 
       31 
32 
     | 
    
         
             
                    def keep_device
         
     | 
| 
         @@ -9,8 +9,14 @@ module Fusuma 
     | 
|
| 
       9 
9 
     | 
    
         
             
                  # Inherite this base
         
     | 
| 
       10 
10 
     | 
    
         
             
                  # @abstract Subclass and override {#io} to implement
         
     | 
| 
       11 
11 
     | 
    
         
             
                  class Input < Base
         
     | 
| 
      
 12 
     | 
    
         
            +
                    def initialize(*args)
         
     | 
| 
      
 13 
     | 
    
         
            +
                      super(*args)
         
     | 
| 
      
 14 
     | 
    
         
            +
                      @tag = self.class.name.split("Inputs::").last.underscore
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    attr_reader :tag
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       12 
19 
     | 
    
         
             
                    # Wait multiple inputs until it becomes readable
         
     | 
| 
       13 
     | 
    
         
            -
                    # and read lines with nonblock
         
     | 
| 
       14 
20 
     | 
    
         
             
                    # @param inputs [Array<Input>]
         
     | 
| 
       15 
21 
     | 
    
         
             
                    # @return [Event]
         
     | 
| 
       16 
22 
     | 
    
         
             
                    def self.select(inputs)
         
     | 
| 
         @@ -20,20 +26,17 @@ module Fusuma 
     | 
|
| 
       20 
26 
     | 
    
         
             
                      input = inputs.find { |i| i.io == io }
         
     | 
| 
       21 
27 
     | 
    
         | 
| 
       22 
28 
     | 
    
         
             
                      begin
         
     | 
| 
       23 
     | 
    
         
            -
                         
     | 
| 
      
 29 
     | 
    
         
            +
                        # NOTE: io.readline is blocking method
         
     | 
| 
      
 30 
     | 
    
         
            +
                        # each input plugin must write line to pipe (include `\n`)
         
     | 
| 
      
 31 
     | 
    
         
            +
                        line = io.readline(chomp: true)
         
     | 
| 
       24 
32 
     | 
    
         
             
                      rescue EOFError => e
         
     | 
| 
       25 
     | 
    
         
            -
                         
     | 
| 
       26 
     | 
    
         
            -
                         
     | 
| 
       27 
     | 
    
         
            -
                         
     | 
| 
       28 
     | 
    
         
            -
                          warn "stop process: #{i.class.name.underscore}"
         
     | 
| 
       29 
     | 
    
         
            -
                          Process.kill(:SIGKILL, i.pid)
         
     | 
| 
       30 
     | 
    
         
            -
                        end
         
     | 
| 
       31 
     | 
    
         
            -
                        exit 1
         
     | 
| 
      
 33 
     | 
    
         
            +
                        MultiLogger.error "#{input.class.name}: #{e}"
         
     | 
| 
      
 34 
     | 
    
         
            +
                        MultiLogger.error "Shutdown fusuma process..."
         
     | 
| 
      
 35 
     | 
    
         
            +
                        Process.kill("TERM", Process.pid)
         
     | 
| 
       32 
36 
     | 
    
         
             
                      rescue => e
         
     | 
| 
       33 
     | 
    
         
            -
                         
     | 
| 
      
 37 
     | 
    
         
            +
                        MultiLogger.error "#{input.class.name}: #{e}"
         
     | 
| 
       34 
38 
     | 
    
         
             
                        exit 1
         
     | 
| 
       35 
39 
     | 
    
         
             
                      end
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
40 
     | 
    
         
             
                      input.create_event(record: line)
         
     | 
| 
       38 
41 
     | 
    
         
             
                    end
         
     | 
| 
       39 
42 
     | 
    
         | 
| 
         @@ -53,32 +56,7 @@ module Fusuma 
     | 
|
| 
       53 
56 
     | 
    
         
             
                      MultiLogger.debug(input_event: e)
         
     | 
| 
       54 
57 
     | 
    
         
             
                      e
         
     | 
| 
       55 
58 
     | 
    
         
             
                    end
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                    def tag
         
     | 
| 
       58 
     | 
    
         
            -
                      self.class.name.split("Inputs::").last.underscore
         
     | 
| 
       59 
     | 
    
         
            -
                    end
         
     | 
| 
       60 
59 
     | 
    
         
             
                  end
         
     | 
| 
       61 
60 
     | 
    
         
             
                end
         
     | 
| 
       62 
61 
     | 
    
         
             
              end
         
     | 
| 
       63 
62 
     | 
    
         
             
            end
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
            # ref: https://github.com/Homebrew/brew/blob/6b2dbbc96f7d8aa12f9b8c9c60107c9cc58befc4/Library/Homebrew/extend/io.rb
         
     | 
| 
       66 
     | 
    
         
            -
            class IO
         
     | 
| 
       67 
     | 
    
         
            -
              def readline_nonblock(sep = $INPUT_RECORD_SEPARATOR)
         
     | 
| 
       68 
     | 
    
         
            -
                line = +""
         
     | 
| 
       69 
     | 
    
         
            -
                buffer = +""
         
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
                loop do
         
     | 
| 
       72 
     | 
    
         
            -
                  break if buffer == sep
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
                  read_nonblock(1, buffer)
         
     | 
| 
       75 
     | 
    
         
            -
                  line.concat(buffer)
         
     | 
| 
       76 
     | 
    
         
            -
                end
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                line.freeze
         
     | 
| 
       79 
     | 
    
         
            -
              rescue IO::WaitReadable, EOFError => e
         
     | 
| 
       80 
     | 
    
         
            -
                raise e if line.empty?
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
                line.freeze
         
     | 
| 
       83 
     | 
    
         
            -
              end
         
     | 
| 
       84 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,20 +1,29 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require_relative "./input"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "timeout"
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module Fusuma
         
     | 
| 
       6 
7 
     | 
    
         
             
              module Plugin
         
     | 
| 
       7 
8 
     | 
    
         
             
                module Inputs
         
     | 
| 
       8 
9 
     | 
    
         
             
                  # libinput commands wrapper
         
     | 
| 
       9 
10 
     | 
    
         
             
                  class TimerInput < Input
         
     | 
| 
       10 
     | 
    
         
            -
                     
     | 
| 
      
 11 
     | 
    
         
            +
                    include Singleton
         
     | 
| 
      
 12 
     | 
    
         
            +
                    DEFAULT_INTERVAL = 5
         
     | 
| 
      
 13 
     | 
    
         
            +
                    EPSILON_TIME = 0.02
         
     | 
| 
       11 
14 
     | 
    
         
             
                    def config_param_types
         
     | 
| 
       12 
15 
     | 
    
         
             
                      {
         
     | 
| 
       13 
16 
     | 
    
         
             
                        interval: [Float]
         
     | 
| 
       14 
17 
     | 
    
         
             
                      }
         
     | 
| 
       15 
18 
     | 
    
         
             
                    end
         
     | 
| 
       16 
19 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                     
     | 
| 
      
 20 
     | 
    
         
            +
                    def initialize(*args, interval: nil)
         
     | 
| 
      
 21 
     | 
    
         
            +
                      super(*args)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @interval = interval || config_params(:interval) || DEFAULT_INTERVAL
         
     | 
| 
      
 23 
     | 
    
         
            +
                      @early_wake_queue = Queue.new
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    attr_reader :pid, :interval
         
     | 
| 
       18 
27 
     | 
    
         | 
| 
       19 
28 
     | 
    
         
             
                    def io
         
     | 
| 
       20 
29 
     | 
    
         
             
                      @io ||= begin
         
     | 
| 
         @@ -26,26 +35,36 @@ module Fusuma 
     | 
|
| 
       26 
35 
     | 
    
         
             
                    end
         
     | 
| 
       27 
36 
     | 
    
         | 
| 
       28 
37 
     | 
    
         
             
                    def start(reader, writer)
         
     | 
| 
       29 
     | 
    
         
            -
                       
     | 
| 
       30 
     | 
    
         
            -
                        timer_loop( 
     | 
| 
      
 38 
     | 
    
         
            +
                      Thread.new do
         
     | 
| 
      
 39 
     | 
    
         
            +
                        timer_loop(writer)
         
     | 
| 
       31 
40 
     | 
    
         
             
                      end
         
     | 
| 
       32 
     | 
    
         
            -
                       
     | 
| 
       33 
     | 
    
         
            -
                      writer.close
         
     | 
| 
       34 
     | 
    
         
            -
                      pid
         
     | 
| 
      
 41 
     | 
    
         
            +
                      nil
         
     | 
| 
       35 
42 
     | 
    
         
             
                    end
         
     | 
| 
       36 
43 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                    def timer_loop( 
     | 
| 
       38 
     | 
    
         
            -
                       
     | 
| 
       39 
     | 
    
         
            -
                       
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
      
 44 
     | 
    
         
            +
                    def timer_loop(writer)
         
     | 
| 
      
 45 
     | 
    
         
            +
                      delta_t = @interval
         
     | 
| 
      
 46 
     | 
    
         
            +
                      next_wake = Time.now + delta_t
         
     | 
| 
      
 47 
     | 
    
         
            +
                      loop do
         
     | 
| 
      
 48 
     | 
    
         
            +
                        sleep_time = next_wake - Time.now
         
     | 
| 
      
 49 
     | 
    
         
            +
                        if sleep_time <= 0
         
     | 
| 
      
 50 
     | 
    
         
            +
                          raise Timeout::Error
         
     | 
| 
      
 51 
     | 
    
         
            +
                        end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                        Timeout.timeout(sleep_time) do
         
     | 
| 
      
 54 
     | 
    
         
            +
                          next_wake = [@early_wake_queue.deq, next_wake].min
         
     | 
| 
       43 
55 
     | 
    
         
             
                        end
         
     | 
| 
       44 
     | 
    
         
            -
                      rescue  
     | 
| 
       45 
     | 
    
         
            -
                         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                        MultiLogger.error e
         
     | 
| 
      
 56 
     | 
    
         
            +
                      rescue Timeout::Error
         
     | 
| 
      
 57 
     | 
    
         
            +
                        writer.puts "timer"
         
     | 
| 
      
 58 
     | 
    
         
            +
                        next_wake = Time.now + delta_t
         
     | 
| 
       48 
59 
     | 
    
         
             
                      end
         
     | 
| 
      
 60 
     | 
    
         
            +
                    rescue Errno::EPIPE
         
     | 
| 
      
 61 
     | 
    
         
            +
                      exit 0
         
     | 
| 
      
 62 
     | 
    
         
            +
                    rescue => e
         
     | 
| 
      
 63 
     | 
    
         
            +
                      MultiLogger.error e
         
     | 
| 
      
 64 
     | 
    
         
            +
                    end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    def wake_early(t)
         
     | 
| 
      
 67 
     | 
    
         
            +
                      @early_wake_queue.push(t + EPSILON_TIME)
         
     | 
| 
       49 
68 
     | 
    
         
             
                    end
         
     | 
| 
       50 
69 
     | 
    
         | 
| 
       51 
70 
     | 
    
         
             
                    private
         
     | 
| 
         @@ -53,10 +72,6 @@ module Fusuma 
     | 
|
| 
       53 
72 
     | 
    
         
             
                    def create_io
         
     | 
| 
       54 
73 
     | 
    
         
             
                      IO.pipe
         
     | 
| 
       55 
74 
     | 
    
         
             
                    end
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                    def interval
         
     | 
| 
       58 
     | 
    
         
            -
                      config_params(:interval) || DEFAULT_INTERVAL
         
     | 
| 
       59 
     | 
    
         
            -
                    end
         
     | 
| 
       60 
75 
     | 
    
         
             
                  end
         
     | 
| 
       61 
76 
     | 
    
         
             
                end
         
     | 
| 
       62 
77 
     | 
    
         
             
              end
         
     |