rb_sdl2 0.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 +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +17 -0
- data/README.md +40 -0
- data/lib/rb_sdl2/audio/audio_allowed_changes.rb +17 -0
- data/lib/rb_sdl2/audio/audio_buffer.rb +49 -0
- data/lib/rb_sdl2/audio/audio_device.rb +44 -0
- data/lib/rb_sdl2/audio/audio_format.rb +23 -0
- data/lib/rb_sdl2/audio/audio_spec.rb +29 -0
- data/lib/rb_sdl2/audio.rb +132 -0
- data/lib/rb_sdl2/clipboard.rb +44 -0
- data/lib/rb_sdl2/cpu_info.rb +39 -0
- data/lib/rb_sdl2/cursor/color_cursor.rb +19 -0
- data/lib/rb_sdl2/cursor/cursor_class.rb +24 -0
- data/lib/rb_sdl2/cursor/cursor_pointer.rb +12 -0
- data/lib/rb_sdl2/cursor/default_cursor.rb +18 -0
- data/lib/rb_sdl2/cursor/system_cursor.rb +45 -0
- data/lib/rb_sdl2/cursor.rb +39 -0
- data/lib/rb_sdl2/display.rb +103 -0
- data/lib/rb_sdl2/display_mode.rb +35 -0
- data/lib/rb_sdl2/error.rb +9 -0
- data/lib/rb_sdl2/event/event_filter.rb +83 -0
- data/lib/rb_sdl2/event/event_queue.rb +137 -0
- data/lib/rb_sdl2/event/event_type.rb +271 -0
- data/lib/rb_sdl2/event.rb +161 -0
- data/lib/rb_sdl2/filesystem.rb +40 -0
- data/lib/rb_sdl2/hint.rb +24 -0
- data/lib/rb_sdl2/keyboard/key_mod.rb +37 -0
- data/lib/rb_sdl2/keyboard/keyboard_state.rb +34 -0
- data/lib/rb_sdl2/keyboard.rb +50 -0
- data/lib/rb_sdl2/message_box.rb +121 -0
- data/lib/rb_sdl2/mouse/global_mouse.rb +18 -0
- data/lib/rb_sdl2/mouse/mouse_button.rb +24 -0
- data/lib/rb_sdl2/mouse/mouse_class.rb +33 -0
- data/lib/rb_sdl2/mouse/mouse_wheel.rb +53 -0
- data/lib/rb_sdl2/mouse/relative_mouse.rb +12 -0
- data/lib/rb_sdl2/mouse/window_mouse.rb +17 -0
- data/lib/rb_sdl2/mouse.rb +74 -0
- data/lib/rb_sdl2/palette.rb +70 -0
- data/lib/rb_sdl2/pixel_format_enum.rb +73 -0
- data/lib/rb_sdl2/platform.rb +7 -0
- data/lib/rb_sdl2/power_info.rb +36 -0
- data/lib/rb_sdl2/rect.rb +14 -0
- data/lib/rb_sdl2/ref_count_pointer.rb +20 -0
- data/lib/rb_sdl2/rw_ops/rw_operator.rb +102 -0
- data/lib/rb_sdl2/rw_ops.rb +124 -0
- data/lib/rb_sdl2/screen_saver.rb +11 -0
- data/lib/rb_sdl2/sdl.rb +32 -0
- data/lib/rb_sdl2/surface/blend_mode.rb +41 -0
- data/lib/rb_sdl2/surface/pixel_format.rb +89 -0
- data/lib/rb_sdl2/surface.rb +244 -0
- data/lib/rb_sdl2/text_input.rb +15 -0
- data/lib/rb_sdl2/timer.rb +22 -0
- data/lib/rb_sdl2/version.rb +13 -0
- data/lib/rb_sdl2/video.rb +25 -0
- data/lib/rb_sdl2/window/dialog.rb +19 -0
- data/lib/rb_sdl2/window/display.rb +85 -0
- data/lib/rb_sdl2/window/grab.rb +23 -0
- data/lib/rb_sdl2/window/hit_test.rb +52 -0
- data/lib/rb_sdl2/window/position.rb +38 -0
- data/lib/rb_sdl2/window/shape.rb +76 -0
- data/lib/rb_sdl2/window/size.rb +59 -0
- data/lib/rb_sdl2/window/window_flags.rb +78 -0
- data/lib/rb_sdl2/window.rb +242 -0
- data/lib/rb_sdl2.rb +53 -0
- data/rb_sdl2.gemspec +19 -0
- metadata +135 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class Display
|
3
|
+
class << self
|
4
|
+
def displays
|
5
|
+
count = ::SDL2.SDL_GetNumVideoDisplays
|
6
|
+
raise RbSDL2Error if count < 0
|
7
|
+
count.times.map { |num| Display.new(num) }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(num)
|
12
|
+
@num = num
|
13
|
+
end
|
14
|
+
|
15
|
+
def bounds
|
16
|
+
rect = Rect.new
|
17
|
+
err = ::SDL2.SDL_GetDisplayBounds(index, rect)
|
18
|
+
raise RbSDL2Error if err < 0
|
19
|
+
rect.to_a
|
20
|
+
end
|
21
|
+
|
22
|
+
require_relative 'display_mode'
|
23
|
+
|
24
|
+
def closest_display_mode(**display_mode)
|
25
|
+
mode ||= DisplayMode.new(**display_mode)
|
26
|
+
closest = DisplayMode.new
|
27
|
+
err = ::SDL2.SDL_GetClosestDisplayMode(self, mode, closest)
|
28
|
+
raise RbSDL2Error if err.null?
|
29
|
+
closest
|
30
|
+
# 利用可能なディスプレイモードが検索され, 要求と最も近いモードがclosestに代入される.
|
31
|
+
# modeのformatとrefresh_rateが0の場合, デスクトップのモードとなる.
|
32
|
+
# モードは, サイズを最優先で検索し, ピクセル形式は次の優先度となる.
|
33
|
+
# そして最後に更新周期をチェックする. 利用可能なモードが要求に対して小さすぎる場合, NULLを戻す.
|
34
|
+
end
|
35
|
+
|
36
|
+
def current_display_mode
|
37
|
+
obj = DisplayMode.new
|
38
|
+
err = ::SDL2.SDL_GetCurrentDisplayMode(index, obj)
|
39
|
+
raise RbSDL2Error if err < 0
|
40
|
+
obj
|
41
|
+
end
|
42
|
+
|
43
|
+
def desktop_display_mode
|
44
|
+
obj = DisplayMode.new
|
45
|
+
err = ::SDL2.SDL_GetDesktopDisplayMode(index, obj)
|
46
|
+
raise RbSDL2Error if err < 0
|
47
|
+
obj
|
48
|
+
end
|
49
|
+
|
50
|
+
def display_modes
|
51
|
+
num = ::SDL2.SDL_GetNumDisplayModes(index)
|
52
|
+
raise RbSDL2Error if num < 0
|
53
|
+
num.times.map do |mode_index|
|
54
|
+
obj = DisplayMode.new
|
55
|
+
err = ::SDL2.SDL_GetDisplayMode(index, mode_index, obj)
|
56
|
+
raise RbSDL2Error if err < 0
|
57
|
+
obj
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# ディスプレイピクセルの斜め、水平、垂直方向の DPI を配列で戻す。
|
62
|
+
def dpi
|
63
|
+
d_h_v_dpi = Array.new(3) { ::FFI::MemoryPointer.new(:float) }
|
64
|
+
err = ::SDL2.SDL_GetDisplayDPI(index, *d_h_v_dpi)
|
65
|
+
raise RbSDL2Error if err < 0
|
66
|
+
d_h_v_dpi.map { |v| v.read_float }
|
67
|
+
end
|
68
|
+
|
69
|
+
def index = @num
|
70
|
+
alias to_int index
|
71
|
+
|
72
|
+
def inspect
|
73
|
+
"#<#{self.class.name} name=#{name.inspect} bounds=#{bounds} dpi=#{dpi}>"
|
74
|
+
end
|
75
|
+
|
76
|
+
def name
|
77
|
+
ptr = ::SDL2.SDL_GetDisplayName(index)
|
78
|
+
raise RbSDL2Error if ptr.null?
|
79
|
+
ptr.read_string.force_encoding(Encoding::UTF_8)
|
80
|
+
end
|
81
|
+
alias to_s name
|
82
|
+
|
83
|
+
def orientation = ::SDL2.SDL_GetDisplayOrientation(index)
|
84
|
+
|
85
|
+
module DisplayOrientation
|
86
|
+
def flipped_landscape? = ::SDL2::SDL_ORIENTATION_LANDSCAPE_FLIPPED == orientation
|
87
|
+
|
88
|
+
def flipped_portrait? = ::SDL2::SDL_ORIENTATION_PORTRAIT_FLIPPED == orientation
|
89
|
+
|
90
|
+
def landscape? = ::SDL2::SDL_ORIENTATION_LANDSCAPE == orientation
|
91
|
+
|
92
|
+
def portrait? = ::SDL2::SDL_ORIENTATION_PORTRAIT == orientation
|
93
|
+
end
|
94
|
+
include DisplayOrientation
|
95
|
+
|
96
|
+
def usable_bounds
|
97
|
+
rect = Rect.new
|
98
|
+
err = ::SDL2.SDL_GetDisplayUsableBounds(index, rect)
|
99
|
+
raise RbSDL2Error if err < 0
|
100
|
+
rect.to_a
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class DisplayMode
|
3
|
+
def initialize(format: 0, h: 0, height: h, refresh_rate: 0, w: 0, width: w)
|
4
|
+
@st = ::SDL2::SDL_DisplayMode.new
|
5
|
+
@st[:format] = PixelFormatEnum.to_num(format)
|
6
|
+
@st[:w] = width
|
7
|
+
@st[:h] = height
|
8
|
+
@st[:refresh_rate] = refresh_rate
|
9
|
+
end
|
10
|
+
|
11
|
+
def format = @st[:format]
|
12
|
+
|
13
|
+
require_relative 'pixel_format_enum'
|
14
|
+
include PixelFormatEnum
|
15
|
+
|
16
|
+
def inspect
|
17
|
+
"#<#{self.class.name} pixel_format_name=#{pixel_format_name} w=#{w} h=#{h}\
|
18
|
+
refresh_rate=#{refresh_rate}>"
|
19
|
+
end
|
20
|
+
|
21
|
+
def width = @st[:w]
|
22
|
+
|
23
|
+
alias w width
|
24
|
+
|
25
|
+
def height = @st[:h]
|
26
|
+
|
27
|
+
alias h height
|
28
|
+
|
29
|
+
def refresh_rate = @st[:refresh_rate]
|
30
|
+
|
31
|
+
def to_h = {format: format, w: w, h: h, refresh_rate: refresh_rate}
|
32
|
+
|
33
|
+
def to_ptr = @st.to_ptr
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class Event
|
3
|
+
class EventFilter < ::FFI::Function
|
4
|
+
@filter_callback = nil, nil
|
5
|
+
@filter_mutex = Mutex.new
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def filter_callback_set(obj, userdata = nil)
|
9
|
+
func = if Proc === obj
|
10
|
+
# イベントを削除する時にイベントメンバーのポインターを開放(Event#clear)する。
|
11
|
+
new { |event| obj.call(event) || (event.clear; nil) }
|
12
|
+
else
|
13
|
+
obj
|
14
|
+
end
|
15
|
+
# func, userdata の対の関係を保つ。
|
16
|
+
@filter_mutex.synchronize do
|
17
|
+
::SDL2.SDL_SetEventFilter(func, userdata)
|
18
|
+
@filter_callback = [func, userdata]
|
19
|
+
end
|
20
|
+
[obj, userdata]
|
21
|
+
end
|
22
|
+
|
23
|
+
# SDL にフィルターコールバック関数が設定されている場合に true を戻す。
|
24
|
+
def filter_callback_defined?
|
25
|
+
_func_userdata = Array.new(2) { ::FFI::MemoryPointer.new(:pointer) }
|
26
|
+
# SDL_GetEventFilter はコールバックのポインター関数が NULL の場合に SDL_FALSE となる。
|
27
|
+
# userdata ポインターが設定されていても SDL_GetEventFilter の戻り値に関与しない。
|
28
|
+
::SDL2.SDL_GetEventFilter(*_func_userdata) == ::SDL2::SDL_TRUE
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
@watch_callbacks = []
|
33
|
+
@watch_mutex = Mutex.new
|
34
|
+
|
35
|
+
class << self
|
36
|
+
def add_watch_callback(obj, userdata = nil)
|
37
|
+
func = if Proc === obj
|
38
|
+
new(&obj)
|
39
|
+
else
|
40
|
+
obj
|
41
|
+
end
|
42
|
+
obj_userdata = [obj, userdata]
|
43
|
+
@watch_mutex.synchronize do
|
44
|
+
::SDL2.SDL_AddEventWatch(func, userdata)
|
45
|
+
@watch_callbacks << [obj_userdata, func]
|
46
|
+
end
|
47
|
+
obj_userdata
|
48
|
+
end
|
49
|
+
|
50
|
+
def remove_watch_callback(obj, userdata = nil)
|
51
|
+
obj_userdata = [obj, userdata]
|
52
|
+
@watch_mutex.synchronize do
|
53
|
+
idx = @watch_callbacks.index { |obj| obj.first == obj_userdata }
|
54
|
+
if idx
|
55
|
+
_, func = @watch_callbacks.delete_at(idx)
|
56
|
+
::SDL2.SDL_DelEventWatch(func, userdata)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
obj_userdata
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
require 'delegate'
|
64
|
+
|
65
|
+
# 引数ブロックへはコールバック実行時に Event のインスタンス(のデリゲーター)が与えられる。
|
66
|
+
# 与えられた Event インスタンスは引数ブロック終了後に nil に変化する(デリゲート先を変更している)。
|
67
|
+
# SDL がイベントコールバックへ与えるイベントへのポインターがイベントキューの一部を直接指しているため
|
68
|
+
# コールバックを抜けた後にイベント内容の永続性が保証ができない(たぶん別のイベント内容になるだろう)。
|
69
|
+
# 引数ブロックに与えられたオブジェクトをスコープ外に持ち出しても安全である。
|
70
|
+
# オブジェクトではなくイベントの内容をスコープ外に持ち出したい場合は
|
71
|
+
# 与えられたオブジェクトをコピー(clone, dup)すればよい。
|
72
|
+
def initialize
|
73
|
+
# typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event);
|
74
|
+
super(:int, [:pointer, :pointer]) do |_userdata, ptr|
|
75
|
+
obj = SimpleDelegator.new(Event.to_ptr(ptr))
|
76
|
+
yield(obj) ? 1 : 0
|
77
|
+
ensure
|
78
|
+
obj.__setobj__(nil)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module RbSDL2
|
2
|
+
class Event
|
3
|
+
module EventQueue
|
4
|
+
class << self
|
5
|
+
require_relative 'event_type'
|
6
|
+
|
7
|
+
def clear
|
8
|
+
# type が ::SDL2::SDL_DROPFILE, ::SDL2::SDL_DROPTEXT の場合に
|
9
|
+
# イベントに含まれる file メンバーのポインターが開放されない。そのため Ruby 側で開放処理を行う。
|
10
|
+
event = Event.new
|
11
|
+
while peep(event, ::SDL2::SDL_GETEVENT,
|
12
|
+
type: ::SDL2::SDL_DROPFILE..::SDL2::SDL_DROPTEXT) > 0
|
13
|
+
event.clear
|
14
|
+
end
|
15
|
+
::SDL2.SDL_FlushEvents(*EventType.minmax)
|
16
|
+
end
|
17
|
+
|
18
|
+
def count(type: nil) = peep(nil, ::SDL2::SDL_PEEKEVENT, type: type)
|
19
|
+
alias length count
|
20
|
+
alias size count
|
21
|
+
|
22
|
+
def deq(non_block = false, type: nil)
|
23
|
+
event = Event.new
|
24
|
+
while peep(event, ::SDL2::SDL_GETEVENT, type: type) == 0
|
25
|
+
raise ThreadError, Error.message if non_block
|
26
|
+
end
|
27
|
+
event
|
28
|
+
end
|
29
|
+
|
30
|
+
# ブロックにはイベントキューにあるイベントが渡される。
|
31
|
+
# ブロックへ渡されるイベントはコピーされたものでありブロックの外へ持ち出すことができる。
|
32
|
+
# このメソッドは SDL のイベントキューをロックする。
|
33
|
+
def each = block_given? ? reject! { |event| yield(event.dup); true } : to_enum
|
34
|
+
|
35
|
+
def empty? = length == 0
|
36
|
+
|
37
|
+
# イベントキューが一杯の時に 例外
|
38
|
+
def enq(event, non_block = false)
|
39
|
+
event_copy(event) do |copy|
|
40
|
+
while peep(copy, ::SDL2::SDL_ADDEVENT) == 0
|
41
|
+
raise ThreadError, Error.message if non_block
|
42
|
+
end
|
43
|
+
event
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private def event_copy(event)
|
48
|
+
copy = event.dup
|
49
|
+
yield(copy).tap do
|
50
|
+
# 成功した場合はメンバーポインターはキューにコピーされた。
|
51
|
+
# ブロックの実行が成功したらメンバーポインターの開放を防ぐ。
|
52
|
+
if event.drop_file? || event.drop_text?
|
53
|
+
copy.to_ptr.autorelease = false
|
54
|
+
::SDL2.SDL_free(copy)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private def main_thread!
|
60
|
+
if Thread.main != Thread.current
|
61
|
+
raise ThreadError, "the current thread is not the main thread"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private def peep(event, action, type: nil)
|
66
|
+
min_type, max_type = case type
|
67
|
+
when nil
|
68
|
+
EventType.minmax
|
69
|
+
when Range
|
70
|
+
type.minmax
|
71
|
+
else
|
72
|
+
[type, type]
|
73
|
+
end
|
74
|
+
num = ::SDL2.SDL_PeepEvents(event, event ? 1 : 0, action, min_type, max_type)
|
75
|
+
raise RbSDL2Error if num < 0
|
76
|
+
num
|
77
|
+
end
|
78
|
+
|
79
|
+
def poll
|
80
|
+
main_thread!
|
81
|
+
event = Event.new
|
82
|
+
::SDL2::SDL_PollEvent(event).nonzero? && event
|
83
|
+
end
|
84
|
+
alias get poll
|
85
|
+
|
86
|
+
def pump
|
87
|
+
main_thread!
|
88
|
+
::SDL2.SDL_PumpEvents
|
89
|
+
end
|
90
|
+
|
91
|
+
# イベントをキューに入れる。enq との違いは push ではイベントコールバックを起動する。
|
92
|
+
# イベントがキューに入った場合は引数のイベントを戻す。フィルターされた場合は nil を戻す。
|
93
|
+
# キューに入れることを失敗したら例外が発生する。
|
94
|
+
def push(event)
|
95
|
+
event_copy(event) do |copy|
|
96
|
+
num = ::SDL2.SDL_PushEvent(copy)
|
97
|
+
if num > 0
|
98
|
+
event
|
99
|
+
elsif num == 0
|
100
|
+
nil
|
101
|
+
else
|
102
|
+
raise RbSDL2Error
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def quit?
|
108
|
+
pump
|
109
|
+
::SDL2.SDL_HasEvent(::SDL2::SDL_QUIT) == ::SDL2::SDL_TRUE
|
110
|
+
end
|
111
|
+
|
112
|
+
require_relative 'event_filter'
|
113
|
+
|
114
|
+
# ブロックへ与えられたイベントは外に持ち出すことはできない。
|
115
|
+
# このメソッドは SDL のイベントキューをロックする。
|
116
|
+
# ブロックの戻り値が false の場合、イベントはキューから取り除かれる。
|
117
|
+
# userdata に渡されたオブジェクトはポインターに変換可能なものである必要がある。
|
118
|
+
def reject!(userdata = nil)
|
119
|
+
func = EventFilter.new { |event| yield(event) || (event.clear; nil) }
|
120
|
+
::SDL2.SDL_FilterEvents(func, userdata)
|
121
|
+
end
|
122
|
+
|
123
|
+
def wait(sec = nil)
|
124
|
+
main_thread!
|
125
|
+
event = Event.new
|
126
|
+
if sec.nil?
|
127
|
+
::SDL2::SDL_WaitEvent(event).nonzero? && event
|
128
|
+
elsif sec >= 0
|
129
|
+
::SDL2::SDL_WaitEventTimeout(event, sec * 1000).nonzero? && event
|
130
|
+
else
|
131
|
+
raise ArgumentError
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,271 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module RbSDL2
|
3
|
+
class Event
|
4
|
+
module EventType
|
5
|
+
RANGE = ::SDL2::SDL_FIRSTEVENT..::SDL2::SDL_LASTEVENT
|
6
|
+
EVENT_TYPES = RANGE.first.succ...::SDL2::SDL_LASTEVENT
|
7
|
+
COMMON_EVENT_TYPES = EVENT_TYPES.first...::SDL2::SDL_USEREVENT
|
8
|
+
USER_EVENT_TYPES = ::SDL2::SDL_USEREVENT...EVENT_TYPES.last
|
9
|
+
|
10
|
+
default_type = -> (_, key) do
|
11
|
+
case key
|
12
|
+
when 0 then :common
|
13
|
+
when COMMON_EVENT_TYPES then :common
|
14
|
+
when USER_EVENT_TYPES then :user
|
15
|
+
else raise KeyError, "(#{key})"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
MEMBER_MAP = Hash.new(&default_type).merge!(
|
20
|
+
::SDL2::SDL_AUDIODEVICEADDED => :adevice,
|
21
|
+
::SDL2::SDL_AUDIODEVICEREMOVED => :adevice,
|
22
|
+
::SDL2::SDL_DISPLAYEVENT => :display,
|
23
|
+
::SDL2::SDL_KEYDOWN => :key,
|
24
|
+
::SDL2::SDL_KEYUP => :key,
|
25
|
+
::SDL2::SDL_CONTROLLERAXISMOTION => :caxis,
|
26
|
+
::SDL2::SDL_CONTROLLERBUTTONDOWN => :cbutton,
|
27
|
+
::SDL2::SDL_CONTROLLERBUTTONUP => :cbutton,
|
28
|
+
::SDL2::SDL_CONTROLLERDEVICEADDED => :cdevice,
|
29
|
+
::SDL2::SDL_CONTROLLERDEVICEREMAPPED => :cdevice,
|
30
|
+
::SDL2::SDL_CONTROLLERDEVICEREMOVED => :cdevice,
|
31
|
+
::SDL2::SDL_CONTROLLERSENSORUPDATE => :csensor,
|
32
|
+
::SDL2::SDL_CONTROLLERTOUCHPADDOWN => :ctouchpad,
|
33
|
+
::SDL2::SDL_CONTROLLERTOUCHPADMOTION => :ctouchpad,
|
34
|
+
::SDL2::SDL_CONTROLLERTOUCHPADUP => :ctouchpad,
|
35
|
+
::SDL2::SDL_DOLLARGESTURE => :dgesture,
|
36
|
+
::SDL2::SDL_DOLLARRECORD => :dgesture,
|
37
|
+
::SDL2::SDL_DROPBEGIN => :drop,
|
38
|
+
::SDL2::SDL_DROPCOMPLETE => :drop,
|
39
|
+
::SDL2::SDL_DROPFILE => :drop,
|
40
|
+
::SDL2::SDL_DROPTEXT => :drop,
|
41
|
+
::SDL2::SDL_FINGERDOWN => :tfinger,
|
42
|
+
::SDL2::SDL_FINGERMOTION => :tfinger,
|
43
|
+
::SDL2::SDL_FINGERUP => :tfinger,
|
44
|
+
::SDL2::SDL_JOYAXISMOTION => :jaxis,
|
45
|
+
::SDL2::SDL_JOYBALLMOTION => :jball,
|
46
|
+
::SDL2::SDL_JOYBUTTONDOWN => :jbutton,
|
47
|
+
::SDL2::SDL_JOYBUTTONUP => :jbutton,
|
48
|
+
::SDL2::SDL_JOYDEVICEADDED => :jdevice,
|
49
|
+
::SDL2::SDL_JOYDEVICEREMOVED => :jdevice,
|
50
|
+
::SDL2::SDL_JOYHATMOTION => :jhat,
|
51
|
+
::SDL2::SDL_MOUSEBUTTONDOWN => :button,
|
52
|
+
::SDL2::SDL_MOUSEBUTTONUP => :button,
|
53
|
+
::SDL2::SDL_MOUSEMOTION => :motion,
|
54
|
+
::SDL2::SDL_MOUSEWHEEL => :wheel,
|
55
|
+
::SDL2::SDL_MULTIGESTURE => :mgesture,
|
56
|
+
::SDL2::SDL_QUIT => :quit,
|
57
|
+
::SDL2::SDL_SENSORUPDATE => :sensor,
|
58
|
+
::SDL2::SDL_SYSWMEVENT => :syswm,
|
59
|
+
::SDL2::SDL_TEXTEDITING => :edit,
|
60
|
+
::SDL2::SDL_TEXTINPUT => :text,
|
61
|
+
::SDL2::SDL_WINDOWEVENT => :window,
|
62
|
+
).freeze
|
63
|
+
|
64
|
+
default_name = -> (_, key) do
|
65
|
+
case key
|
66
|
+
when 0 then ""
|
67
|
+
when COMMON_EVENT_TYPES then "common_event"
|
68
|
+
when USER_EVENT_TYPES then "user_event"
|
69
|
+
else raise KeyError, "(#{key})"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
@name_map = Hash.new(&default_name).merge!(
|
74
|
+
::SDL2::SDL_APP_DIDENTERBACKGROUND => "app_did_enter_background",
|
75
|
+
::SDL2::SDL_APP_DIDENTERFOREGROUND => "app_did_enter_foreground",
|
76
|
+
::SDL2::SDL_APP_LOWMEMORY => "app_low_memory",
|
77
|
+
::SDL2::SDL_APP_TERMINATING => "app_terminating",
|
78
|
+
::SDL2::SDL_APP_WILLENTERBACKGROUND => "app_will_enter_background",
|
79
|
+
::SDL2::SDL_APP_WILLENTERFOREGROUND => "app_will_enter_foreground",
|
80
|
+
::SDL2::SDL_AUDIODEVICEADDED => "audio_device_added",
|
81
|
+
::SDL2::SDL_AUDIODEVICEREMOVED => "audio_device_removed",
|
82
|
+
::SDL2::SDL_CLIPBOARDUPDATE => "clipboard_update",
|
83
|
+
::SDL2::SDL_CONTROLLERAXISMOTION => "controller_axis_motion",
|
84
|
+
::SDL2::SDL_CONTROLLERBUTTONDOWN => "controller_button_down",
|
85
|
+
::SDL2::SDL_CONTROLLERBUTTONUP => "controller_button_up",
|
86
|
+
::SDL2::SDL_CONTROLLERDEVICEADDED => "controller_device_added",
|
87
|
+
::SDL2::SDL_CONTROLLERDEVICEREMAPPED => "controller_device_remapped",
|
88
|
+
::SDL2::SDL_CONTROLLERDEVICEREMOVED => "controller_device_removed",
|
89
|
+
::SDL2::SDL_CONTROLLERSENSORUPDATE => "controller_sensor_update",
|
90
|
+
::SDL2::SDL_CONTROLLERTOUCHPADDOWN => "controller_touchpad_down",
|
91
|
+
::SDL2::SDL_CONTROLLERTOUCHPADMOTION => "controller_touchpad_motion",
|
92
|
+
::SDL2::SDL_CONTROLLERTOUCHPADUP => "controller_touchpad_up",
|
93
|
+
::SDL2::SDL_DISPLAYEVENT => "display_event",
|
94
|
+
::SDL2::SDL_DOLLARGESTURE => "dollar_gesture",
|
95
|
+
::SDL2::SDL_DOLLARRECORD => "dollar_record",
|
96
|
+
::SDL2::SDL_DROPBEGIN => "drop_begin",
|
97
|
+
::SDL2::SDL_DROPCOMPLETE => "drop_complete",
|
98
|
+
::SDL2::SDL_DROPFILE => "drop_file",
|
99
|
+
::SDL2::SDL_DROPTEXT => "drop_text",
|
100
|
+
::SDL2::SDL_FINGERDOWN => "finger_down",
|
101
|
+
::SDL2::SDL_FINGERUP => "finger_up",
|
102
|
+
::SDL2::SDL_FINGERMOTION => "finger_motion",
|
103
|
+
::SDL2::SDL_JOYAXISMOTION => "joy_axis_motion",
|
104
|
+
::SDL2::SDL_JOYBALLMOTION => "joy_ball_motion",
|
105
|
+
::SDL2::SDL_JOYBUTTONDOWN => "joy_button_down",
|
106
|
+
::SDL2::SDL_JOYBUTTONUP => "joy_button_up",
|
107
|
+
::SDL2::SDL_JOYDEVICEADDED => "joy_device_added",
|
108
|
+
::SDL2::SDL_JOYDEVICEREMOVED => "joy_device_removed",
|
109
|
+
::SDL2::SDL_JOYHATMOTION => "joy_hat_motion",
|
110
|
+
::SDL2::SDL_KEYDOWN => "key_down",
|
111
|
+
::SDL2::SDL_KEYUP => "key_up",
|
112
|
+
::SDL2::SDL_KEYMAPCHANGED => "keymap_changed",
|
113
|
+
::SDL2::SDL_LOCALECHANGED => "locale_changed",
|
114
|
+
::SDL2::SDL_MULTIGESTURE => "multi_gesture",
|
115
|
+
::SDL2::SDL_MOUSEBUTTONDOWN => "mouse_button_down",
|
116
|
+
::SDL2::SDL_MOUSEBUTTONUP => "mouse_button_up",
|
117
|
+
::SDL2::SDL_MOUSEMOTION => "mouse_motion",
|
118
|
+
::SDL2::SDL_MOUSEWHEEL => "mouse_wheel",
|
119
|
+
::SDL2::SDL_QUIT => "quit",
|
120
|
+
::SDL2::SDL_RENDER_DEVICE_RESET => "render_device_reset",
|
121
|
+
::SDL2::SDL_RENDER_TARGETS_RESET => "render_targets_reset",
|
122
|
+
::SDL2::SDL_SENSORUPDATE => "sensor_update",
|
123
|
+
::SDL2::SDL_SYSWMEVENT => "sys_wm_event",
|
124
|
+
::SDL2::SDL_TEXTEDITING => "text_editing",
|
125
|
+
::SDL2::SDL_TEXTINPUT => "text_input",
|
126
|
+
::SDL2::SDL_WINDOWEVENT => "window_event",
|
127
|
+
)
|
128
|
+
|
129
|
+
@mutex = Mutex.new
|
130
|
+
|
131
|
+
class << self
|
132
|
+
def define_user_event(name = "user_event")
|
133
|
+
@mutex.synchronize do
|
134
|
+
num = ::SDL2::SDL_RegisterEvents(1)
|
135
|
+
if num == 0xFFFFFFFF
|
136
|
+
raise RbSDL2Error, "unable to register user events because too many requests"
|
137
|
+
end
|
138
|
+
@name_map[num] = name
|
139
|
+
num
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def disable(type) = ::SDL2.SDL_EventState(type, ::SDL2::SDL_DISABLE) == ::SDL2::SDL_ENABLE
|
144
|
+
|
145
|
+
def enable(type) = ::SDL2.SDL_EventState(type, ::SDL2::SDL_ENABLE) == ::SDL2::SDL_DISABLE
|
146
|
+
|
147
|
+
def ignore?(type) = ::SDL2.SDL_EventState(type, ::SDL2::SDL_QUERY) == ::SDL2::SDL_IGNORE
|
148
|
+
|
149
|
+
def minmax = RANGE.minmax
|
150
|
+
|
151
|
+
def to_name(num) = @name_map[num]
|
152
|
+
|
153
|
+
def to_num(obj)
|
154
|
+
num = @name_map.key(obj.to_s)
|
155
|
+
raise ArgumentError unless num
|
156
|
+
num
|
157
|
+
end
|
158
|
+
|
159
|
+
def to_type(num) = MEMBER_MAP[num]
|
160
|
+
end
|
161
|
+
|
162
|
+
def app_did_enter_background? = ::SDL2::SDL_APP_DIDENTERBACKGROUND == type
|
163
|
+
|
164
|
+
def app_did_enter_foreground? = ::SDL2::SDL_APP_DIDENTERFOREGROUND == type
|
165
|
+
|
166
|
+
def app_low_memory? = ::SDL2::SDL_APP_LOWMEMORY == type
|
167
|
+
|
168
|
+
def app_terminating? = ::SDL2::SDL_APP_TERMINATING == type
|
169
|
+
|
170
|
+
def app_will_enter_background? = ::SDL2::SDL_APP_WILLENTERBACKGROUND == type
|
171
|
+
|
172
|
+
def app_will_enter_foreground? = ::SDL2::SDL_APP_WILLENTERFOREGROUND == type
|
173
|
+
|
174
|
+
def audio_device_added? = ::SDL2::SDL_AUDIODEVICEADDED == type
|
175
|
+
|
176
|
+
def audio_device_removed? = ::SDL2::SDL_AUDIODEVICEREMOVED == type
|
177
|
+
|
178
|
+
def clipboard_update? = ::SDL2::SDL_CLIPBOARDUPDATE == type
|
179
|
+
|
180
|
+
def controller_axis_motion? = ::SDL2::SDL_CONTROLLERAXISMOTION == type
|
181
|
+
|
182
|
+
def controller_button_down? = ::SDL2::SDL_CONTROLLERBUTTONDOWN == type
|
183
|
+
|
184
|
+
def controller_button_up? = ::SDL2::SDL_CONTROLLERBUTTONUP == type
|
185
|
+
|
186
|
+
def controller_device_added? = ::SDL2::SDL_CONTROLLERDEVICEADDED == type
|
187
|
+
|
188
|
+
def controller_device_remapped? = ::SDL2::SDL_CONTROLLERDEVICEREMAPPED == type
|
189
|
+
|
190
|
+
def controller_device_removed? = ::SDL2::SDL_CONTROLLERDEVICEREMOVED == type
|
191
|
+
|
192
|
+
def controller_sensor_update? = ::SDL2::SDL_CONTROLLERSENSORUPDATE == type
|
193
|
+
|
194
|
+
def controller_touchpad_down? = ::SDL2::SDL_CONTROLLERTOUCHPADDOWN == type
|
195
|
+
|
196
|
+
def controller_touchpad_motion? = ::SDL2::SDL_CONTROLLERTOUCHPADMOTION == type
|
197
|
+
|
198
|
+
def controller_touchpad_up? = ::SDL2::SDL_CONTROLLERTOUCHPADUP == type
|
199
|
+
|
200
|
+
def display_event? = ::SDL2::SDL_DISPLAYEVENT == type
|
201
|
+
|
202
|
+
def dollar_gesture? = ::SDL2::SDL_DOLLARGESTURE == type
|
203
|
+
|
204
|
+
def dollar_record? = ::SDL2::SDL_DOLLARRECORD == type
|
205
|
+
|
206
|
+
def drop_begin? = ::SDL2::SDL_DROPBEGIN == type
|
207
|
+
|
208
|
+
def drop_complete? = ::SDL2::SDL_DROPCOMPLETE == type
|
209
|
+
|
210
|
+
def drop_file? = ::SDL2::SDL_DROPFILE == type
|
211
|
+
|
212
|
+
def drop_text? = ::SDL2::SDL_DROPTEXT == type
|
213
|
+
|
214
|
+
def finger_down? = ::SDL2::SDL_FINGERDOWN == type
|
215
|
+
|
216
|
+
def finger_up? = ::SDL2::SDL_FINGERUP == type
|
217
|
+
|
218
|
+
def finger_motion? = ::SDL2::SDL_FINGERMOTION == type
|
219
|
+
|
220
|
+
def joy_axis_motion? = ::SDL2::SDL_JOYAXISMOTION == type
|
221
|
+
|
222
|
+
def joy_ball_motion? = ::SDL2::SDL_JOYBALLMOTION == type
|
223
|
+
|
224
|
+
def joy_button_down? = ::SDL2::SDL_JOYBUTTONDOWN == type
|
225
|
+
|
226
|
+
def joy_button_up? = ::SDL2::SDL_JOYBUTTONUP == type
|
227
|
+
|
228
|
+
def joy_device_added? = ::SDL2::SDL_JOYDEVICEADDED == type
|
229
|
+
|
230
|
+
def joy_device_removed? = ::SDL2::SDL_JOYDEVICEREMOVED == type
|
231
|
+
|
232
|
+
def joy_hat_motion? = ::SDL2::SDL_JOYHATMOTION == type
|
233
|
+
|
234
|
+
def key_down? = ::SDL2::SDL_KEYDOWN == type
|
235
|
+
|
236
|
+
def key_up? = ::SDL2::SDL_KEYUP == type
|
237
|
+
|
238
|
+
def keymap_changed? = ::SDL2::SDL_KEYMAPCHANGED == type
|
239
|
+
|
240
|
+
def locale_changed? = ::SDL2::SDL_LOCALECHANGED == type
|
241
|
+
|
242
|
+
def multi_gesture? = ::SDL2::SDL_MULTIGESTURE == type
|
243
|
+
|
244
|
+
def mouse_button_down? = ::SDL2::SDL_MOUSEBUTTONDOWN == type
|
245
|
+
|
246
|
+
def mouse_button_up? = ::SDL2::SDL_MOUSEBUTTONUP == type
|
247
|
+
|
248
|
+
def mouse_motion? = ::SDL2::SDL_MOUSEMOTION == type
|
249
|
+
|
250
|
+
def mouse_wheel? = ::SDL2::SDL_MOUSEWHEEL == type
|
251
|
+
|
252
|
+
def quit? = ::SDL2::SDL_QUIT == type
|
253
|
+
|
254
|
+
def render_device_reset? = ::SDL2::SDL_RENDER_DEVICE_RESET == type
|
255
|
+
|
256
|
+
def render_targets_reset? = ::SDL2::SDL_RENDER_TARGETS_RESET == type
|
257
|
+
|
258
|
+
def sensor_update? = ::SDL2::SDL_SENSORUPDATE == type
|
259
|
+
|
260
|
+
def sys_wm_event? = ::SDL2::SDL_SYSWMEVENT == type
|
261
|
+
|
262
|
+
def text_editing? = ::SDL2::SDL_TEXTEDITING == type
|
263
|
+
|
264
|
+
def text_input? = ::SDL2::SDL_TEXTINPUT == type
|
265
|
+
|
266
|
+
def user_event? = USER_EVENT_TYPES === type
|
267
|
+
|
268
|
+
def window_event? = ::SDL2::SDL_WINDOWEVENT == type
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|