procon_bypass_man 0.1.9 → 0.1.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rubocop.yml +2 -0
  4. data/CHANGELOG.md +14 -0
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +13 -12
  7. data/README.md +14 -16
  8. data/bin/console +4 -0
  9. data/bin/{report_receive_server.rb → dev_api_server.rb} +8 -1
  10. data/lib/procon_bypass_man/background/has_server_pool.rb +54 -0
  11. data/lib/procon_bypass_man/background/http_client.rb +67 -0
  12. data/lib/procon_bypass_man/background/job_performer.rb +16 -0
  13. data/lib/procon_bypass_man/background/job_runnable.rb +16 -0
  14. data/lib/procon_bypass_man/background/job_runner.rb +45 -0
  15. data/lib/procon_bypass_man/background/jobs/base_job.rb +12 -0
  16. data/lib/procon_bypass_man/background/jobs/report_boot_job.rb +10 -0
  17. data/lib/procon_bypass_man/background/jobs/report_error_job.rb +10 -0
  18. data/lib/procon_bypass_man/background/jobs/report_heartbeat_job.rb +10 -0
  19. data/lib/procon_bypass_man/background/jobs/report_load_config_job.rb +10 -0
  20. data/lib/procon_bypass_man/background/jobs/report_pressed_buttons_job.rb +18 -0
  21. data/lib/procon_bypass_man/background/jobs/report_reload_config_job.rb +10 -0
  22. data/lib/procon_bypass_man/background.rb +12 -0
  23. data/lib/procon_bypass_man/boot_message.rb +13 -9
  24. data/lib/procon_bypass_man/{configuration → buttons_setting_configuration}/layer.rb +51 -30
  25. data/lib/procon_bypass_man/{configuration → buttons_setting_configuration}/loader.rb +12 -11
  26. data/lib/procon_bypass_man/{configuration → buttons_setting_configuration}/validator.rb +1 -1
  27. data/lib/procon_bypass_man/buttons_setting_configuration.rb +101 -0
  28. data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +42 -0
  29. data/lib/procon_bypass_man/bypass.rb +57 -38
  30. data/lib/procon_bypass_man/commands/bypass_command.rb +86 -0
  31. data/lib/procon_bypass_man/commands/connect_device_command.rb +11 -0
  32. data/lib/procon_bypass_man/commands/print_boot_message_command.rb +9 -0
  33. data/lib/procon_bypass_man/commands/send_error_command.rb +19 -0
  34. data/lib/procon_bypass_man/commands/send_reload_config_event_command.rb +11 -0
  35. data/lib/procon_bypass_man/commands/write_device_id_command.rb +12 -0
  36. data/lib/procon_bypass_man/commands/write_session_id_command.rb +13 -0
  37. data/lib/procon_bypass_man/commands.rb +7 -0
  38. data/lib/procon_bypass_man/configuration.rb +92 -78
  39. data/lib/procon_bypass_man/device_connector.rb +31 -25
  40. data/lib/procon_bypass_man/io_monitor.rb +9 -4
  41. data/lib/procon_bypass_man/procon/analog_stick.rb +31 -0
  42. data/lib/procon_bypass_man/procon/analog_stick_cap.rb +9 -32
  43. data/lib/procon_bypass_man/procon/button_collection.rb +1 -0
  44. data/lib/procon_bypass_man/procon/{data.rb → consts.rb} +1 -1
  45. data/lib/procon_bypass_man/procon/layer_changer.rb +40 -0
  46. data/lib/procon_bypass_man/procon/macro_registry.rb +2 -2
  47. data/lib/procon_bypass_man/procon/mode_registry.rb +2 -2
  48. data/lib/procon_bypass_man/procon/user_operation.rb +15 -17
  49. data/lib/procon_bypass_man/procon.rb +15 -15
  50. data/lib/procon_bypass_man/procon_reader.rb +31 -0
  51. data/lib/procon_bypass_man/runner.rb +15 -113
  52. data/lib/procon_bypass_man/splatoon2/macro/fast_return.rb +15 -0
  53. data/lib/procon_bypass_man/splatoon2/macro/jump_to_left_key.rb +15 -0
  54. data/lib/procon_bypass_man/splatoon2/macro/jump_to_right_key.rb +15 -0
  55. data/lib/procon_bypass_man/splatoon2/macro/jump_to_up_key.rb +15 -0
  56. data/lib/procon_bypass_man/splatoon2/mode/guruguru.rb +57 -0
  57. data/lib/procon_bypass_man/splatoon2/version.rb +7 -0
  58. data/lib/procon_bypass_man/splatoon2.rb +11 -0
  59. data/lib/procon_bypass_man/support/callbacks.rb +70 -0
  60. data/lib/procon_bypass_man/support/compress_array.rb +56 -0
  61. data/lib/procon_bypass_man/{on_memory_cache.rb → support/on_memory_cache.rb} +0 -0
  62. data/lib/procon_bypass_man/{timer.rb → support/safe_timeout.rb} +1 -1
  63. data/lib/procon_bypass_man/support/signal_handler.rb +11 -0
  64. data/lib/procon_bypass_man/support/uptime.rb +25 -0
  65. data/lib/procon_bypass_man/version.rb +1 -1
  66. data/lib/procon_bypass_man.rb +41 -82
  67. data/procon_bypass_man.gemspec +2 -2
  68. data/project_template/README.md +19 -12
  69. data/project_template/app.rb +7 -8
  70. data/project_template/systemd_units/pbm_web.service +11 -0
  71. data/project_template/web.rb +16 -0
  72. data/sig/{README.rb → README.md} +0 -0
  73. data/sig/main.rbs +54 -16
  74. metadata +53 -22
  75. data/examples/practical/app.rb +0 -21
  76. data/examples/practical/setting.yml +0 -24
  77. data/lib/procon_bypass_man/analog_stick_position.rb +0 -14
  78. data/lib/procon_bypass_man/error_reporter.rb +0 -44
  79. data/lib/procon_bypass_man/procon/debug_dumper.rb +0 -17
  80. data/lib/procon_bypass_man/procon/layer_changeable.rb +0 -28
  81. data/lib/procon_bypass_man/procon/pressed_button_helper.rb +0 -15
  82. data/lib/procon_bypass_man/reporter.rb +0 -42
  83. data/lib/procon_bypass_man/uptime.rb +0 -13
