rufio 0.83.0 → 0.83.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b75328867a09d6dfa3b4c759e242d239ab8d087540a43af19471473cc0515c4c
4
- data.tar.gz: 798358451d71a8b74ee70ce2d362b2f24fb887e6de9b574f700c0f25a449e389
3
+ metadata.gz: c96ef480cab0968de6e595b56af26baeb59c0fd0542a85e2ccc0e4d1970bd696
4
+ data.tar.gz: 50366b86a8ef40df39f00a58e7a4e4d86d8314c919855acd96cdc0a03f39a156
5
5
  SHA512:
6
- metadata.gz: 8072bc03c642bbc3043caca4cfa4899c72b6622ab7a74517ef7964010a9257e938005191de9a8e8aaed444749108ef1ef983b6b4dc8483aa8b4d2a6a8cb075a6
7
- data.tar.gz: d6fb6e10e070e94120518d5a883bd241b46a957e7938b375b09e7dc3e28e73e9652aabe7b6a191e2575872764919581ac6d4b163d48fbb2d5dcd50e7740e2e2f
6
+ metadata.gz: dd1d2a5f82340c12caf57184b90cf3ad0773ef905caf07214376eab6b41d2af5c99fec088bd6e4dc51c20b928c3640d62c8b1d3681d08724fdb32e719e4205cd
7
+ data.tar.gz: d38b805a6592cae4b6cc1c8e08ea587c3f88ebdadd605561b1cef67a3700009f5d656df61548a2f755db659c89b995dfabdd38a29e14c8e728280d22f12fe337
data/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ All notable changes to rufio will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.83.1] - 2026-03-20
9
+
10
+ ### Changed
11
+ - **Windows console input detection rewritten using Win32 API**: Replaced the background thread + Queue workaround (introduced in v0.82.1 to handle ESC key detection on Windows) with `GetNumberOfConsoleInputEvents` via the Win32 API (`fiddle` stdlib)
12
+ - The previous approach had a race condition where the background `STDIN.read(1)` thread competed with `STDIN.getch` calls in dialogs, potentially dropping dialog input (including multi-byte/Japanese characters)
13
+ - Background thread, Queue, and `windows_read_next_byte` helper are removed
14
+ - `read_next_input_byte` is now a single unified implementation for both Windows and Unix (`read_nonblock`)
15
+ - Cygwin is excluded from the Windows path since it provides POSIX-compatible `IO.select`
16
+ - Falls back to `read_nonblock` if `Fiddle::DLError` occurs (no extra gem required — `fiddle` is a Ruby stdlib)
17
+
8
18
  ## [0.83.0] - 2026-03-14
9
19
 
10
20
  ### Added
@@ -189,23 +189,6 @@ module Rufio
189
189
  print "\e[?1003h\e[?1006h"
190
190
  STDOUT.flush
191
191
 
192
- # Windows: IO.select + read_nonblockはコンソールハンドルのESCキーを
193
- # 検出できない場合がある。バックグラウンドスレッドでSTDINを読み取り
194
- # Queueに格納することで信頼性のある入力検出を実現する。
195
- if windows?
196
- @windows_input_queue = Queue.new
197
- @windows_input_thread = Thread.new do
198
- loop do
199
- begin
200
- byte = STDIN.read(1)
201
- @windows_input_queue << byte if byte
202
- rescue
203
- break
204
- end
205
- end
206
- end
207
- end
208
-
209
192
  # re-acquire terminal size (just in case)
210
193
  update_screen_size
211
194
  end
@@ -217,31 +200,37 @@ module Rufio
217
200
  @screen_width, @screen_height = console.winsize.reverse
218
201
  end
219
202
 
203
+ # Cygwinは POSIX互換のIO.selectが使えるため除外
220
204
  def windows?
221
- RUBY_PLATFORM =~ /mswin|mingw|cygwin/ ? true : false
205
+ RUBY_PLATFORM =~ /mswin|mingw/ ? true : false
222
206
  end
223
207
 
