Module: Plushie::Protocol::Encode
- Defined in:
- lib/plushie/protocol/encode.rb,
sig/plushie/protocol.rbs
Overview
Outbound message encoding for the wire protocol.
Every method produces wire-ready bytes (iodata for msgpack, JSONL string for json). The session field defaults to "" and is injected by the Connection or SessionPool when multiplexing.
Class Method Summary collapse
-
.encode(map, format = :msgpack) ⇒ String
Encode an arbitrary hash as wire-format bytes.
-
.encode_advance_frame(timestamp, format = :msgpack) ⇒ String
Animation.
-
.encode_binary(data, format) ⇒ String
Encode binary data for the wire format.
-
.encode_binary_field(payload, key, format) ⇒ Hash
Encode a binary field in a payload hash if present.
-
.encode_command(id, family, value = nil, format = :msgpack) ⇒ String
Widget-targeted commands (unified wire format).
-
.encode_commands(commands, format = :msgpack) ⇒ String
Send multiple widget-targeted commands in a single message.
-
.encode_effect(id, kind, payload, format = :msgpack) ⇒ String
Effects.
-
.encode_image_op(op, payload, format = :msgpack) ⇒ String
Image operations.
-
.encode_interact(id, action, selector = nil, payload = {}, format = :msgpack) ⇒ String
Interactions.
-
.encode_load_font(family, data, format = :msgpack) ⇒ String
Font load (typed top-level message; carries raw TTF/OTF bytes).
-
.encode_patch(ops, format = :msgpack) ⇒ String
Incrementally patch the existing tree.
-
.encode_query(id, target, selector = {}, format = :msgpack) ⇒ String
Queries.
-
.encode_register_effect_stub(kind, response, format = :msgpack) ⇒ String
Register an effect stub with the renderer.
-
.encode_reset(id, format = :msgpack) ⇒ String
Session management.
-
.encode_screenshot(id, name, width = 1024, height = 768, format = :msgpack) ⇒ String
Capture rendered pixels.
-
.encode_settings(settings, format = :msgpack) ⇒ String
Settings.
-
.encode_snapshot(tree, format = :msgpack) ⇒ String
Tree updates.
-
.encode_subscribe(kind, tag, format = :msgpack, max_rate: nil, window_id: nil) ⇒ String
Subscriptions.
-
.encode_system_op(op, payload, format = :msgpack) ⇒ String
Send a system-level operation not tied to a specific window.
-
.encode_system_query(op, payload, format = :msgpack) ⇒ String
Send a system-level query.
-
.encode_tree_hash(id, name, format = :msgpack) ⇒ String
Structural testing.
-
.encode_unregister_effect_stub(kind, format = :msgpack) ⇒ String
Remove a previously registered effect stub.
-
.encode_unsubscribe(kind, tag: nil, format: :msgpack) ⇒ String
Unsubscribe from an event category.
-
.encode_widget_op(op, payload, format = :msgpack) ⇒ String
Widget operations.
-
.encode_window_op(op, window_id, payload, format = :msgpack) ⇒ String
Window operations.
-
.normalize_default_font(settings) ⇒ Object
private
The renderer reads
default_fontstrictly as an object with at least afamilykey; a bare string is silently dropped and the renderer falls back to the platform default. -
.stringify_keys(obj) ⇒ Object
Helpers.
Class Method Details
.encode(map, format = :msgpack) ⇒ String
Encode an arbitrary hash as wire-format bytes.
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/plushie/protocol/encode.rb', line 23 def encode(map, format = :msgpack) case format when :json JSON.generate(stringify_keys(map)) + "\n" when :msgpack require "msgpack" MessagePack.pack(stringify_keys(map)) else raise ArgumentError, "unknown format: #{format.inspect}" end end |
.encode_advance_frame(timestamp, format = :msgpack) ⇒ String
Animation
385 386 387 |
# File 'lib/plushie/protocol/encode.rb', line 385 def encode_advance_frame(, format = :msgpack) encode({type: "advance_frame", session: "", timestamp: }, format) end |
.encode_binary(data, format) ⇒ String
Encode binary data for the wire format. JSON: base64-encoded string. MessagePack: raw binary pass-through.
439 440 441 442 443 444 |
# File 'lib/plushie/protocol/encode.rb', line 439 def encode_binary(data, format) case format when :json then Base64.strict_encode64(data) when :msgpack then data end end |
.encode_binary_field(payload, key, format) ⇒ Hash
Encode a binary field in a payload hash if present. Returns a new hash with the field encoded for the wire format, or the original hash if the field is absent or nil.
454 455 456 457 |
# File 'lib/plushie/protocol/encode.rb', line 454 def encode_binary_field(payload, key, format) return payload unless payload.is_a?(Hash) && payload.key?(key) && payload[key].is_a?(String) payload.merge(key => encode_binary(payload[key], format)) end |
.encode_command(id, family, value = nil, format = :msgpack) ⇒ String
Widget-targeted commands (unified wire format)
274 275 276 277 278 279 |
# File 'lib/plushie/protocol/encode.rb', line 274 def encode_command(id, family, value = nil, format = :msgpack) encode({ type: "command", session: "", id: id, family: family.to_s, value: value }, format) end |
.encode_commands(commands, format = :msgpack) ⇒ String
Send multiple widget-targeted commands in a single message.
286 287 288 289 290 291 292 293 |
# File 'lib/plushie/protocol/encode.rb', line 286 def encode_commands(commands, format = :msgpack) encode({ type: "commands", session: "", commands: commands.map { |c| {id: c[:id], family: c[:family].to_s, value: c[:value]} } }, format) end |
.encode_effect(id, kind, payload, format = :msgpack) ⇒ String
Effects
214 215 216 217 218 219 |
# File 'lib/plushie/protocol/encode.rb', line 214 def encode_effect(id, kind, payload, format = :msgpack) encode({ type: "effect", session: "", id: id, kind: kind.to_s, payload: payload }, format) end |
.encode_image_op(op, payload, format = :msgpack) ⇒ String
Image operations
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/plushie/protocol/encode.rb', line 242 def encode_image_op(op, payload, format = :msgpack) op_payload = {} op_payload[:handle] = payload[:handle] if payload[:handle] op_payload[:tag] = payload[:tag].to_s if payload[:tag] if payload[:data] op_payload[:data] = encode_binary(payload[:data], format) end if payload[:pixels] op_payload[:pixels] = encode_binary(payload[:pixels], format) op_payload[:width] = payload[:width] op_payload[:height] = payload[:height] end encode({type: "image_op", session: "", op: op.to_s, payload: op_payload}, format) end |
.encode_interact(id, action, selector = nil, payload = {}, format = :msgpack) ⇒ String
Interactions
325 326 327 328 329 330 331 332 |
# File 'lib/plushie/protocol/encode.rb', line 325 def encode_interact(id, action, selector = nil, payload = {}, format = :msgpack) msg = { type: "interact", session: "", id: id, action: action.to_s, payload: payload } msg[:selector] = selector if selector encode(msg, format) end |
.encode_load_font(family, data, format = :msgpack) ⇒ String
Font load (typed top-level message; carries raw TTF/OTF bytes)
147 148 149 150 |
# File 'lib/plushie/protocol/encode.rb', line 147 def encode_load_font(family, data, format = :msgpack) payload = encode_binary_field({family: family, data: data}, :data, format) encode({type: "load_font", session: "", payload: payload}, format) end |
.encode_patch(ops, format = :msgpack) ⇒ String
Incrementally patch the existing tree.
89 90 91 |
# File 'lib/plushie/protocol/encode.rb', line 89 def encode_patch(ops, format = :msgpack) encode({type: "patch", session: "", ops: ops}, format) end |
.encode_query(id, target, selector = {}, format = :msgpack) ⇒ String
Queries
306 307 308 309 310 311 |
# File 'lib/plushie/protocol/encode.rb', line 306 def encode_query(id, target, selector = {}, format = :msgpack) encode({ type: "query", session: "", id: id, target: target, selector: selector }, format) end |
.encode_register_effect_stub(kind, response, format = :msgpack) ⇒ String
Register an effect stub with the renderer. The renderer will return the given response immediately for any effect of the given kind, without executing the real effect.
401 402 403 |
# File 'lib/plushie/protocol/encode.rb', line 401 def encode_register_effect_stub(kind, response, format = :msgpack) encode({type: "register_effect_stub", session: "", kind: kind.to_s, response: response}, format) end |
.encode_reset(id, format = :msgpack) ⇒ String
Session management
372 373 374 |
# File 'lib/plushie/protocol/encode.rb', line 372 def encode_reset(id, format = :msgpack) encode({type: "reset", session: "", id: id}, format) end |
.encode_screenshot(id, name, width = 1024, height = 768, format = :msgpack) ⇒ String
Capture rendered pixels.
356 357 358 359 360 361 |
# File 'lib/plushie/protocol/encode.rb', line 356 def encode_screenshot(id, name, width = 1024, height = 768, format = :msgpack) encode({ type: "screenshot", session: "", id: id, name: name, width: width, height: height }, format) end |
.encode_settings(settings, format = :msgpack) ⇒ String
Settings
49 50 51 52 53 |
# File 'lib/plushie/protocol/encode.rb', line 49 def encode_settings(settings, format = :msgpack) merged = {protocol_version: Protocol::PROTOCOL_VERSION}.merge(settings) merged = normalize_default_font(merged) encode({type: "settings", session: "", settings: merged}, format) end |
.encode_snapshot(tree, format = :msgpack) ⇒ String
Tree updates
80 81 82 |
# File 'lib/plushie/protocol/encode.rb', line 80 def encode_snapshot(tree, format = :msgpack) encode({type: "snapshot", session: "", tree: tree}, format) end |
.encode_subscribe(kind, tag, format = :msgpack, max_rate: nil, window_id: nil) ⇒ String
Subscriptions
104 105 106 107 108 109 |
# File 'lib/plushie/protocol/encode.rb', line 104 def encode_subscribe(kind, tag, format = :msgpack, max_rate: nil, window_id: nil) msg = {type: "subscribe", session: "", kind: kind.to_s, tag: tag.to_s} msg[:max_rate] = max_rate if max_rate msg[:window_id] = window_id if window_id encode(msg, format) end |
.encode_system_op(op, payload, format = :msgpack) ⇒ String
Send a system-level operation not tied to a specific window.
Uses the unified _op envelope: op-specific data lives under payload.
181 182 183 184 185 186 |
# File 'lib/plushie/protocol/encode.rb', line 181 def encode_system_op(op, payload, format = :msgpack) encode({ type: "system_op", session: "", op: op.to_s, payload: payload }, format) end |
.encode_system_query(op, payload, format = :msgpack) ⇒ String
Send a system-level query.
Uses the unified _op envelope: query-specific data lives under payload.
196 197 198 199 200 201 |
# File 'lib/plushie/protocol/encode.rb', line 196 def encode_system_query(op, payload, format = :msgpack) encode({ type: "system_query", session: "", op: op.to_s, payload: payload }, format) end |
.encode_tree_hash(id, name, format = :msgpack) ⇒ String
Structural testing
344 345 346 |
# File 'lib/plushie/protocol/encode.rb', line 344 def encode_tree_hash(id, name, format = :msgpack) encode({type: "tree_hash", session: "", id: id, name: name}, format) end |
.encode_unregister_effect_stub(kind, format = :msgpack) ⇒ String
Remove a previously registered effect stub.
410 411 412 |
# File 'lib/plushie/protocol/encode.rb', line 410 def encode_unregister_effect_stub(kind, format = :msgpack) encode({type: "unregister_effect_stub", session: "", kind: kind.to_s}, format) end |
.encode_unsubscribe(kind, tag: nil, format: :msgpack) ⇒ String
Unsubscribe from an event category.
117 118 119 120 121 |
# File 'lib/plushie/protocol/encode.rb', line 117 def encode_unsubscribe(kind, tag: nil, format: :msgpack) msg = {type: "unsubscribe", session: "", kind: kind.to_s} msg[:tag] = tag.to_s if tag encode(msg, format) end |
.encode_widget_op(op, payload, format = :msgpack) ⇒ String
Widget operations
133 134 135 |
# File 'lib/plushie/protocol/encode.rb', line 133 def (op, payload, format = :msgpack) encode({type: "widget_op", session: "", op: op.to_s, payload: payload}, format) end |
.encode_window_op(op, window_id, payload, format = :msgpack) ⇒ String
Window operations
166 167 168 169 170 171 |
# File 'lib/plushie/protocol/encode.rb', line 166 def encode_window_op(op, window_id, payload, format = :msgpack) encode({ type: "window_op", session: "", op: op.to_s, window_id: window_id, payload: payload }, format) end |
.normalize_default_font(settings) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The renderer reads default_font strictly as an object with
at least a family key; a bare string is silently dropped and
the renderer falls back to the platform default. The Font
encoder returns a string for the :default and :monospace
shorthands but a hash for everything else, so wrap any string
result back into the canonical {family: ...} shape.
63 64 65 66 67 68 69 |
# File 'lib/plushie/protocol/encode.rb', line 63 def normalize_default_font(settings) return settings unless settings.key?(:default_font) encoded = Type::Font.encode(settings[:default_font]) encoded = {family: encoded} if encoded.is_a?(String) settings.merge(default_font: encoded) end |
.stringify_keys(obj) ⇒ Object
Helpers
422 423 424 425 426 427 428 429 430 431 |
# File 'lib/plushie/protocol/encode.rb', line 422 def stringify_keys(obj) case obj when Hash obj.each_with_object({}) { |(k, v), h| h[k.to_s] = stringify_keys(v) } when Array obj.map { |v| stringify_keys(v) } else obj end end |