@@ -1,100 +1,114 @@
1
- require "procon_bypass_man/configuration/validator"
2
- require "procon_bypass_man/configuration/loader"
3
- require "procon_bypass_man/configuration/layer"
4
-
5
- module ProconBypassMan
6
- class Configuration
7
- attr_accessor :layers,
8
- :setting_path,
9
- :mode_plugins,
10
- :macro_plugins,
11
- :context,
12
- :current_context_key,
13
- :neutral_position
14
-
15
- def self.instance
16
- @@current_context_key ||= :main
17
- @@context ||= {}
18
- @@context[@@current_context_key] ||= new
1
+ class ProconBypassMan::Configuration
2
+ module ClassMethods
3
+ def root
4
+ config.root
19
5
  end
20
6
 
21
- def self.switch_new_context(key)
22
- @@context[key] = new
23
- previous_key = @@current_context_key
24
- if block_given?
25
- @@current_context_key = key
26
- value = yield(@@context[key])
27
- @@current_context_key = previous_key
28
- return value
29
- else
30
- @@current_context_key = key
31
- end
7
+ def logger
8
+ config.logger
32
9
  end
33
10
 
34
- def initialize
35
- reset!
11
+ def error_logger
12
+ config.error_logger
36
13
  end
37
14
 
38
- module ManualMode
39
- def self.name
40
- 'manual'
41
- end
15
+ def pid_path
16
+ @@pid_path ||= File.expand_path("#{root}/pbm_pid", __dir__).freeze
42
17
  end