224
- # Windows: エスケープシーケンスの後続バイトをQueueから短いタイムアウトで読み取る
225
- # VT対応ターミナルでの矢印キー(\e[A 等)の後続バイト読み取りに使用
226
- def windows_read_next_byte
227
- deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 0.005 # 5ms
228
- loop do
229
- begin
230
- return @windows_input_queue.pop(true)
231
- rescue ThreadError
232
- return nil if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline
233
- sleep 0.001
234
- end
235
- end
208
+ # Windows: GetNumberOfConsoleInputEvents でコンソール入力バッファを確認する。
209
+ # IO.select はWindowsコンソールハンドルでESCキーを取りこぼすため使用しない。
210
+ # fiddle はRuby標準ライブラリなので追加gemは不要。
211
+ def windows_console_input_available?
212
+ require 'fiddle'
213
+ @win32_kernel32 ||= Fiddle.dlopen('kernel32')
214
+ @win32_get_std_handle ||= Fiddle::Function.new(
215
+ @win32_kernel32['GetStdHandle'],
216
+ [Fiddle::TYPE_INT], Fiddle::TYPE_VOIDP
217
+ )
218
+ @win32_get_num_events ||= Fiddle::Function.new(
219
+ @win32_kernel32['GetNumberOfConsoleInputEvents'],
220
+ [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT
221
+ )
222
+ handle = @win32_get_std_handle.call(0xFFFFFFF6) # STD_INPUT_HANDLE = (DWORD)(-10)
223
+ count_ptr = Fiddle::Pointer.malloc(4)
224
+ @win32_get_num_events.call(handle, count_ptr)
225
+ count_ptr[0, 4].unpack1('L') > 0
226
+ rescue Fiddle::DLError
227
+ # fiddle が使えない場合は常に入力ありとみなし read_nonblock に任せる
228
+ true
236
229
  end
237
230
 
238
231
  # エスケープシーケンスの後続バイトを読み取る(Windows/Unix共通ヘルパー)
239
232
  def read_next_input_byte
240
- if @windows_input_queue
241
- windows_read_next_byte
242
- else
243
- STDIN.read_nonblock(1) rescue nil
244
- end
233
+ STDIN.read_nonblock(1) rescue nil
245
234
  end
246
235
 
247
236
  def cleanup_terminal
@@ -250,13 +239,6 @@ module Rufio
250
239
  STDIN.cooked!
251
240
  end
252
241
 
253
- # Windowsバックグラウンド入力スレッドを停止
254
- if @windows_input_thread
255
- @windows_input_thread.kill rescue nil
256
- @windows_input_thread = nil
257
- @windows_input_queue = nil
258
- end
259
-
260
242
  # マウスレポートを無効化
261
243
  print "\e[?1003l\e[?1006l"
262
244
  STDOUT.flush
@@ -442,31 +424,24 @@ module Rufio
442
424
  private
443
425
 
444
426
  # ノンブロッキング入力処理(ゲームループ用)
445
- # Windows: Queueベース、Unix: IO.select + read_nonblock
427
+ # Windows: GetNumberOfConsoleInputEvents で入力確認後 read_nonblock
428
+ # Unix: IO.select(timeout=0) で入力確認後 read_nonblock
446
429
  def handle_input_nonblocking
447
430
  # 入力バイトを1つ読み取る
448
- if @windows_input_queue
449
- # Windows: バックグラウンドスレッドのQueueからノンブロッキングで読み取る
450
- begin
451
- input = @windows_input_queue.pop(true)
452
- rescue ThreadError
453
- return false
454
- end
431
+ if windows?
432
+ # Windows: IO.selectはESCキーを取りこぼすため Win32 API で入力確認
433
+ return false unless windows_console_input_available?
455
434
  else
456
435
  # Unix: 0msタイムアウトで即座にチェック(30FPS = 33.33ms/frame)
457
- ready = IO.select([STDIN], nil, nil, 0)
458
- return false unless ready
459
-
460
- begin
461
- # read_nonblockを使ってノンブロッキングで1文字読み取る
462
- input = STDIN.read_nonblock(1)
463
- rescue IO::WaitReadable, IO::EAGAINWaitReadable
464
- # 入力が利用できない
465
- return false
466
- rescue Errno::ENOTTY, Errno::ENODEV
467
- # ターミナルでない環境
468
- return false
469
- end
436
+ return false unless IO.select([STDIN], nil, nil, 0)
437
+ end
438
+
439
+ begin
440
+ input = STDIN.read_nonblock(1)
441
+ rescue IO::WaitReadable, IO::EAGAINWaitReadable
442
+ return false
443
+ rescue Errno::ENOTTY, Errno::ENODEV
444
+ return false
470
445
  end
471
446
 
472
447
  # コマンドモードがアクティブな場合は、エスケープシーケンス処理をスキップ
data/lib/rufio/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rufio
4
- VERSION = '0.83.0'
4
+ VERSION = '0.83.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rufio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.83.0
4
+ version: 0.83.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - masisz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-14 00:00:00.000000000 Z
11
+ date: 2026-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: io-console