Class: Plushie::Subscription
- Inherits:
-
Object
- Object
- Plushie::Subscription
- Defined in:
- lib/plushie/subscription.rb
Overview
Declarative subscription specifications.
Return subscriptions from your subscribe method. The runtime diffs the list each cycle and starts/stops subscriptions automatically.
def subscribe(model) subs = [Subscription.on_key_press] subs << Subscription.every(1000, :tick) if model.timer_running subs end
Timer subscriptions require a tag (it appears in the Timer event). Renderer subscriptions do not take a tag; they are identified by their kind and optional window scope.
Defined Under Namespace
Classes: Sub
Instance Attribute Summary collapse
-
#interval [Integer, nil] interval in milliseconds (only for :every)([Integer, nil]) ⇒ Object
readonly
An immutable subscription specification.
-
#max_rate [Integer, nil] maximum events per second (nil = unlimited)([Integer, nil](nil = unlimited)) ⇒ Object
readonly
An immutable subscription specification.
-
#tag [Symbol, nil] identifier for timer event correlation (timers only)([Symbol, nil]) ⇒ Object
readonly
An immutable subscription specification.
-
#type [Symbol] subscription type (:every, :on_key_press, etc.)([Symbol](: every, :on_key_press, etc.)) ⇒ Object
readonly
An immutable subscription specification.
-
#window_id [String, nil] window scope (nil = all windows)([String, nil](nil = all windows)) ⇒ Object
readonly
An immutable subscription specification.
Class Method Summary collapse
-
.every(interval_ms, tag) ⇒ Sub
Subscribe to a periodic timer.
-
.for_window(window_id, subscriptions) ⇒ Array<Sub>
Scope a list of subscriptions to a specific window.
-
.on_animation_frame(max_rate: nil, window: nil) ⇒ Sub
Subscribe to animation frame ticks for smooth animations.
-
.on_event(max_rate: nil, window: nil) ⇒ Sub
Subscribe to all renderer events (catch-all).
-
.on_file_drop(max_rate: nil, window: nil) ⇒ Sub
Subscribe to file drag and drop events.
-
.on_ime(max_rate: nil, window: nil) ⇒ Sub
Subscribe to IME (Input Method Editor) composition events.
-
.on_key_press(max_rate: nil, window: nil) ⇒ Sub
Subscribe to keyboard press events.
-
.on_key_release(max_rate: nil, window: nil) ⇒ Sub
Subscribe to keyboard release events.
-
.on_modifiers_changed(max_rate: nil, window: nil) ⇒ Sub
Subscribe to modifier key state changes.
-
.on_pointer_button(max_rate: nil, window: nil) ⇒ Sub
Subscribe to pointer button press/release events (mouse or touch).
-
.on_pointer_move(max_rate: nil, window: nil) ⇒ Sub
Subscribe to pointer movement events (mouse or touch).
-
.on_pointer_scroll(max_rate: nil, window: nil) ⇒ Sub
Subscribe to pointer scroll events.
-
.on_pointer_touch(max_rate: nil, window: nil) ⇒ Sub
Subscribe to touch events.
-
.on_theme_change(max_rate: nil, window: nil) ⇒ Sub
Subscribe to OS theme changes (light/dark mode).
-
.on_window_close(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window close request events.
-
.on_window_focus(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window focus events.
-
.on_window_move(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window move events.
-
.on_window_open(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window opened events.
-
.on_window_resize(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window resize events.
-
.on_window_unfocus(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window unfocus events.
Instance Attribute Details
#interval [Integer, nil] interval in milliseconds (only for :every)([Integer, nil]) ⇒ Object (readonly)
An immutable subscription specification.
Created via factory methods on Subscription rather than directly.
The runtime uses #key to diff subscriptions between cycles,
starting new ones and stopping removed ones automatically.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/plushie/subscription.rb', line 31 Sub = Data.define(:type, :tag, :interval, :max_rate, :window_id) do def initialize(type:, tag: nil, interval: nil, max_rate: nil, window_id: nil) super end # Returns a key that uniquely identifies this subscription. # Used by the runtime to diff subscription lists between cycles. # Timer subs include the interval so that changing the interval # creates a new subscription rather than updating the existing one. # Renderer subs are keyed by type and window_id. # # @return [Array] unique identity tuple for this subscription def key if type == :every [:every, interval, tag] else [type, window_id] end end # Derive the wire tag sent to the renderer. Window-scoped # subscriptions include the window_id so they don't collide # with global subscriptions of the same kind. # # @return [String] def wire_tag kind = type.to_s window_id ? "#{kind}:#{window_id}" : kind end # Set the maximum event rate (events per second). # # @param rate [Integer] max events per second # @return [Sub] new Sub with the rate applied def with_max_rate(rate) self.class.new(**to_h.merge(max_rate: rate)) end end |
#max_rate [Integer, nil] maximum events per second (nil = unlimited)([Integer, nil](nil = unlimited)) ⇒ Object (readonly)
An immutable subscription specification.
Created via factory methods on Subscription rather than directly.
The runtime uses #key to diff subscriptions between cycles,
starting new ones and stopping removed ones automatically.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/plushie/subscription.rb', line 31 Sub = Data.define(:type, :tag, :interval, :max_rate, :window_id) do def initialize(type:, tag: nil, interval: nil, max_rate: nil, window_id: nil) super end # Returns a key that uniquely identifies this subscription. # Used by the runtime to diff subscription lists between cycles. # Timer subs include the interval so that changing the interval # creates a new subscription rather than updating the existing one. # Renderer subs are keyed by type and window_id. # # @return [Array] unique identity tuple for this subscription def key if type == :every [:every, interval, tag] else [type, window_id] end end # Derive the wire tag sent to the renderer. Window-scoped # subscriptions include the window_id so they don't collide # with global subscriptions of the same kind. # # @return [String] def wire_tag kind = type.to_s window_id ? "#{kind}:#{window_id}" : kind end # Set the maximum event rate (events per second). # # @param rate [Integer] max events per second # @return [Sub] new Sub with the rate applied def with_max_rate(rate) self.class.new(**to_h.merge(max_rate: rate)) end end |
#tag [Symbol, nil] identifier for timer event correlation (timers only)([Symbol, nil]) ⇒ Object (readonly)
An immutable subscription specification.
Created via factory methods on Subscription rather than directly.
The runtime uses #key to diff subscriptions between cycles,
starting new ones and stopping removed ones automatically.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/plushie/subscription.rb', line 31 Sub = Data.define(:type, :tag, :interval, :max_rate, :window_id) do def initialize(type:, tag: nil, interval: nil, max_rate: nil, window_id: nil) super end # Returns a key that uniquely identifies this subscription. # Used by the runtime to diff subscription lists between cycles. # Timer subs include the interval so that changing the interval # creates a new subscription rather than updating the existing one. # Renderer subs are keyed by type and window_id. # # @return [Array] unique identity tuple for this subscription def key if type == :every [:every, interval, tag] else [type, window_id] end end # Derive the wire tag sent to the renderer. Window-scoped # subscriptions include the window_id so they don't collide # with global subscriptions of the same kind. # # @return [String] def wire_tag kind = type.to_s window_id ? "#{kind}:#{window_id}" : kind end # Set the maximum event rate (events per second). # # @param rate [Integer] max events per second # @return [Sub] new Sub with the rate applied def with_max_rate(rate) self.class.new(**to_h.merge(max_rate: rate)) end end |
#type [Symbol] subscription type (:every, :on_key_press, etc.)([Symbol](: every, :on_key_press, etc.)) ⇒ Object (readonly)
An immutable subscription specification.
Created via factory methods on Subscription rather than directly.
The runtime uses #key to diff subscriptions between cycles,
starting new ones and stopping removed ones automatically.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/plushie/subscription.rb', line 31 Sub = Data.define(:type, :tag, :interval, :max_rate, :window_id) do def initialize(type:, tag: nil, interval: nil, max_rate: nil, window_id: nil) super end # Returns a key that uniquely identifies this subscription. # Used by the runtime to diff subscription lists between cycles. # Timer subs include the interval so that changing the interval # creates a new subscription rather than updating the existing one. # Renderer subs are keyed by type and window_id. # # @return [Array] unique identity tuple for this subscription def key if type == :every [:every, interval, tag] else [type, window_id] end end # Derive the wire tag sent to the renderer. Window-scoped # subscriptions include the window_id so they don't collide # with global subscriptions of the same kind. # # @return [String] def wire_tag kind = type.to_s window_id ? "#{kind}:#{window_id}" : kind end # Set the maximum event rate (events per second). # # @param rate [Integer] max events per second # @return [Sub] new Sub with the rate applied def with_max_rate(rate) self.class.new(**to_h.merge(max_rate: rate)) end end |
#window_id [String, nil] window scope (nil = all windows)([String, nil](nil = all windows)) ⇒ Object (readonly)
An immutable subscription specification.
Created via factory methods on Subscription rather than directly.
The runtime uses #key to diff subscriptions between cycles,
starting new ones and stopping removed ones automatically.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/plushie/subscription.rb', line 31 Sub = Data.define(:type, :tag, :interval, :max_rate, :window_id) do def initialize(type:, tag: nil, interval: nil, max_rate: nil, window_id: nil) super end # Returns a key that uniquely identifies this subscription. # Used by the runtime to diff subscription lists between cycles. # Timer subs include the interval so that changing the interval # creates a new subscription rather than updating the existing one. # Renderer subs are keyed by type and window_id. # # @return [Array] unique identity tuple for this subscription def key if type == :every [:every, interval, tag] else [type, window_id] end end # Derive the wire tag sent to the renderer. Window-scoped # subscriptions include the window_id so they don't collide # with global subscriptions of the same kind. # # @return [String] def wire_tag kind = type.to_s window_id ? "#{kind}:#{window_id}" : kind end # Set the maximum event rate (events per second). # # @param rate [Integer] max events per second # @return [Sub] new Sub with the rate applied def with_max_rate(rate) self.class.new(**to_h.merge(max_rate: rate)) end end |
Class Method Details
.every(interval_ms, tag) ⇒ Sub
Subscribe to a periodic timer. Delivers Event::Timer[tag: tag, timestamp: ms] to update at the given interval.
76 77 78 |
# File 'lib/plushie/subscription.rb', line 76 def self.every(interval_ms, tag) Sub.new(type: :every, tag:, interval: interval_ms) end |
.for_window(window_id, subscriptions) ⇒ Array<Sub>
Scope a list of subscriptions to a specific window.
Window-scoped subscriptions tell the renderer to only deliver events from the given window. Without a window scope, subscriptions receive events from all windows.
Subscription.for_window("editor", [ Subscription.on_key_press(max_rate: 60), Subscription.on_pointer_move(max_rate: 60) ])
275 276 277 |
# File 'lib/plushie/subscription.rb', line 275 def self.for_window(window_id, subscriptions) subscriptions.map { |sub| sub.with(window_id: window_id) } end |
.on_animation_frame(max_rate: nil, window: nil) ⇒ Sub
Subscribe to animation frame ticks for smooth animations. Delivers Event::System[type: :animation_frame, data: delta_ms] to update.
236 237 238 |
# File 'lib/plushie/subscription.rb', line 236 def self.on_animation_frame(max_rate: nil, window: nil) Sub.new(type: :on_animation_frame, max_rate:, window_id: window) end |
.on_event(max_rate: nil, window: nil) ⇒ Sub
Subscribe to all renderer events (catch-all). Delivers the raw event to update without filtering by type. Useful for debugging or handling event types not covered by specific subscriptions.
257 258 259 |
# File 'lib/plushie/subscription.rb', line 257 def self.on_event(max_rate: nil, window: nil) Sub.new(type: :on_event, max_rate:, window_id: window) end |
.on_file_drop(max_rate: nil, window: nil) ⇒ Sub
Subscribe to file drag and drop events. Delivers Event::Window[type: :file_dropped/:file_hovered, path:] to update.
246 247 248 |
# File 'lib/plushie/subscription.rb', line 246 def self.on_file_drop(max_rate: nil, window: nil) Sub.new(type: :on_file_drop, max_rate:, window_id: window) end |
.on_ime(max_rate: nil, window: nil) ⇒ Sub
Subscribe to IME (Input Method Editor) composition events. Delivers Event::Ime[type: :enabled/:preedit/:commit/:disabled, ...] to update.
216 217 218 |
# File 'lib/plushie/subscription.rb', line 216 def self.on_ime(max_rate: nil, window: nil) Sub.new(type: :on_ime, max_rate:, window_id: window) end |
.on_key_press(max_rate: nil, window: nil) ⇒ Sub
Subscribe to keyboard press events. Delivers Event::Key[type: :press, ...] to update.
86 87 88 |
# File 'lib/plushie/subscription.rb', line 86 def self.on_key_press(max_rate: nil, window: nil) Sub.new(type: :on_key_press, max_rate:, window_id: window) end |
.on_key_release(max_rate: nil, window: nil) ⇒ Sub
Subscribe to keyboard release events. Delivers Event::Key[type: :release, ...] to update.
96 97 98 |
# File 'lib/plushie/subscription.rb', line 96 def self.on_key_release(max_rate: nil, window: nil) Sub.new(type: :on_key_release, max_rate:, window_id: window) end |
.on_modifiers_changed(max_rate: nil, window: nil) ⇒ Sub
Subscribe to modifier key state changes. Delivers Event::Modifiers with the current modifier state.
106 107 108 |
# File 'lib/plushie/subscription.rb', line 106 def self.on_modifiers_changed(max_rate: nil, window: nil) Sub.new(type: :on_modifiers_changed, max_rate:, window_id: window) end |
.on_pointer_button(max_rate: nil, window: nil) ⇒ Sub
Subscribe to pointer button press/release events (mouse or touch). Delivers Event::Widget with type: :press/:release, pointer data in data map.
126 127 128 |
# File 'lib/plushie/subscription.rb', line 126 def self.(max_rate: nil, window: nil) Sub.new(type: :on_pointer_button, max_rate:, window_id: window) end |
.on_pointer_move(max_rate: nil, window: nil) ⇒ Sub
Subscribe to pointer movement events (mouse or touch). Delivers Event::Widget with type: :move, pointer data in data map.
116 117 118 |
# File 'lib/plushie/subscription.rb', line 116 def self.on_pointer_move(max_rate: nil, window: nil) Sub.new(type: :on_pointer_move, max_rate:, window_id: window) end |
.on_pointer_scroll(max_rate: nil, window: nil) ⇒ Sub
Subscribe to pointer scroll events. Delivers Event::Widget with type: :scroll, pointer data in data map.
136 137 138 |
# File 'lib/plushie/subscription.rb', line 136 def self.on_pointer_scroll(max_rate: nil, window: nil) Sub.new(type: :on_pointer_scroll, max_rate:, window_id: window) end |
.on_pointer_touch(max_rate: nil, window: nil) ⇒ Sub
Subscribe to touch events. Delivers Event::Widget with type: :press/:move/:release, pointer: :touch in data.
206 207 208 |
# File 'lib/plushie/subscription.rb', line 206 def self.on_pointer_touch(max_rate: nil, window: nil) Sub.new(type: :on_pointer_touch, max_rate:, window_id: window) end |
.on_theme_change(max_rate: nil, window: nil) ⇒ Sub
Subscribe to OS theme changes (light/dark mode). Delivers Event::System[type: :theme_changed, data: theme_name] to update.
226 227 228 |
# File 'lib/plushie/subscription.rb', line 226 def self.on_theme_change(max_rate: nil, window: nil) Sub.new(type: :on_theme_change, max_rate:, window_id: window) end |
.on_window_close(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window close request events. Delivers Event::Window[type: :close_requested, window_id:] to update.
146 147 148 |
# File 'lib/plushie/subscription.rb', line 146 def self.on_window_close(max_rate: nil, window: nil) Sub.new(type: :on_window_close, max_rate:, window_id: window) end |
.on_window_focus(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window focus events. Delivers Event::Window[type: :focused, window_id:] to update.
176 177 178 |
# File 'lib/plushie/subscription.rb', line 176 def self.on_window_focus(max_rate: nil, window: nil) Sub.new(type: :on_window_focus, max_rate:, window_id: window) end |
.on_window_move(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window move events. Delivers Event::Window[type: :moved, window_id:, x:, y:] to update.
196 197 198 |
# File 'lib/plushie/subscription.rb', line 196 def self.on_window_move(max_rate: nil, window: nil) Sub.new(type: :on_window_move, max_rate:, window_id: window) end |
.on_window_open(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window opened events. Delivers Event::Window[type: :opened, window_id:, width:, height:] to update.
156 157 158 |
# File 'lib/plushie/subscription.rb', line 156 def self.on_window_open(max_rate: nil, window: nil) Sub.new(type: :on_window_open, max_rate:, window_id: window) end |
.on_window_resize(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window resize events. Delivers Event::Window[type: :resized, window_id:, width:, height:] to update.
166 167 168 |
# File 'lib/plushie/subscription.rb', line 166 def self.on_window_resize(max_rate: nil, window: nil) Sub.new(type: :on_window_resize, max_rate:, window_id: window) end |
.on_window_unfocus(max_rate: nil, window: nil) ⇒ Sub
Subscribe to window unfocus events. Delivers Event::Window[type: :unfocused, window_id:] to update.
186 187 188 |
# File 'lib/plushie/subscription.rb', line 186 def self.on_window_unfocus(max_rate: nil, window: nil) Sub.new(type: :on_window_unfocus, max_rate:, window_id: window) end |