fusuma 3.9.0 → 3.10.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 +27 -1
- data/lib/fusuma/config/index.rb +12 -7
- data/lib/fusuma/config/searcher.rb +17 -6
- data/lib/fusuma/config/yaml_duplication_checker.rb +6 -0
- data/lib/fusuma/config.rb +17 -3
- data/lib/fusuma/custom_process.rb +3 -0
- data/lib/fusuma/device.rb +15 -0
- data/lib/fusuma/environment.rb +4 -0
- data/lib/fusuma/hash_support.rb +6 -1
- data/lib/fusuma/libinput_command.rb +11 -3
- data/lib/fusuma/multi_logger.rb +15 -4
- data/lib/fusuma/plugin/base.rb +11 -1
- data/lib/fusuma/plugin/buffers/buffer.rb +6 -0
- data/lib/fusuma/plugin/buffers/gesture_buffer.rb +15 -9
- data/lib/fusuma/plugin/buffers/timer_buffer.rb +2 -1
- data/lib/fusuma/plugin/detectors/detector.rb +15 -15
- data/lib/fusuma/plugin/detectors/hold_detector.rb +10 -2
- data/lib/fusuma/plugin/detectors/pinch_detector.rb +13 -1
- data/lib/fusuma/plugin/detectors/rotate_detector.rb +11 -0
- data/lib/fusuma/plugin/detectors/swipe_detector.rb +12 -0
- data/lib/fusuma/plugin/events/event.rb +5 -2
- data/lib/fusuma/plugin/events/records/gesture_record.rb +2 -0
- data/lib/fusuma/plugin/events/records/index_record.rb +2 -0
- data/lib/fusuma/plugin/events/records/record.rb +1 -0
- data/lib/fusuma/plugin/events/records/text_record.rb +3 -0
- data/lib/fusuma/plugin/executors/command_executor.rb +5 -1
- data/lib/fusuma/plugin/executors/executor.rb +6 -0
- data/lib/fusuma/plugin/filters/filter.rb +2 -0
- data/lib/fusuma/plugin/filters/libinput_device_filter.rb +10 -0
- data/lib/fusuma/plugin/inputs/input.rb +5 -0
- data/lib/fusuma/plugin/inputs/libinput_command_input.rb +10 -3
- data/lib/fusuma/plugin/inputs/timer_input.rb +4 -0
- data/lib/fusuma/plugin/manager.rb +11 -1
- data/lib/fusuma/plugin/parsers/libinput_gesture_parser.rb +9 -0
- data/lib/fusuma/plugin/parsers/parser.rb +4 -0
- data/lib/fusuma/string_support.rb +1 -0
- data/lib/fusuma/version.rb +1 -1
- data/lib/fusuma.rb +10 -1
- metadata +2 -2
data/lib/fusuma/multi_logger.rb
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "logger"
|
|
4
|
+
require "singleton"
|
|
5
|
+
|
|
3
6
|
# module as namespace
|
|
4
7
|
module Fusuma
|
|
5
|
-
require "logger"
|
|
6
|
-
require "singleton"
|
|
7
8
|
# logger separate between stdout and strerr
|
|
8
9
|
class MultiLogger < Logger
|
|
9
10
|
include Singleton
|
|
@@ -14,23 +15,28 @@ module Fusuma
|
|
|
14
15
|
class << self
|
|
15
16
|
attr_writer :filepath
|
|
16
17
|
|
|
18
|
+
#: (untyped) -> void
|
|
17
19
|
def info(msg)
|
|
18
20
|
instance.info(msg)
|
|
19
21
|
end
|
|
20
22
|
|
|
23
|
+
#: (untyped) -> void
|
|
21
24
|
def debug(msg)
|
|
22
25
|
instance.debug(msg)
|
|
23
26
|
end
|
|
24
27
|
|
|
28
|
+
#: (untyped) -> void
|
|
25
29
|
def warn(msg)
|
|
26
30
|
instance.warn(msg)
|
|
27
31
|
end
|
|
28
32
|
|
|
33
|
+
#: (untyped) -> void
|
|
29
34
|
def error(msg)
|
|
30
35
|
instance.error(msg)
|
|
31
36
|
end
|
|
32
37
|
end
|
|
33
38
|
|
|
39
|
+
#: () -> void
|
|
34
40
|
def initialize
|
|
35
41
|
filepath = self.class.instance_variable_get(:@filepath)
|
|
36
42
|
if filepath
|
|
@@ -45,28 +51,33 @@ module Fusuma
|
|
|
45
51
|
@debug_mode = false
|
|
46
52
|
end
|
|
47
53
|
|
|
54
|
+
#: (untyped) -> void
|
|
48
55
|
def debug(msg)
|
|
49
56
|
return unless debug_mode?
|
|
50
57
|
|
|
51
58
|
return if ignore_pattern?(msg)
|
|
52
59
|
|
|
53
|
-
super
|
|
60
|
+
super
|
|
54
61
|
end
|
|
55
62
|
|
|
63
|
+
#: (untyped) -> void
|
|
56
64
|
def warn(msg)
|
|
57
65
|
err_logger.warn(msg)
|
|
58
66
|
end
|
|
59
67
|
|
|
68
|
+
#: (untyped) -> void
|
|
60
69
|
def error(msg)
|
|
61
70
|
err_logger.error(msg)
|
|
62
71
|
end
|
|
63
72
|
|
|
73
|
+
#: () -> bool
|
|
64
74
|
def debug_mode?
|
|
65
75
|
debug_mode
|
|
66
76
|
end
|
|
67
77
|
|
|
68
78
|
private
|
|
69
79
|
|
|
80
|
+
#: (String) -> bool
|
|
70
81
|
def ignore_pattern?(msg)
|
|
71
82
|
# TODO: configurable from config.yml
|
|
72
83
|
# pattern = /timer_input|remap_touchpad_input|thumbsense context|libinput_command_input/
|
|
@@ -74,7 +85,7 @@ module Fusuma
|
|
|
74
85
|
case msg
|
|
75
86
|
when Hash
|
|
76
87
|
e = msg.values.find { |v| v.is_a? Fusuma::Plugin::Events::Event }
|
|
77
|
-
return unless e
|
|
88
|
+
return false unless e
|
|
78
89
|
|
|
79
90
|
e.tag.match?(pattern)
|
|
80
91
|
when String
|
data/lib/fusuma/plugin/base.rb
CHANGED
|
@@ -11,7 +11,13 @@ module Fusuma
|
|
|
11
11
|
# when inherited from subclass
|
|
12
12
|
def self.inherited(subclass)
|
|
13
13
|
super
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
locations = Kernel.caller_locations(1..1)
|
|
16
|
+
if locations.nil? || locations.empty?
|
|
17
|
+
raise "Plugin class #{subclass.name} must be defined in a file."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
subclass_path = locations.first.path
|
|
15
21
|
Manager.add(plugin_class: subclass, plugin_path: subclass_path)
|
|
16
22
|
end
|
|
17
23
|
|
|
@@ -22,11 +28,13 @@ module Fusuma
|
|
|
22
28
|
end
|
|
23
29
|
|
|
24
30
|
# @abstract override `#shutdown` to implement
|
|
31
|
+
#: () -> nil
|
|
25
32
|
def shutdown
|
|
26
33
|
end
|
|
27
34
|
|
|
28
35
|
# config parameter name and Type of the value of parameter
|
|
29
36
|
# @return [Hash]
|
|
37
|
+
#: () -> Hash[Symbol, Array[Class] | Class]
|
|
30
38
|
def config_param_types
|
|
31
39
|
raise NotImplementedError, "override #{self.class.name}##{__method__}"
|
|
32
40
|
end
|
|
@@ -34,6 +42,7 @@ module Fusuma
|
|
|
34
42
|
# @param key [Symbol]
|
|
35
43
|
# @param base [Config::Index]
|
|
36
44
|
# @return [Object]
|
|
45
|
+
#: (?Symbol?) -> (String | Hash[untyped, untyped] | Float | bool)?
|
|
37
46
|
def config_params(key = nil)
|
|
38
47
|
@config_params ||= {}
|
|
39
48
|
if @config_params["#{config_index.cache_key},#{key}"]
|
|
@@ -59,6 +68,7 @@ module Fusuma
|
|
|
59
68
|
end
|
|
60
69
|
end
|
|
61
70
|
|
|
71
|
+
#: () -> Fusuma::Config::Index
|
|
62
72
|
def config_index
|
|
63
73
|
@config_index ||= Config::Index.new(self.class.name.gsub("Fusuma::", "").underscore.split("/"))
|
|
64
74
|
end
|
|
@@ -7,6 +7,7 @@ module Fusuma
|
|
|
7
7
|
module Buffers
|
|
8
8
|
# buffer events and output
|
|
9
9
|
class Buffer < Base
|
|
10
|
+
#: (*nil | Array[untyped]) -> void
|
|
10
11
|
def initialize(*args)
|
|
11
12
|
super()
|
|
12
13
|
@events = Array.new(*args)
|
|
@@ -15,11 +16,13 @@ module Fusuma
|
|
|
15
16
|
attr_reader :events
|
|
16
17
|
|
|
17
18
|
# @return [String]
|
|
19
|
+
#: () -> String
|
|
18
20
|
def type
|
|
19
21
|
@type ||= self.class.name.underscore.split("/").last.gsub("_buffer", "")
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
# @param event [Event]
|
|
25
|
+
#: (Fusuma::Plugin::Events::Event) -> Array[untyped]?
|
|
23
26
|
def buffer(event)
|
|
24
27
|
return if event&.tag != source
|
|
25
28
|
|
|
@@ -32,17 +35,20 @@ module Fusuma
|
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
# @return [TrueClass, FalseClass]
|
|
38
|
+
#: () -> bool
|
|
35
39
|
def empty?
|
|
36
40
|
@events.empty?
|
|
37
41
|
end
|
|
38
42
|
|
|
39
43
|
# clear buffer
|
|
44
|
+
#: () -> void
|
|
40
45
|
def clear
|
|
41
46
|
@events.clear
|
|
42
47
|
end
|
|
43
48
|
|
|
44
49
|
# Set source for tag from config.yml.
|
|
45
50
|
# DEFAULT_SOURCE is defined in each plugins.
|
|
51
|
+
#: () -> String
|
|
46
52
|
def source
|
|
47
53
|
@source ||= config_params(:source) || self.class.const_get(:DEFAULT_SOURCE)
|
|
48
54
|
end
|
|
@@ -11,6 +11,7 @@ module Fusuma
|
|
|
11
11
|
DEFAULT_SOURCE = "libinput_gesture_parser"
|
|
12
12
|
DEFAULT_SECONDS_TO_KEEP = 100
|
|
13
13
|
|
|
14
|
+
#: (*nil | Array[untyped]) -> void
|
|
14
15
|
def initialize(*args)
|
|
15
16
|
super
|
|
16
17
|
@cache = {}
|
|
@@ -18,6 +19,7 @@ module Fusuma
|
|
|
18
19
|
@cache_sum10 = {}
|
|
19
20
|
end
|
|
20
21
|
|
|
22
|
+
#: () -> Hash[untyped, untyped]
|
|
21
23
|
def clear
|
|
22
24
|
super.clear
|
|
23
25
|
@cache = {}
|
|
@@ -25,6 +27,7 @@ module Fusuma
|
|
|
25
27
|
@cache_sum10 = {}
|
|
26
28
|
end
|
|
27
29
|
|
|
30
|
+
#: () -> Hash[Symbol, Array[Class] | Class]
|
|
28
31
|
def config_param_types
|
|
29
32
|
{
|
|
30
33
|
source: [String],
|
|
@@ -34,6 +37,7 @@ module Fusuma
|
|
|
34
37
|
|
|
35
38
|
# @param event [Event]
|
|
36
39
|
# @return [Buffer, FalseClass]
|
|
40
|
+
#: (Fusuma::Plugin::Events::Event) -> Fusuma::Plugin::Buffers::GestureBuffer?
|
|
37
41
|
def buffer(event)
|
|
38
42
|
# TODO: buffering events into buffer plugins
|
|
39
43
|
# - gesture event buffer
|
|
@@ -45,10 +49,11 @@ module Fusuma
|
|
|
45
49
|
self
|
|
46
50
|
end
|
|
47
51
|
|
|
52
|
+
#: (?current_time: Time) -> void
|
|
48
53
|
def clear_expired(current_time: Time.now)
|
|
49
54
|
clear if ended?
|
|
50
55
|
|
|
51
|
-
@seconds_to_keep ||=
|
|
56
|
+
@seconds_to_keep ||= config_params(:seconds_to_keep) || DEFAULT_SECONDS_TO_KEEP
|
|
52
57
|
@events.each do |e|
|
|
53
58
|
break if current_time - e.time < @seconds_to_keep
|
|
54
59
|
|
|
@@ -61,6 +66,7 @@ module Fusuma
|
|
|
61
66
|
end
|
|
62
67
|
end
|
|
63
68
|
|
|
69
|
+
#: () -> bool
|
|
64
70
|
def ended?
|
|
65
71
|
return false if empty?
|
|
66
72
|
|
|
@@ -74,6 +80,7 @@ module Fusuma
|
|
|
74
80
|
|
|
75
81
|
# @param attr [Symbol]
|
|
76
82
|
# @return [Float]
|
|
83
|
+
#: (Symbol) -> Float
|
|
77
84
|
def sum_attrs(attr)
|
|
78
85
|
updating_events.map do |gesture_event|
|
|
79
86
|
gesture_event.record.delta[attr].to_f
|
|
@@ -82,6 +89,7 @@ module Fusuma
|
|
|
82
89
|
|
|
83
90
|
# @param attr [Symbol]
|
|
84
91
|
# @return [Float]
|
|
92
|
+
#: (Symbol) -> Float
|
|
85
93
|
def sum_last10_attrs(attr) # sums last 10 values of attr (or all if length < 10)
|
|
86
94
|
cache_entry = (@cache_sum10[attr] ||= CacheEntry.new(0, 0))
|
|
87
95
|
upd_ev = updating_events
|
|
@@ -90,7 +98,7 @@ module Fusuma
|
|
|
90
98
|
gesture_event.record.delta[attr].to_f
|
|
91
99
|
end.reduce(:+)
|
|
92
100
|
elsif upd_ev.length > cache_entry.checked
|
|
93
|
-
cache_entry.value = cache_entry.value + upd_ev[-1].record.delta[attr].to_f -
|
|
101
|
+
cache_entry.value = cache_entry.value + upd_ev[-1].record.delta[attr].to_f -
|
|
94
102
|
((upd_ev.length > 10) ? upd_ev[-11].record.delta[attr].to_f : 0)
|
|
95
103
|
else
|
|
96
104
|
return cache_entry.value
|
|
@@ -99,6 +107,7 @@ module Fusuma
|
|
|
99
107
|
cache_entry.value
|
|
100
108
|
end
|
|
101
109
|
|
|
110
|
+
#: () -> Array[untyped]
|
|
102
111
|
def updating_events
|
|
103
112
|
cache_entry = (@cache[:updating_events] ||= CacheEntry.new(0, []))
|
|
104
113
|
cache_entry.checked.upto(@events.length - 1).each do |i|
|
|
@@ -110,11 +119,13 @@ module Fusuma
|
|
|
110
119
|
|
|
111
120
|
# @param attr [Symbol]
|
|
112
121
|
# @return [Float]
|
|
122
|
+
#: (Symbol) -> Float
|
|
113
123
|
def avg_attrs(attr)
|
|
114
124
|
sum_attrs(attr).to_f / updating_events.length
|
|
115
125
|
end
|
|
116
126
|
|
|
117
127
|
# return [Integer]
|
|
128
|
+
#: () -> Integer
|
|
118
129
|
def finger
|
|
119
130
|
@events.last.record.finger.to_i
|
|
120
131
|
end
|
|
@@ -127,13 +138,7 @@ module Fusuma
|
|
|
127
138
|
@events.last.record.gesture
|
|
128
139
|
end
|
|
129
140
|
|
|
130
|
-
|
|
131
|
-
return enum_for(:select_by_events) unless block
|
|
132
|
-
|
|
133
|
-
events = @events.select(&block)
|
|
134
|
-
self.class.new events
|
|
135
|
-
end
|
|
136
|
-
|
|
141
|
+
#: (String) -> Fusuma::Plugin::Buffers::GestureBuffer
|
|
137
142
|
def select_by_type(type)
|
|
138
143
|
cache_entry = (@cache_select_by[type] ||= CacheEntry.new(0, self.class.new([])))
|
|
139
144
|
cache_entry.checked.upto(@events.length - 1).each do |i|
|
|
@@ -143,6 +148,7 @@ module Fusuma
|
|
|
143
148
|
cache_entry.value
|
|
144
149
|
end
|
|
145
150
|
|
|
151
|
+
#: () -> Fusuma::Plugin::Buffers::GestureBuffer
|
|
146
152
|
def select_from_last_begin
|
|
147
153
|
return self if empty?
|
|
148
154
|
cache_entry = (@cache[:last_begin] ||= CacheEntry.new(0, nil))
|
|
@@ -19,6 +19,7 @@ module Fusuma
|
|
|
19
19
|
|
|
20
20
|
# @param event [Event]
|
|
21
21
|
# @return [Buffer, NilClass]
|
|
22
|
+
#: (Fusuma::Plugin::Events::Event) -> Fusuma::Plugin::Buffers::TimerBuffer?
|
|
22
23
|
def buffer(event)
|
|
23
24
|
return if event&.tag != source
|
|
24
25
|
|
|
@@ -27,7 +28,7 @@ module Fusuma
|
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
def clear_expired(current_time: Time.now)
|
|
30
|
-
@seconds_to_keep ||=
|
|
31
|
+
@seconds_to_keep ||= config_params(:seconds_to_keep) || DEFAULT_SECONDS_TO_KEEP
|
|
31
32
|
@events.each do |e|
|
|
32
33
|
break if current_time - e.time < @seconds_to_keep
|
|
33
34
|
|
|
@@ -8,22 +8,29 @@ module Fusuma
|
|
|
8
8
|
module Detectors
|
|
9
9
|
# Inherite this base
|
|
10
10
|
class Detector < Base
|
|
11
|
+
def self.type(tag_name)
|
|
12
|
+
tag_name.gsub("_detector", "")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
#: (*nil) -> void
|
|
11
16
|
def initialize(*args)
|
|
12
17
|
super
|
|
13
|
-
@tag = self.class.
|
|
14
|
-
@type = self.class.type
|
|
18
|
+
@tag = self.class.name.split("Detectors::").last.underscore
|
|
19
|
+
@type = self.class.type(@tag)
|
|
15
20
|
end
|
|
16
21
|
|
|
17
|
-
attr_reader :tag
|
|
18
|
-
attr_reader :type
|
|
22
|
+
attr_reader :tag #: String
|
|
23
|
+
attr_reader :type #: String
|
|
19
24
|
|
|
20
25
|
# @return [Array<String>]
|
|
26
|
+
#: () -> Array[String]
|
|
21
27
|
def sources
|
|
22
28
|
@sources ||= self.class.const_get(:SOURCES)
|
|
23
29
|
end
|
|
24
30
|
|
|
25
31
|
# Always watch buffers and detect them or not
|
|
26
32
|
# @return [TrueClass,FalseClass]
|
|
33
|
+
#: () -> bool
|
|
27
34
|
def watch?
|
|
28
35
|
false
|
|
29
36
|
end
|
|
@@ -39,28 +46,21 @@ module Fusuma
|
|
|
39
46
|
|
|
40
47
|
# @param record [Events::Records::Record]
|
|
41
48
|
# @return [Events::Event]
|
|
49
|
+
#: (record: Fusuma::Plugin::Events::Records::IndexRecord) -> Fusuma::Plugin::Events::Event
|
|
42
50
|
def create_event(record:)
|
|
43
51
|
@last_time = Time.now
|
|
44
|
-
Events::Event.new(time: @last_time, tag: tag, record: record)
|
|
52
|
+
Events::Event.new(time: @last_time, tag: @tag, record: record)
|
|
45
53
|
end
|
|
46
54
|
|
|
55
|
+
#: () -> Time
|
|
47
56
|
def last_time
|
|
48
57
|
@last_time ||= Time.now
|
|
49
58
|
end
|
|
50
59
|
|
|
60
|
+
#: () -> bool
|
|
51
61
|
def first_time?
|
|
52
62
|
@last_time.nil?
|
|
53
63
|
end
|
|
54
|
-
|
|
55
|
-
class << self
|
|
56
|
-
def tag
|
|
57
|
-
name.split("Detectors::").last.underscore
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def type(tag_name = tag)
|
|
61
|
-
tag_name.gsub("_detector", "")
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
end
|
|
@@ -14,6 +14,7 @@ module Fusuma
|
|
|
14
14
|
|
|
15
15
|
BASE_THRESHOLD = 0.7
|
|
16
16
|
|
|
17
|
+
#: (*nil) -> void
|
|
17
18
|
def initialize(*args)
|
|
18
19
|
super
|
|
19
20
|
@timer = Inputs::TimerInput.instance
|
|
@@ -23,6 +24,7 @@ module Fusuma
|
|
|
23
24
|
# @return [Events::Event] if event is detected
|
|
24
25
|
# @return [Array<Events::Event>] if hold end event is detected
|
|
25
26
|
# @return [NilClass] if event is NOT detected
|
|
27
|
+
#: (Array[untyped]) -> Fusuma::Plugin::Events::Event?
|
|
26
28
|
def detect(buffers)
|
|
27
29
|
hold_buffer = find_hold_buffer(buffers)
|
|
28
30
|
return if hold_buffer.empty?
|
|
@@ -77,6 +79,7 @@ module Fusuma
|
|
|
77
79
|
|
|
78
80
|
# @param [Integer] finger
|
|
79
81
|
# @return [Config::Index]
|
|
82
|
+
#: (finger: Integer) -> Fusuma::Config::Index
|
|
80
83
|
def create_oneshot_index(finger:)
|
|
81
84
|
Config::Index.new(
|
|
82
85
|
[
|
|
@@ -88,6 +91,7 @@ module Fusuma
|
|
|
88
91
|
|
|
89
92
|
# @param [Integer] finger
|
|
90
93
|
# @return [Config::Index]
|
|
94
|
+
#: (finger: Integer, status: String) -> Fusuma::Config::Index
|
|
91
95
|
def create_repeat_index(finger:, status:)
|
|
92
96
|
Config::Index.new(
|
|
93
97
|
[
|
|
@@ -102,12 +106,14 @@ module Fusuma
|
|
|
102
106
|
|
|
103
107
|
# @param buffers [Array<Buffers::Buffer>]
|
|
104
108
|
# @return [Buffers::GestureBuffer]
|
|
109
|
+
#: (Array[untyped]) -> Fusuma::Plugin::Buffers::GestureBuffer
|
|
105
110
|
def find_hold_buffer(buffers)
|
|
106
111
|
buffers.find { |b| b.type == BUFFER_TYPE }
|
|
107
112
|
.select_from_last_begin
|
|
108
113
|
.select_by_type(GESTURE_RECORD_TYPE)
|
|
109
114
|
end
|
|
110
115
|
|
|
116
|
+
#: (hold_events: Array[untyped], last_timer: nil | Fusuma::Plugin::Events::Event) -> Float
|
|
111
117
|
def calc_holding_time(hold_events:, last_timer:)
|
|
112
118
|
last_time = if last_timer && (hold_events.last.time < last_timer.time)
|
|
113
119
|
last_timer.time
|
|
@@ -117,16 +123,18 @@ module Fusuma
|
|
|
117
123
|
last_time - hold_events.first.time
|
|
118
124
|
end
|
|
119
125
|
|
|
126
|
+
#: (index: Fusuma::Config::Index, holding_time: Float) -> bool
|
|
120
127
|
def enough?(index:, holding_time:)
|
|
121
128
|
diff = threshold(index: index) - holding_time
|
|
122
129
|
if diff < 0
|
|
123
|
-
true
|
|
130
|
+
return true
|
|
124
131
|
elsif diff < @timer.interval
|
|
125
132
|
@timer.wake_early(Time.now + diff)
|
|
126
|
-
false
|
|
127
133
|
end
|
|
134
|
+
false
|
|
128
135
|
end
|
|
129
136
|
|
|
137
|
+
#: (index: Fusuma::Config::Index) -> Float
|
|
130
138
|
def threshold(index:)
|
|
131
139
|
@threshold ||= {}
|
|
132
140
|
@threshold[index.cache_key] ||= begin
|
|
@@ -16,6 +16,7 @@ module Fusuma
|
|
|
16
16
|
# @param buffers [Array<Buffer>]
|
|
17
17
|
# @return [Events::Event] if event is detected
|
|
18
18
|
# @return [NilClass] if event is NOT detected
|
|
19
|
+
#: (Array[untyped]) -> (Fusuma::Plugin::Events::Event | Array[untyped])?
|
|
19
20
|
def detect(buffers)
|
|
20
21
|
gesture_buffer = buffers.find { |b| b.type == BUFFER_TYPE }
|
|
21
22
|
.select_from_last_begin
|
|
@@ -53,7 +54,7 @@ module Fusuma
|
|
|
53
54
|
delta = event.record.delta
|
|
54
55
|
prev_delta = prev_event.record.delta
|
|
55
56
|
|
|
56
|
-
repeat_direction = Direction.new(target: delta.zoom, base:
|
|
57
|
+
repeat_direction = Direction.new(target: delta.zoom, base: prev_delta&.zoom || 1.0).to_s
|
|
57
58
|
# repeat_quantity = Quantity.new(target: delta.zoom, base: (prev_delta&.zoom || 1.0)).to_f
|
|
58
59
|
|
|
59
60
|
repeat_index = create_repeat_index(gesture: type, finger: finger,
|
|
@@ -97,6 +98,7 @@ module Fusuma
|
|
|
97
98
|
# @param [String] direction
|
|
98
99
|
# @param [String] status
|
|
99
100
|
# @return [Config::Index]
|
|
101
|
+
#: (gesture: String, finger: Integer, direction: String, status: String) -> Fusuma::Config::Index
|
|
100
102
|
def create_repeat_index(gesture:, finger:, direction:, status:)
|
|
101
103
|
Config::Index.new(
|
|
102
104
|
[
|
|
@@ -112,6 +114,7 @@ module Fusuma
|
|
|
112
114
|
# @param [Integer] finger
|
|
113
115
|
# @param [String] direction
|
|
114
116
|
# @return [Config::Index]
|
|
117
|
+
#: (gesture: String, finger: Integer, direction: String) -> Fusuma::Config::Index
|
|
115
118
|
def create_oneshot_index(gesture:, finger:, direction:)
|
|
116
119
|
Config::Index.new(
|
|
117
120
|
[
|
|
@@ -124,16 +127,19 @@ module Fusuma
|
|
|
124
127
|
|
|
125
128
|
private
|
|
126
129
|
|
|
130
|
+
#: (Fusuma::Plugin::Events::Event, Fusuma::Plugin::Events::Event) -> bool
|
|
127
131
|
def moved?(prev_event, event)
|
|
128
132
|
zoom_delta = (event.record.delta.zoom - prev_event.record.delta.zoom).abs
|
|
129
133
|
updating_time = (event.time - prev_event.time) * 100
|
|
130
134
|
zoom_delta / updating_time > 0.01
|
|
131
135
|
end
|
|
132
136
|
|
|
137
|
+
#: (index: Fusuma::Config::Index, quantity: Float) -> bool
|
|
133
138
|
def enough_oneshot_threshold?(index:, quantity:)
|
|
134
139
|
quantity >= threshold(index: index)
|
|
135
140
|
end
|
|
136
141
|
|
|
142
|
+
#: (index: Fusuma::Config::Index) -> Float
|
|
137
143
|
def threshold(index:)
|
|
138
144
|
@threshold ||= {}
|
|
139
145
|
@threshold[index.cache_key] ||= begin
|
|
@@ -150,15 +156,18 @@ module Fusuma
|
|
|
150
156
|
IN = "in"
|
|
151
157
|
OUT = "out"
|
|
152
158
|
|
|
159
|
+
#: (target: Float, base: Integer | Float) -> void
|
|
153
160
|
def initialize(target:, base:)
|
|
154
161
|
@target = target.to_f
|
|
155
162
|
@base = base.to_f
|
|
156
163
|
end
|
|
157
164
|
|
|
165
|
+
#: () -> String
|
|
158
166
|
def to_s
|
|
159
167
|
calc
|
|
160
168
|
end
|
|
161
169
|
|
|
170
|
+
#: () -> String
|
|
162
171
|
def calc
|
|
163
172
|
if @target > @base
|
|
164
173
|
OUT
|
|
@@ -170,15 +179,18 @@ module Fusuma
|
|
|
170
179
|
|
|
171
180
|
# quantity of gesture
|
|
172
181
|
class Quantity
|
|
182
|
+
#: (target: Float, base: Float) -> void
|
|
173
183
|
def initialize(target:, base:)
|
|
174
184
|
@target = target.to_f
|
|
175
185
|
@base = base.to_f
|
|
176
186
|
end
|
|
177
187
|
|
|
188
|
+
#: () -> Float
|
|
178
189
|
def to_f
|
|
179
190
|
calc.to_f
|
|
180
191
|
end
|
|
181
192
|
|
|
193
|
+
#: () -> Float
|
|
182
194
|
def calc
|
|
183
195
|
if @target > @base
|
|
184
196
|
@target / @base
|
|
@@ -16,6 +16,7 @@ module Fusuma
|
|
|
16
16
|
# @param buffers [Array<Buffer>]
|
|
17
17
|
# @return [Events::Event] if event is detected
|
|
18
18
|
# @return [NilClass] if event is NOT detected
|
|
19
|
+
#: (Array[untyped]) -> (Fusuma::Plugin::Events::Event | Array[untyped])?
|
|
19
20
|
def detect(buffers)
|
|
20
21
|
gesture_buffer = buffers.find { |b| b.type == BUFFER_TYPE }
|
|
21
22
|
.select_from_last_begin
|
|
@@ -84,6 +85,7 @@ module Fusuma
|
|
|
84
85
|
# @param [String] direction
|
|
85
86
|
# @param [String] status
|
|
86
87
|
# @return [Config::Index]
|
|
88
|
+
#: (gesture: String, finger: Integer, direction: String, status: String) -> Fusuma::Config::Index
|
|
87
89
|
def create_repeat_index(gesture:, finger:, direction:, status:)
|
|
88
90
|
Config::Index.new(
|
|
89
91
|
[
|
|
@@ -99,6 +101,7 @@ module Fusuma
|
|
|
99
101
|
# @param [Integer] finger
|
|
100
102
|
# @param [String] direction
|
|
101
103
|
# @return [Config::Index]
|
|
104
|
+
#: (gesture: String, finger: Integer, direction: String) -> Fusuma::Config::Index
|
|
102
105
|
def create_oneshot_index(gesture:, finger:, direction:)
|
|
103
106
|
Config::Index.new(
|
|
104
107
|
[
|
|
@@ -111,14 +114,17 @@ module Fusuma
|
|
|
111
114
|
|
|
112
115
|
private
|
|
113
116
|
|
|
117
|
+
#: (Float) -> bool
|
|
114
118
|
def moved?(repeat_quantity)
|
|
115
119
|
repeat_quantity > 0.2
|
|
116
120
|
end
|
|
117
121
|
|
|
122
|
+
#: (index: Fusuma::Config::Index, quantity: Float) -> bool
|
|
118
123
|
def enough_oneshot_threshold?(index:, quantity:)
|
|
119
124
|
quantity > threshold(index: index)
|
|
120
125
|
end
|
|
121
126
|
|
|
127
|
+
#: (index: Fusuma::Config::Index) -> Float
|
|
122
128
|
def threshold(index:)
|
|
123
129
|
@threshold ||= {}
|
|
124
130
|
@threshold[index.cache_key] ||= begin
|
|
@@ -135,14 +141,17 @@ module Fusuma
|
|
|
135
141
|
CLOCKWISE = "clockwise"
|
|
136
142
|
COUNTERCLOCKWISE = "counterclockwise"
|
|
137
143
|
|
|
144
|
+
#: (angle: Float) -> void
|
|
138
145
|
def initialize(angle:)
|
|
139
146
|
@angle = angle.to_f
|
|
140
147
|
end
|
|
141
148
|
|
|
149
|
+
#: () -> String
|
|
142
150
|
def to_s
|
|
143
151
|
calc
|
|
144
152
|
end
|
|
145
153
|
|
|
154
|
+
#: () -> String
|
|
146
155
|
def calc
|
|
147
156
|
if @angle.positive?
|
|
148
157
|
CLOCKWISE
|
|
@@ -154,10 +163,12 @@ module Fusuma
|
|
|
154
163
|
|
|
155
164
|
# quantity of gesture
|
|
156
165
|
class Quantity
|
|
166
|
+
#: (angle: Float) -> void
|
|
157
167
|
def initialize(angle:)
|
|
158
168
|
@angle = angle.abs
|
|
159
169
|
end
|
|
160
170
|
|
|
171
|
+
#: () -> Float
|
|
161
172
|
def to_f
|
|
162
173
|
@angle.to_f
|
|
163
174
|
end
|
|
@@ -16,6 +16,7 @@ module Fusuma
|
|
|
16
16
|
# @param buffers [Array<Buffers::Buffer>]
|
|
17
17
|
# @return [Events::Event] if event is detected
|
|
18
18
|
# @return [NilClass] if event is NOT detected
|
|
19
|
+
#: (Array[untyped]) -> (Fusuma::Plugin::Events::Event | Array[untyped])?
|
|
19
20
|
def detect(buffers)
|
|
20
21
|
gesture_buffer = buffers.find { |b| b.type == BUFFER_TYPE }
|
|
21
22
|
.select_from_last_begin
|
|
@@ -82,6 +83,7 @@ module Fusuma
|
|
|
82
83
|
# @param [String] direction
|
|
83
84
|
# @param [String] status
|
|
84
85
|
# @return [Config::Index]
|
|
86
|
+
#: (gesture: String, finger: Integer, direction: String, status: String) -> Fusuma::Config::Index
|
|
85
87
|
def create_repeat_index(gesture:, finger:, direction:, status:)
|
|
86
88
|
Config::Index.new(
|
|
87
89
|
[
|
|
@@ -97,6 +99,7 @@ module Fusuma
|
|
|
97
99
|
# @param [Integer] finger
|
|
98
100
|
# @param [String] direction
|
|
99
101
|
# @return [Config::Index]
|
|
102
|
+
#: (gesture: String, finger: Integer, direction: String) -> Fusuma::Config::Index
|
|
100
103
|
def create_oneshot_index(gesture:, finger:, direction:)
|
|
101
104
|
Config::Index.new(
|
|
102
105
|
[
|
|
@@ -109,14 +112,17 @@ module Fusuma
|
|
|
109
112
|
|
|
110
113
|
private
|
|
111
114
|
|
|
115
|
+
#: (Float) -> bool
|
|
112
116
|
def moved?(repeat_quantity)
|
|
113
117
|
repeat_quantity > 0.3
|
|
114
118
|
end
|
|
115
119
|
|
|
120
|
+
#: (index: Fusuma::Config::Index, quantity: Float) -> bool
|
|
116
121
|
def enough_oneshot_threshold?(index:, quantity:)
|
|
117
122
|
quantity > threshold(index: index)
|
|
118
123
|
end
|
|
119
124
|
|
|
125
|
+
#: (index: Fusuma::Config::Index) -> Integer
|
|
120
126
|
def threshold(index:)
|
|
121
127
|
@threshold ||= {}
|
|
122
128
|
@threshold[index.cache_key] ||= begin
|
|
@@ -135,15 +141,18 @@ module Fusuma
|
|
|
135
141
|
DOWN = "down"
|
|
136
142
|
UP = "up"
|
|
137
143
|
|
|
144
|
+
#: (move_x: Integer | Float, move_y: Integer | Float) -> void
|
|
138
145
|
def initialize(move_x:, move_y:)
|
|
139
146
|
@move_x = move_x.to_f
|
|
140
147
|
@move_y = move_y.to_f
|
|
141
148
|
end
|
|
142
149
|
|
|
150
|
+
#: () -> String
|
|
143
151
|
def to_s
|
|
144
152
|
calc
|
|
145
153
|
end
|
|
146
154
|
|
|
155
|
+
#: () -> String
|
|
147
156
|
def calc
|
|
148
157
|
if @move_x.abs > @move_y.abs
|
|
149
158
|
@move_x.positive? ? RIGHT : LEFT
|
|
@@ -157,15 +166,18 @@ module Fusuma
|
|
|
157
166
|
|
|
158
167
|
# quantity of gesture
|
|
159
168
|
class Quantity
|
|
169
|
+
#: (move_x: Integer | Float, move_y: Integer | Float) -> void
|
|
160
170
|
def initialize(move_x:, move_y:)
|
|
161
171
|
@x = move_x.to_f.abs
|
|
162
172
|
@y = move_y.to_f.abs
|
|
163
173
|
end
|
|
164
174
|
|
|
175
|
+
#: () -> Float
|
|
165
176
|
def to_f
|
|
166
177
|
calc.to_f
|
|
167
178
|
end
|
|
168
179
|
|
|
180
|
+
#: () -> Float
|
|
169
181
|
def calc
|
|
170
182
|
(@x > @y) ? @x.abs : @y.abs
|
|
171
183
|
end
|