43
- MODES = [:manual]
44
- def layer(direction, mode: ManualMode, &block)
45
- mode_name = case mode
46
- when String
47
- mode.to_sym
48
- when Symbol
49
- mode
50
- else
51
- mode.name.to_sym
52
- end
53
- unless (MODES + ProconBypassMan::Procon::ModeRegistry.plugins.keys).include?(mode_name)
54
- raise("#{mode_name} mode is unknown")
55
- end
56
-
57
- layer = Layer.new(mode: mode_name)
58
- layer.instance_eval(&block) if block_given?
59
- self.layers[direction] = layer
60
- self
18
+
19
+ def digest_path
20
+ config.digest_path
61
21
  end
62
22
 
63
- def install_mode_plugin(klass)
64
- ProconBypassMan::Procon::ModeRegistry.install_plugin(klass)
65
- self
23
+ def cache
24
+ @@cache_table ||= ProconBypassMan::OnMemoryCache.new
66
25
  end
67
26
 
68
- def install_macro_plugin(klass)
69
- ProconBypassMan::Procon::MacroRegistry.install_plugin(klass)
70
- self
27
+ # @return [String]
28
+ def session_id
29
+ ProconBypassMan::WriteSessionIdCommand.execute
71
30
  end
72
31
 
73
- def prefix_keys_for_changing_layer(buttons)
74
- @prefix_keys_for_changing_layer = buttons
75
- self
32
+ # @return [String]
33
+ def device_id
34
+ ProconBypassMan::WriteDeviceIdCommand.execute
76
35
  end
36
+ end
77
37
 
78
- def set_neutral_position(x, y)
79
- self.neutral_position = AnalogStickPosition.new(x: x, y: y)
80
- self
38
+ attr_accessor :enable_critical_error_logging
39
+ attr_writer :verbose_bypass_log, :raw_setting
40
+
41
+ def root=(path)
42
+ @root = path
43
+ return self
44
+ end
45
+
46
+ def root
47
+ if defined?(@root)
48
+ @root
49
+ else
50
+ File.expand_path('..', __dir__ || ".").freeze
81
51
  end
52
+ end
82
53
 
83
- def prefix_keys
84
- @prefix_keys_for_changing_layer
54
+ def api_servers=(api_servers)
55
+ @api_servers = api_servers
56
+ return self
57
+ end
58
+
59
+ def logger=(logger)
60
+ @logger = logger
61
+ return self
62
+ end
63
+
64
+ def logger
65
+ if ENV["PBM_ENV"] == 'test'
66
+ return Logger.new($stdout)
85
67
  end
86
68
 
87
- def reset!
88
- @prefix_keys_for_changing_layer = []
89
- self.mode_plugins = {}
90
- self.macro_plugins = {}
91
- self.layers = {
92
- up: Layer.new,
93
- down: Layer.new,
94
- left: Layer.new,
95
- right: Layer.new,
96
- }
97
- @neutral_position = AnalogStickPosition.new(x: 2124, y: 1808)
69
+ if defined?(@logger) && @logger.is_a?(Logger)
70
+ @logger
71
+ else
72
+ Logger.new(File.open("/dev/null"))
73
+ end
74
+ end
75
+
76
+ def error_logger
77
+ if enable_critical_error_logging
78
+ @error_logger ||= Logger.new("#{ProconBypassMan.root}/error.log", 5, 1024 * 1024 * 10)
79
+ else
80
+ Logger.new(File.open("/dev/null"))
98
81
  end
99
82
  end
83
+
84
+ def digest_path
85
+ "#{root}/.setting_yaml_digest"
86
+ end
87
+
88
+ # @return [String] pbm-webの接続先
89
+ def internal_api_servers
90
+ if !!ENV["INTERNAL_API_SERVER"]
91
+ [ENV["INTERNAL_API_SERVER"]]
92
+ else
93
+ [ 'http://localhost:9090',
94
+ 'http://localhost:8080',
95
+ ].compact
96
+ end
97
+ end
98
+
99
+ def api_servers
100
+ if !!ENV["API_SERVER"]
101
+ [ENV["API_SERVER"]].reject(&:nil?)
102
+ else
103
+ [@api_servers].flatten.reject(&:nil?)
104
+ end
105
+ end
106
+
107
+ def verbose_bypass_log
108
+ @verbose_bypass_log || !!ENV["VERBOSE_BYPASS_LOG"]
109
+ end
110
+
111
+ def raw_setting
112
+ @raw_setting ||= {}
113
+ end
100
114
  end
