Module: Qt::EventRuntime
- Defined in:
- lib/qt/event_runtime.rb,
lib/qt/event_runtime_qobject_methods.rb
Overview
Event/signal subscription runtime backed by generated native callbacks.
Defined Under Namespace
Modules: QObjectMethods
Constant Summary collapse
- WidgetMethods =
Backward-compatible alias for already-generated code.
QObjectMethods
Class Method Summary collapse
- .acquire_signal_registration(handle, signal_key) ⇒ Object
- .clear_signal_registrations_for_address(address) ⇒ Object
- .decode_event_payload(event_type, payload_json) ⇒ Object
- .ensure_event_callback! ⇒ Object
- .ensure_native_bridge_ready! ⇒ Object
- .ensure_signal_callback! ⇒ Object
- .event_type_for(event_name) ⇒ Object
- .off_event(widget, event_name = nil) ⇒ Object
- .off_event_for_widget(handle, per_widget, event_name) ⇒ Object
- .off_signal(widget, signal_name = nil) ⇒ Object
- .on_event(widget, event_name, &block) ⇒ Object
- .on_internal_signal(widget, signal_name, &block) ⇒ Object
- .on_signal(widget, signal_name, &block) ⇒ Object
- .prepare_signal_registration(signal_store, handle, signal_name) ⇒ Object
- .release_signal_registration(handle, signal_key) ⇒ Object
- .widget_handle(widget) ⇒ Object
Class Method Details
.acquire_signal_registration(handle, signal_key) ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/qt/event_runtime.rb', line 160 def acquire_signal_registration(handle, signal_key) @signal_registrations ||= {} = (@signal_registrations[handle.address] ||= {}) registration = ([signal_key] ||= { index: nil, refcount: 0 }) if registration[:index].nil? index = Qt::Native.qobject_connect_signal(handle, signal_key) raise ArgumentError, "failed to connect signal #{signal_key.inspect} (code=#{index})" if index.negative? registration[:index] = index end registration[:refcount] += 1 registration[:index] end |
.clear_signal_registrations_for_address(address) ⇒ Object
191 192 193 194 195 |
# File 'lib/qt/event_runtime.rb', line 191 def clear_signal_registrations_for_address(address) @signal_handlers&.delete(address) @internal_signal_handlers&.delete(address) @signal_registrations&.delete(address) end |
.decode_event_payload(event_type, payload_json) ⇒ Object
133 134 135 136 137 138 139 140 141 142 |
# File 'lib/qt/event_runtime.rb', line 133 def decode_event_payload(event_type, payload_json) payload = if payload_json.nil? || payload_json.empty? {} else JSON.parse(Qt::StringCodec.from_qt_text(payload_json), symbolize_names: true) end payload[:type] ||= event_type payload end |
.ensure_event_callback! ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/qt/event_runtime.rb', line 101 def ensure_event_callback! return if @event_callback @event_callback = FFI::Function.new( :int, %i[pointer int string] ) do |object_handle, event_type, payload_json| payload = decode_event_payload(event_type, payload_json) EventRuntimeDispatch.dispatch_event(@event_handlers, object_handle, event_type, payload) end Qt::Native.set_event_callback(@event_callback) end |
.ensure_native_bridge_ready! ⇒ Object
144 145 146 147 |
# File 'lib/qt/event_runtime.rb', line 144 def ensure_native_bridge_ready! Qt::Native.ensure_loaded! Qt::Native.define_bridge_wrappers! end |
.ensure_signal_callback! ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/qt/event_runtime.rb', line 114 def ensure_signal_callback! return if @signal_callback @signal_callback = FFI::Function.new(:void, %i[pointer int string]) do |object_handle, signal_index, payload| normalized_payload = payload.nil? ? nil : Qt::StringCodec.from_qt_text(payload) EventRuntimeDispatch.dispatch_signal( @internal_signal_handlers, @signal_handlers, object_handle, signal_index, normalized_payload ) end Qt::Native.set_signal_callback(@signal_callback) end |
.event_type_for(event_name) ⇒ Object
93 94 95 96 97 98 99 |
# File 'lib/qt/event_runtime.rb', line 93 def event_type_for(event_name) key = event_name.to_sym event_type = Qt::GENERATED_EVENT_TYPES[key] raise ArgumentError, "unknown event: #{event_name.inspect}" unless event_type event_type end |
.off_event(widget, event_name = nil) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/qt/event_runtime.rb', line 81 def off_event(, event_name = nil) ensure_native_bridge_ready! handle = () return false if handle.nil? || @event_handlers.nil? = @event_handlers[handle.address] return false unless (handle, , event_name) true end |
.off_event_for_widget(handle, per_widget, event_name) ⇒ Object
149 150 151 152 153 154 155 156 157 158 |
# File 'lib/qt/event_runtime.rb', line 149 def (handle, , event_name) if event_name event_type = event_type_for(event_name) .delete(event_type) Qt::Native.unwatch_qobject_event(handle, event_type) else .each_key { |event_type| Qt::Native.unwatch_qobject_event(handle, event_type) } @event_handlers.delete(handle.address) end end |
.off_signal(widget, signal_name = nil) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/qt/event_runtime.rb', line 61 def off_signal(, signal_name = nil) ensure_native_bridge_ready! handle = () return false if handle.nil? || @signal_handlers.nil? = @signal_handlers[handle.address] return false if .nil? signal_key = signal_name&.to_s if signal_key .delete(signal_key) release_signal_registration(handle, signal_key) else .keys.each { |registered_signal| release_signal_registration(handle, registered_signal) } .clear end @signal_handlers.delete(handle.address) if .empty? true end |
.on_event(widget, event_name, &block) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/qt/event_runtime.rb', line 10 def on_event(, event_name, &block) raise ArgumentError, 'pass block to on_event' unless block ensure_native_bridge_ready! ensure_event_callback! event_type = event_type_for(event_name) handle = () || raise(ArgumentError, 'widget handle is required') @event_handlers ||= {} ((@event_handlers[handle.address] ||= {})[event_type] ||= []) << block Qt::Native.watch_qobject_event(handle, event_type) true end |
.on_internal_signal(widget, signal_name, &block) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/qt/event_runtime.rb', line 38 def on_internal_signal(, signal_name, &block) raise ArgumentError, 'pass block to on_internal_signal' unless block ensure_native_bridge_ready! ensure_signal_callback! handle = () || raise(ArgumentError, 'widget handle is required') per_signal = prepare_signal_registration(@internal_signal_handlers ||= {}, handle, signal_name) per_signal[:blocks] << block true end |
.on_signal(widget, signal_name, &block) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/qt/event_runtime.rb', line 26 def on_signal(, signal_name, &block) raise ArgumentError, 'pass block to on_signal' unless block ensure_native_bridge_ready! ensure_signal_callback! handle = () || raise(ArgumentError, 'widget handle is required') per_signal = prepare_signal_registration(@signal_handlers ||= {}, handle, signal_name) per_signal[:blocks] << block true end |
.prepare_signal_registration(signal_store, handle, signal_name) ⇒ Object
50 51 52 53 54 55 56 57 58 59 |
# File 'lib/qt/event_runtime.rb', line 50 def prepare_signal_registration(signal_store, handle, signal_name) signal_key = signal_name.to_s raise ArgumentError, 'signal name is required' if signal_key.empty? per_signal = ((signal_store[handle.address] ||= {})[signal_key] ||= { index: nil, blocks: [] }) if per_signal[:index].nil? per_signal[:index] = acquire_signal_registration(handle, signal_key) end per_signal end |
.release_signal_registration(handle, signal_key) ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/qt/event_runtime.rb', line 174 def release_signal_registration(handle, signal_key) return if @signal_registrations.nil? = @signal_registrations[handle.address] return if .nil? registration = [signal_key] return if registration.nil? registration[:refcount] -= 1 return if registration[:refcount].positive? Qt::Native.qobject_disconnect_signal(handle, signal_key) .delete(signal_key) @signal_registrations.delete(handle.address) if .empty? end |
.widget_handle(widget) ⇒ Object
127 128 129 130 131 |
# File 'lib/qt/event_runtime.rb', line 127 def () return nil if .nil? .respond_to?(:handle) ? .handle : end |