fusuma 2.5.1 → 3.1.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/exe/fusuma +4 -0
- data/fusuma.gemspec +3 -2
- data/lib/fusuma/config/index.rb +19 -46
- data/lib/fusuma/config/searcher.rb +68 -60
- data/lib/fusuma/config.rb +43 -6
- data/lib/fusuma/custom_process.rb +34 -2
- data/lib/fusuma/device.rb +1 -0
- data/lib/fusuma/environment.rb +6 -0
- data/lib/fusuma/hash_support.rb +22 -0
- data/lib/fusuma/multi_logger.rb +16 -0
- data/lib/fusuma/plugin/base.rb +16 -7
- data/lib/fusuma/plugin/buffers/gesture_buffer.rb +62 -6
- data/lib/fusuma/plugin/detectors/detector.rb +10 -9
- data/lib/fusuma/plugin/detectors/hold_detector.rb +28 -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 +8 -16
- 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/libinput_command_input.yml +3 -0
- data/lib/fusuma/plugin/inputs/timer_input.rb +36 -21
- data/lib/fusuma/plugin/manager.rb +17 -6
- data/lib/fusuma/version.rb +1 -1
- data/lib/fusuma.rb +51 -36
- metadata +5 -4
@@ -1,21 +1,53 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "./string_support"
|
4
4
|
|
5
5
|
module Fusuma
|
6
6
|
# Rename process
|
7
7
|
module CustomProcess
|
8
8
|
attr_writer :proctitle
|
9
9
|
|
10
|
+
def child_pids
|
11
|
+
@child_pids ||= []
|
12
|
+
end
|
13
|
+
|
10
14
|
def fork
|
11
|
-
Process.fork do
|
15
|
+
pid = Process.fork do
|
12
16
|
Process.setproctitle(proctitle)
|
17
|
+
set_trap # for child process
|
13
18
|
yield
|
14
19
|
end
|
20
|
+
child_pids << pid
|
21
|
+
pid
|
22
|
+
end
|
23
|
+
|
24
|
+
def shutdown
|
25
|
+
child_pids.each do |pid|
|
26
|
+
Process.kill("TERM", pid)
|
27
|
+
rescue Errno::ESRCH
|
28
|
+
# ignore
|
29
|
+
end
|
30
|
+
|
31
|
+
child_pids.each do |pid|
|
32
|
+
Process.wait(pid)
|
33
|
+
rescue Errno::ECHILD
|
34
|
+
# ignore
|
35
|
+
end
|
15
36
|
end
|
16
37
|
|
17
38
|
def proctitle
|
18
39
|
@proctitle ||= self.class.name.underscore
|
19
40
|
end
|
41
|
+
|
42
|
+
def set_trap
|
43
|
+
Signal.trap("INT") {
|
44
|
+
shutdown
|
45
|
+
exit
|
46
|
+
} # Trap ^C
|
47
|
+
Signal.trap("TERM") {
|
48
|
+
shutdown
|
49
|
+
exit
|
50
|
+
} # Trap `Kill `
|
51
|
+
end
|
20
52
|
end
|
21
53
|
end
|
data/lib/fusuma/device.rb
CHANGED
@@ -66,6 +66,7 @@ module Fusuma
|
|
66
66
|
line_parser = LineParser.new
|
67
67
|
|
68
68
|
libinput_command = Plugin::Inputs::LibinputCommandInput.new.command
|
69
|
+
# note: this libinput command takes a nontrivial amout of time (~200ms)
|
69
70
|
libinput_command.list_devices do |line|
|
70
71
|
line_parser.push(line)
|
71
72
|
end
|
data/lib/fusuma/environment.rb
CHANGED
data/lib/fusuma/hash_support.rb
CHANGED
@@ -2,6 +2,28 @@
|
|
2
2
|
|
3
3
|
# Patch to hash
|
4
4
|
class Hash
|
5
|
+
# activesupport-5.2.0/lib/active_support/core_ext/hash/deep_merge.rb
|
6
|
+
def deep_merge(other_hash, &block)
|
7
|
+
dup.deep_merge!(other_hash, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Same as +deep_merge+, but modifies +self+.
|
11
|
+
def deep_merge!(other_hash, &block)
|
12
|
+
merge!(other_hash) do |key, this_val, other_val|
|
13
|
+
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
14
|
+
this_val.deep_merge(other_val, &block)
|
15
|
+
elsif block
|
16
|
+
block.call(key, this_val, other_val)
|
17
|
+
else
|
18
|
+
other_val
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def deep_stringify_keys
|
24
|
+
deep_transform_keys(&:to_s)
|
25
|
+
end
|
26
|
+
|
5
27
|
# activesupport-4.1.1/lib/active_support/core_ext/hash/keys.rb
|
6
28
|
def deep_symbolize_keys
|
7
29
|
deep_transform_keys do |key|
|
data/lib/fusuma/multi_logger.rb
CHANGED
@@ -32,6 +32,8 @@ module Fusuma
|
|
32
32
|
def debug(msg)
|
33
33
|
return unless debug_mode?
|
34
34
|
|
35
|
+
return if ignore_pattern?(msg)
|
36
|
+
|
35
37
|
super(msg)
|
36
38
|
end
|
37
39
|
|
@@ -47,6 +49,20 @@ module Fusuma
|
|
47
49
|
debug_mode
|
48
50
|
end
|
49
51
|
|
52
|
+
def ignore_pattern?(msg)
|
53
|
+
# TODO: configurable from config.yml
|
54
|
+
pattern = /timer_input/
|
55
|
+
case msg
|
56
|
+
when Hash
|
57
|
+
e = msg.values.find { |v| v.is_a? Fusuma::Plugin::Events::Event }
|
58
|
+
return unless e
|
59
|
+
|
60
|
+
e.tag.match?(pattern)
|
61
|
+
else
|
62
|
+
false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
50
66
|
class << self
|
51
67
|
def info(msg)
|
52
68
|
instance.info(msg)
|
data/lib/fusuma/plugin/base.rb
CHANGED
@@ -8,7 +8,6 @@ module Fusuma
|
|
8
8
|
module Plugin
|
9
9
|
# Create a Plugin Class with extending this class
|
10
10
|
class Base
|
11
|
-
include CustomProcess
|
12
11
|
# when inherited from subclass
|
13
12
|
def self.inherited(subclass)
|
14
13
|
super
|
@@ -22,20 +21,30 @@ module Fusuma
|
|
22
21
|
Manager.plugins[name]
|
23
22
|
end
|
24
23
|
|
24
|
+
# @abstract override `#shutdown` to implement
|
25
|
+
def shutdown
|
26
|
+
end
|
27
|
+
|
25
28
|
# config parameter name and Type of the value of parameter
|
26
29
|
# @return [Hash]
|
27
30
|
def config_param_types
|
28
31
|
raise NotImplementedError, "override #{self.class.name}##{__method__}"
|
29
32
|
end
|
30
33
|
|
34
|
+
# @param key [Symbol]
|
35
|
+
# @param base [Config::Index]
|
31
36
|
# @return [Object]
|
32
|
-
def config_params(key = nil
|
33
|
-
|
37
|
+
def config_params(key = nil)
|
38
|
+
@config_params ||= {}
|
39
|
+
if @config_params["#{config_index.cache_key},#{key}"]
|
40
|
+
return @config_params["#{config_index.cache_key},#{key}"]
|
41
|
+
end
|
42
|
+
|
43
|
+
params = Config.instance.fetch_config_params(key, config_index)
|
34
44
|
|
35
45
|
return params unless key
|
36
46
|
|
37
|
-
@config_params
|
38
|
-
@config_params["#{base.cache_key},#{key}"] ||=
|
47
|
+
@config_params["#{config_index.cache_key},#{key}"] =
|
39
48
|
params.fetch(key, nil).tap do |val|
|
40
49
|
next if val.nil?
|
41
50
|
|
@@ -45,14 +54,14 @@ module Fusuma
|
|
45
54
|
next if param_types.any? { |klass| val.is_a?(klass) }
|
46
55
|
|
47
56
|
MultiLogger.error("Please fix config.yml.")
|
48
|
-
MultiLogger.error(":#{
|
57
|
+
MultiLogger.error(":#{config_index.keys.map(&:symbol)
|
49
58
|
.join(" => :")} => :#{key} should be #{param_types.join(" OR ")}.")
|
50
59
|
exit 1
|
51
60
|
end
|
52
61
|
end
|
53
62
|
|
54
63
|
def config_index
|
55
|
-
Config::Index.new(self.class.name.gsub("Fusuma::", "").underscore.split("/"))
|
64
|
+
@config_index ||= Config::Index.new(self.class.name.gsub("Fusuma::", "").underscore.split("/"))
|
56
65
|
end
|
57
66
|
end
|
58
67
|
end
|
@@ -7,9 +7,24 @@ 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
|
+
def initialize(*args)
|
15
|
+
super(*args)
|
16
|
+
@cache = {}
|
17
|
+
@cache_select_by = {}
|
18
|
+
@cache_sum10 = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def clear
|
22
|
+
super.clear
|
23
|
+
@cache = {}
|
24
|
+
@cache_select_by = {}
|
25
|
+
@cache_sum10 = {}
|
26
|
+
end
|
27
|
+
|
13
28
|
def config_param_types
|
14
29
|
{
|
15
30
|
source: [String],
|
@@ -40,6 +55,9 @@ module Fusuma
|
|
40
55
|
MultiLogger.debug("#{self.class.name}##{__method__}")
|
41
56
|
|
42
57
|
@events.delete(e)
|
58
|
+
@cache = {}
|
59
|
+
@cache_select_by = {}
|
60
|
+
@cache_sum10 = {}
|
43
61
|
end
|
44
62
|
end
|
45
63
|
|
@@ -59,11 +77,35 @@ module Fusuma
|
|
59
77
|
def sum_attrs(attr)
|
60
78
|
updating_events.map do |gesture_event|
|
61
79
|
gesture_event.record.delta[attr].to_f
|
62
|
-
end.
|
80
|
+
end.reduce(:+)
|
81
|
+
end
|
82
|
+
|
83
|
+
# @param attr [Symbol]
|
84
|
+
# @return [Float]
|
85
|
+
def sum_last10_attrs(attr) # sums last 10 values of attr (or all if length < 10)
|
86
|
+
cache_entry = (@cache_sum10[attr] ||= CacheEntry.new(0, 0))
|
87
|
+
upd_ev = updating_events
|
88
|
+
if upd_ev.length > cache_entry.checked + 1
|
89
|
+
cache_entry.value = upd_ev.last(10).map do |gesture_event|
|
90
|
+
gesture_event.record.delta[attr].to_f
|
91
|
+
end.reduce(:+)
|
92
|
+
elsif upd_ev.length > cache_entry.checked
|
93
|
+
cache_entry.value = cache_entry.value + upd_ev[-1].record.delta[attr].to_f - \
|
94
|
+
((upd_ev.length > 10) ? upd_ev[-11].record.delta[attr].to_f : 0)
|
95
|
+
else
|
96
|
+
return cache_entry.value
|
97
|
+
end
|
98
|
+
cache_entry.checked = upd_ev.length
|
99
|
+
cache_entry.value
|
63
100
|
end
|
64
101
|
|
65
102
|
def updating_events
|
66
|
-
@
|
103
|
+
cache_entry = (@cache[:updating_events] ||= CacheEntry.new(0, []))
|
104
|
+
cache_entry.checked.upto(@events.length - 1).each do |i|
|
105
|
+
(cache_entry.value << @events[i]) if @events[i].record.status == "update"
|
106
|
+
end
|
107
|
+
cache_entry.checked = @events.length
|
108
|
+
cache_entry.value
|
67
109
|
end
|
68
110
|
|
69
111
|
# @param attr [Symbol]
|
@@ -96,14 +138,28 @@ module Fusuma
|
|
96
138
|
self.class.new events
|
97
139
|
end
|
98
140
|
|
141
|
+
def select_by_type(type)
|
142
|
+
cache_entry = (@cache_select_by[type] ||= CacheEntry.new(0, self.class.new([])))
|
143
|
+
cache_entry.checked.upto(@events.length - 1).each do |i|
|
144
|
+
(cache_entry.value.events << @events[i]) if @events[i].record.gesture == type
|
145
|
+
end
|
146
|
+
cache_entry.checked = @events.length
|
147
|
+
cache_entry.value
|
148
|
+
end
|
149
|
+
|
99
150
|
def select_from_last_begin
|
100
151
|
return self if empty?
|
152
|
+
cache_entry = (@cache[:last_begin] ||= CacheEntry.new(0, nil))
|
153
|
+
|
154
|
+
cache_entry.value = (@events.length - 1).downto(cache_entry.checked).find do |i|
|
155
|
+
@events[i].record.status == "begin"
|
156
|
+
end || cache_entry.value
|
157
|
+
cache_entry.checked = @events.length
|
101
158
|
|
102
|
-
|
103
|
-
return GestureBuffer.new([]) if
|
159
|
+
return self if cache_entry.value == 0
|
160
|
+
return GestureBuffer.new([]) if cache_entry.value.nil?
|
104
161
|
|
105
|
-
|
106
|
-
GestureBuffer.new(@events[index_last_begin..-1])
|
162
|
+
GestureBuffer.new(@events[cache_entry.value..-1])
|
107
163
|
end
|
108
164
|
end
|
109
165
|
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
|
@@ -13,6 +14,11 @@ module Fusuma
|
|
13
14
|
|
14
15
|
BASE_THERESHOLD = 0.7
|
15
16
|
|
17
|
+
def initialize(*args)
|
18
|
+
super(*args)
|
19
|
+
@timer = Inputs::TimerInput.instance
|
20
|
+
end
|
21
|
+
|
16
22
|
# @param buffers [Array<Buffers::Buffer>]
|
17
23
|
# @return [Events::Event] if event is detected
|
18
24
|
# @return [Array<Events::Event>] if hold end event is detected
|
@@ -21,16 +27,15 @@ module Fusuma
|
|
21
27
|
hold_buffer = find_hold_buffer(buffers)
|
22
28
|
return if hold_buffer.empty?
|
23
29
|
|
24
|
-
|
30
|
+
last_hold = hold_buffer.events.last
|
25
31
|
|
26
32
|
timer_buffer = buffers.find { |b| b.type == "timer" }
|
27
|
-
|
33
|
+
last_timer = timer_buffer.events.last
|
28
34
|
|
29
35
|
finger = hold_buffer.finger
|
30
|
-
holding_time = calc_holding_time(hold_events:
|
36
|
+
holding_time = calc_holding_time(hold_events: hold_buffer.events, last_timer: last_timer)
|
31
37
|
|
32
|
-
|
33
|
-
status = case hold_events.last.record.status
|
38
|
+
status = case last_hold.record.status
|
34
39
|
when "begin"
|
35
40
|
if holding_time.zero?
|
36
41
|
"begin"
|
@@ -42,16 +47,19 @@ module Fusuma
|
|
42
47
|
when "end"
|
43
48
|
"end"
|
44
49
|
else
|
45
|
-
last_record =
|
50
|
+
last_record = last_hold.record.status
|
46
51
|
raise "Unexpected Status:#{last_record.status} in #{last_record}"
|
47
52
|
end
|
48
53
|
|
49
54
|
repeat_index = create_repeat_index(finger: finger, status: status)
|
50
55
|
oneshot_index = create_oneshot_index(finger: finger)
|
51
56
|
|
52
|
-
|
53
|
-
|
54
|
-
|
57
|
+
if status == "begin"
|
58
|
+
@timeout = nil
|
59
|
+
if threshold(index: oneshot_index) < @timer.interval
|
60
|
+
@timer.wake_early(Time.now + threshold(index: oneshot_index))
|
61
|
+
end
|
62
|
+
elsif status == "timer"
|
55
63
|
return if @timeout
|
56
64
|
|
57
65
|
return unless enough?(index: oneshot_index, holding_time: holding_time)
|
@@ -97,12 +105,12 @@ module Fusuma
|
|
97
105
|
def find_hold_buffer(buffers)
|
98
106
|
buffers.find { |b| b.type == BUFFER_TYPE }
|
99
107
|
.select_from_last_begin
|
100
|
-
.
|
108
|
+
.select_by_type(GESTURE_RECORD_TYPE)
|
101
109
|
end
|
102
110
|
|
103
|
-
def calc_holding_time(hold_events:,
|
104
|
-
last_time = if
|
105
|
-
|
111
|
+
def calc_holding_time(hold_events:, last_timer:)
|
112
|
+
last_time = if last_timer && (hold_events.last.time < last_timer.time)
|
113
|
+
last_timer.time
|
106
114
|
else
|
107
115
|
hold_events.last.time
|
108
116
|
end
|
@@ -110,7 +118,13 @@ module Fusuma
|
|
110
118
|
end
|
111
119
|
|
112
120
|
def enough?(index:, holding_time:)
|
113
|
-
|
121
|
+
diff = threshold(index: index) - holding_time
|
122
|
+
if diff < 0
|
123
|
+
true
|
124
|
+
elsif diff < @timer.interval
|
125
|
+
@timer.wake_early(Time.now + diff)
|
126
|
+
false
|
127
|
+
end
|
114
128
|
end
|
115
129
|
|
116
130
|
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
|
)
|
@@ -175,7 +167,7 @@ module Fusuma
|
|
175
167
|
end
|
176
168
|
|
177
169
|
def calc
|
178
|
-
@x > @y ? @x.abs : @y.abs
|
170
|
+
(@x > @y) ? @x.abs : @y.abs
|
179
171
|
end
|
180
172
|
end
|
181
173
|
end
|
@@ -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
|