@@ -48,6 +48,7 @@ class ProconBypassMan::DeviceConnector
48
48
  end
49
49
 
50
50
  def drain_all
51
+ debug_log_buffer = []
51
52
  unless @initialized_devices
52
53
  init_devices
53
54
  end
@@ -55,11 +56,13 @@ class ProconBypassMan::DeviceConnector
55
56
  while(item = @stack.shift)
56
57
  item.values.each do |value|
57
58
  data = nil
58
- timer = ProconBypassMan::Timer.new
59
+ timer = ProconBypassMan::SafeTimeout.new
59
60
  begin
60
61
  timer.throw_if_timeout!
61
62
  data = from_device(item).read_nonblock(64)
63
+ debug_log_buffer << "read_from(#{item.read_from}): #{data}"
62
64
  rescue IO::EAGAINWaitReadable
65
+ debug_log_buffer << "read_from(#{item.read_from}): IO::EAGAINWaitReadable"
63
66
  retry
64
67
  end
65
68
 
@@ -74,15 +77,19 @@ class ProconBypassMan::DeviceConnector
74
77
  end
75
78
  if result
76
79
  ProconBypassMan.logger.info "OK(expected: #{value}, got: #{data.unpack("H*")})"
80
+ debug_log_buffer << "OK(expected: #{value}, got: #{data.unpack("H*")})"
77
81
  else
78
82
  ProconBypassMan.logger.info "NG(expected: #{value}, got: #{data.unpack("H*")})"
83
+ debug_log_buffer << "NG(expected: #{value}, got: #{data.unpack("H*")})"
79
84
  raise BytesMismatchError if @throw_error_if_mismatch
80
85
  end
81
86
  to_device(item).write_nonblock(data)
82
87
  end
83
88
  end
84
- rescue ProconBypassMan::Timer::Timeout
89
+ rescue ProconBypassMan::SafeTimeout::Timeout
85
90
  ProconBypassMan.logger.error "timeoutになりました"
91
+ copressed_buffer_text = ProconBypassMan::CompressArray.new(debug_log_buffer).compress.join("\n")
92
+ ProconBypassMan::SendErrorCommand.execute(error: copressed_buffer_text)
86
93
  raise if @throw_error_if_timeout
87
94
  end
88
95
 
@@ -95,31 +102,31 @@ class ProconBypassMan::DeviceConnector
95
102
  init_devices
96
103
  end
97
104
 
98
- timer = ProconBypassMan::Timer.new
105
+ timer = ProconBypassMan::SafeTimeout.new
99
106
  data = nil
100
107
  begin
101
108
  timer.throw_if_timeout!
102
109
  switch.write_nonblock(data)
103
110
  rescue IO::EAGAINWaitReadable
104
111
  retry
105
- rescue ProconBypassMan::Timer::Timeout
112
+ rescue ProconBypassMan::SafeTimeout::Timeout
106
113
  ProconBypassMan.logger.error "writeでtimeoutになりました"
107
114
  raise
108
115
  end
109
116
  return(data.unpack("H*")) if only_write
110
117
 
111
- timer = ProconBypassMan::Timer.new
118
+ timer = ProconBypassMan::SafeTimeout.new
112
119
  begin
113
120
  timer.throw_if_timeout!
114
121
  data = switch.read_nonblock(64)
115
122
  ProconBypassMan.logger.debug { " >>> #{data.unpack("H*")})" }
116
123
  rescue IO::EAGAINWaitReadable
117
124
  retry
118
- rescue ProconBypassMan::Timer::Timeout
125
+ rescue ProconBypassMan::SafeTimeout::Timeout
119
126
  ProconBypassMan.logger.error "readでtimeoutになりました"
120
127
  raise
121
128
  end
122
- rescue ProconBypassMan::Timer::Timeout
129
+ rescue ProconBypassMan::SafeTimeout::Timeout
123
130
  raise if @throw_error_if_timeout
124
131
  end
125
132
 
@@ -131,30 +138,30 @@ class ProconBypassMan::DeviceConnector
131
138
  init_devices
132
139
  end
133
140
 
134
- timer = ProconBypassMan::Timer.new
141
+ timer = ProconBypassMan::SafeTimeout.new
135
142
  begin
136
143
  timer.throw_if_timeout!
137
144
  procon.write_nonblock(data)
138
145
  rescue IO::EAGAINWaitReadable
139
146
  retry
140
- rescue ProconBypassMan::Timer::Timeout
147
+ rescue ProconBypassMan::SafeTimeout::Timeout
141
148
  ProconBypassMan.logger.error "writeでtimeoutになりました"
142
149
  raise
143
150
  end
144
151
  return(data.unpack("H*")) if only_write
145
152
 
146
- timer = ProconBypassMan::Timer.new
153
+ timer = ProconBypassMan::SafeTimeout.new
147
154
  begin
148
155
  timer.throw_if_timeout!
149
156
  data = procon.read_nonblock(64)
150
157
  ProconBypassMan.logger.error " <<< #{data.unpack("H*")})"
151
158
  rescue IO::EAGAINWaitReadable
152
159
  retry
153
- rescue ProconBypassMan::Timer::Timeout
160
+ rescue ProconBypassMan::SafeTimeout::Timeout
154
161
  ProconBypassMan.logger.error "readでtimeoutになりました"
155
162
  raise
156
163
  end
157
- rescue ProconBypassMan::Timer::Timeout
164
+ rescue ProconBypassMan::SafeTimeout::Timeout
158
165
  raise if @throw_error_if_timeout
159
166
  end
160
167
 
@@ -164,30 +171,30 @@ class ProconBypassMan::DeviceConnector
164
171
  end
165
172
 
166
173
  data = nil
167
- timer = ProconBypassMan::Timer.new
174
+ timer = ProconBypassMan::SafeTimeout.new
168
175
  begin
169
176
  timer.throw_if_timeout!
170
177
  data = procon.read_nonblock(64)
171
178
  ProconBypassMan.logger.debug { " <<< #{data.unpack("H*")})" }
172
179
  rescue IO::EAGAINWaitReadable
173
180
  retry
174
- rescue ProconBypassMan::Timer::Timeout
181
+ rescue ProconBypassMan::SafeTimeout::Timeout
175
182
  ProconBypassMan.logger.error "readでtimeoutになりました"
176
183
  raise
177
184
  end
178
185
  return(data.unpack("H*")) if only_read
179
186
 
180
- timer = ProconBypassMan::Timer.new
187
+ timer = ProconBypassMan::SafeTimeout.new
181
188
  begin
182
189
  timer.throw_if_timeout!
183
190
  switch.write_nonblock(data)
184
191
  rescue IO::EAGAINWaitReadable
185
192
  retry
186
- rescue ProconBypassMan::Timer::Timeout
193
+ rescue ProconBypassMan::SafeTimeout::Timeout
187
194
  ProconBypassMan.logger.error "writeでtimeoutになりました"
188
195
  raise
189
196
  end
190
- rescue ProconBypassMan::Timer::Timeout
197
+ rescue ProconBypassMan::SafeTimeout::Timeout
191
198
  raise if @throw_error_if_timeout
192
199
  end
193
200
 
@@ -197,30 +204,30 @@ class ProconBypassMan::DeviceConnector
197
204
  end
198
205
 
199
206
  data = nil
200
- timer = ProconBypassMan::Timer.new
207
+ timer = ProconBypassMan::SafeTimeout.new
201
208
  begin
202
209
  timer.throw_if_timeout!
203
210
  data = switch.read_nonblock(64)
204
211
  ProconBypassMan.logger.debug { " >>> #{data.unpack("H*")})" }
205
212
  rescue IO::EAGAINWaitReadable
206
213
  retry
207
- rescue ProconBypassMan::Timer::Timeout
214
+ rescue ProconBypassMan::SafeTimeout::Timeout
208
215
  ProconBypassMan.logger.error "readでtimeoutになりました"
209
216
  raise
210
217
  end
211
218
  return(data.unpack("H*")) if only_read
212
219
 
213
- timer = ProconBypassMan::Timer.new
220
+ timer = ProconBypassMan::SafeTimeout.new
214
221
  begin
215
222
  timer.throw_if_timeout!
216
223
  procon.write_nonblock(data)
217
224
  rescue IO::EAGAINWaitReadable
218
225
  retry
219
- rescue ProconBypassMan::Timer::Timeout
226
+ rescue ProconBypassMan::SafeTimeout::Timeout
220
227
  ProconBypassMan.logger.error "writeでtimeoutになりました"
221
228
  raise
222
229
  end
223
- rescue ProconBypassMan::Timer::Timeout
230
+ rescue ProconBypassMan::SafeTimeout::Timeout
224
231
  raise if @throw_error_if_timeout
225
232
  end
226
233
 
@@ -309,11 +316,10 @@ class ProconBypassMan::DeviceConnector
309
316
  end
310
317
  rescue Errno::ENXIO => e
311
318
  # /dev/hidg0 をopenできないときがある
312
- ProconBypassMan.logger.error "Errno::ENXIO (No such device or address @ rb_sysopen - /dev/hidg0)が起きました。resetします"
313
- ProconBypassMan.logger.error e
319
+ ProconBypassMan::SendErrorCommand.execute(error: "Errno::ENXIO (No such device or address @ rb_sysopen - /dev/hidg0)が起きました。resetします. #{e.full_message}")
314
320
  system('echo > /sys/kernel/config/usb_gadget/procon/UDC')
315
321
  system('ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC')
316
- sleep 2
322
+ sleep 0.5
317
323
  retry
318
324
  end
319
325
  end
@@ -1,11 +1,12 @@
1
1
  module ProconBypassMan
2
2
  class Counter
3
- attr_accessor :label, :table, :previous_table
3
+ attr_accessor :label, :table, :previous_table, :active
4
4
 
5
5
  def initialize(label: )
6
6
  self.label = label
7
7
  self.table = {}
8
8
  self.previous_table = {}
9
+ self.active = true
9
10
  end
10
11
 
11
12
  # アクティブなバケットは1つだけ
@@ -24,7 +25,7 @@ module ProconBypassMan
24
25
  self
25
26
  end
26
27
 
27
- def formated_previous_table
28
+ def formatted_previous_table
28
29
  t = previous_table.dup
29
30
  start_function = t[:start_function] || 0
30
31
  end_function = t[:end_function] || 0
@@ -32,6 +33,10 @@ module ProconBypassMan
32
33
  eagain_wait_readable_on_write = t[:eagain_wait_readable_on_write] || 0
33
34
  "(#{(end_function / start_function.to_f * 100).floor(1)}%(#{end_function}/#{start_function}), loss: #{eagain_wait_readable_on_read}, #{eagain_wait_readable_on_write})"
34
35
  end
36
+
37
+ def shutdown
38
+ self.active = false
39
+ end
35
40
  end
36
41
 
37
42
  module IOMonitor
@@ -51,14 +56,14 @@ module ProconBypassMan
51
56
  Thread.start do
52
57
  max_output_length = 0
53
58
  loop do
54
- list = @@list.dup
59
+ list = @@list.select(&:active).dup
55
60
  unless list.all? { |x| x&.previous_table.is_a?(Hash) }
56
61
  sleep 0.5
57
62
  next
58
63
  end
59
64
 
60
65
  line = list.map { |counter|
61
- "#{counter.label}(#{counter.formated_previous_table})"
66
+ "#{counter.label}(#{counter.formatted_previous_table})"
62
67
  }.join(", ")
63
68
  max_output_length = line.length
64
69
  sleep 0.7
@@ -0,0 +1,31 @@
1
+ class ProconBypassMan::Procon::AnalogStick
2
+ attr_accessor :neutral_position
3
+ attr_accessor :bin_x, :bin_y
4
+
5
+ def initialize(binary: )
6
+ @neutral_position = ProconBypassMan::ButtonsSettingConfiguration.instance.neutral_position
7
+
8
+ byte6 = binary[6].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
9
+ byte7 = binary[7].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
10
+ byte8 = binary[8].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
11
+
12
+ self.bin_x = "#{byte7[4..7]}#{byte6}"
13
+ self.bin_y = "#{byte8}#{byte7[0..3]}"
14
+ end
15
+
16
+ def abs_x
17
+ bin_x.to_i(2)
18
+ end
19
+
20
+ def abs_y
21
+ bin_y.to_i(2)
22
+ end
23
+
24
+ def relative_x
25
+ bin_x.to_i(2) - neutral_position.x
26
+ end
27
+
28
+ def relative_y
29
+ bin_y.to_i(2) - neutral_position.y
30
+ end
31
+ end
@@ -18,19 +18,9 @@ class ProconBypassMan::Procon::AnalogStickCap
18
18
  end
19
19
  end
20
20
 
21
- attr_accessor :bin_x, :bin_y
22
- attr_accessor :neutral_position
23
-
24
21
  def initialize(binary)
25
- @neutral_position = ProconBypassMan::Configuration.instance.neutral_position
26
22
  @binary = binary
27
-
28
- byte6 = binary[6].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
29
- byte7 = binary[7].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
30
- byte8 = binary[8].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
31
-
32
- self.bin_x = "#{byte7[4..7]}#{byte6}"
33
- self.bin_y = "#{byte8}#{byte7[0..3]}"
23
+ @analog_stick = ProconBypassMan::Procon::AnalogStick.new(binary: binary)
34
24
  end
35
25
 
36
26
  # @return [ProconBypassMan::Procon::AnalogStickCap::Position]
@@ -41,8 +31,8 @@ class ProconBypassMan::Procon::AnalogStickCap
41
31
  relative_capped_x = -(relative_capped_x.abs) if relative_x.negative?
42
32
  relative_capped_y = -(relative_capped_y.abs) if relative_y.negative?
43
33
  return Position.new(
44
- x: relative_capped_x + neutral_position.x,
45
- y: relative_capped_y + neutral_position.y,
34
+ x: relative_capped_x + @analog_stick.neutral_position.x,
35
+ y: relative_capped_y + @analog_stick.neutral_position.y,
46
36
  )
47
37
  else
48
38
  return position
@@ -54,23 +44,10 @@ class ProconBypassMan::Procon::AnalogStickCap
54
44
  Position.new(x: abs_x, y: abs_y)
55
45
  end
56
46
 
57
- # 0, 0からのx
58
- def abs_x
59
- bin_x.to_i(2)
60
- end
61
-
62
- # 0, 0からのy
63
- def abs_y
64
- bin_y.to_i(2)
65
- end
66
-
67
- def relative_x
68
- bin_x.to_i(2) - neutral_position.x
69
- end
70
-
71
- def relative_y
72
- bin_y.to_i(2) - neutral_position.y
73
- end
47
+ def abs_x; @analog_stick.abs_x; end # 0, 0からのx
48
+ def abs_y; @analog_stick.abs_y; end # 0, 0からのy
49
+ def relative_x; @analog_stick.relative_x; end
50
+ def relative_y; @analog_stick.relative_y; end
74
51
 
75
52
  # @deprecated
76
53
  def x; relative_x; end
@@ -78,11 +55,11 @@ class ProconBypassMan::Procon::AnalogStickCap
78
55
 
79
56
  def rad
80
57
  (
81
- Math.atan(y / x.to_f) * 180 / Math::PI
58
+ Math.atan(relative_y / relative_x.to_f) * 180 / Math::PI
82
59
  ).floor(6)
83
60
  end
84
61
 
85
62
  def hypotenuse
86
- Math.sqrt(x**2 + y**2).floor(6)
63
+ Math.sqrt((relative_x**2) + (relative_y**2)).floor(6)
87
64
  end
88
65
  end
@@ -37,6 +37,7 @@ class ProconBypassMan::Procon::ButtonCollection
37
37
  BUTTONS_MAP = BYTES_MAP.reduce({}) { |acc, value|
38
38
  next acc if value[1].nil?
39
39
  value[1].reverse.each.with_index do |button, index|
40
+ next(acc) if button == :grip || button == :_undefined_key
40
41
  acc[button] = { byte_position: value[0], bit_position: index }
41
42
  end
42
43
  acc
@@ -1,5 +1,5 @@
1
1
  class ProconBypassMan::Procon
2
- module Data
2
+ module Consts
3
3
  NO_ACTION = "30f28100800078c77448287509550274ff131029001b0022005a0271ff191028001e00210064027cff1410280020002100000000000000000000000000000000".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,40 @@
1
+ class ProconBypassMan::Procon::LayerChanger
2
+ def initialize(binary: )
3
+ @procon_reader = ProconBypassMan::ProconReader.new(binary: binary).freeze
4
+ end
5
+
6
+ # @return [Symbol]
7
+ def next_layer_key
8
+ case
9
+ when pressed?(button: :up)
10
+ :up
11
+ when pressed?(button: :right)
12
+ :right
13
+ when pressed?(button: :left)
14
+ :left
15
+ when pressed?(button: :down)
16
+ :down
17
+ else
18
+ ProconBypassMan.logger.warn("next_layer_key is unknown")
19
+ :up
20
+ end
21
+ end
22
+
23
+ # @return [Boolean]
24
+ def change_layer?
25
+ if ProconBypassMan::ButtonsSettingConfiguration.instance.prefix_keys.empty?
26
+ raise "prefix_keysが未設定です"
27
+ end
28
+ ProconBypassMan::ButtonsSettingConfiguration.instance.prefix_keys.map { |b| pressed?(button: b) }.all?
29
+ end
30
+
31
+ # @return [Boolean]
32
+ def pressed_next_layer?
33
+ change_layer? && (pressed?(button: :up) || pressed?(button: :right) || pressed?(button: :left) || pressed?(button: :down))
34
+ end
35
+
36
+ # @return [Boolean]
37
+ def pressed?(button: )
38
+ @procon_reader.pressed.include?(button)
39
+ end
40
+ end
@@ -37,11 +37,11 @@ class ProconBypassMan::Procon::MacroRegistry
37
37
  end
38
38
 
39
39
  def self.reset!
40
- ProconBypassMan::Configuration.instance.macro_plugins = {}
40
+ ProconBypassMan::ButtonsSettingConfiguration.instance.macro_plugins = {}
41
41
  end
42
42
 
43
43
  def self.plugins
44
- ProconBypassMan::Configuration.instance.macro_plugins
44
+ ProconBypassMan::ButtonsSettingConfiguration.instance.macro_plugins
45
45
  end
46
46
 
47
47
  reset!
@@ -35,11 +35,11 @@ class ProconBypassMan::Procon::ModeRegistry
35
35
  end
36
36
 
37
37
  def self.reset!
38
- ProconBypassMan::Configuration.instance.mode_plugins = {}
38
+ ProconBypassMan::ButtonsSettingConfiguration.instance.mode_plugins = {}
39
39
  end
40
40
 
41
41
  def self.plugins
42
- ProconBypassMan::Configuration.instance.mode_plugins
42
+ ProconBypassMan::ButtonsSettingConfiguration.instance.mode_plugins
43
43
  end
44
44
 
45
45
  reset!