asterism 0.6.0 → 0.7.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.
data/mrblib/future.rb CHANGED
@@ -48,16 +48,22 @@ module Asterism
48
48
  @finished
49
49
  end
50
50
 
51
+ # The answer: {"value" => v} gives v, {"error" => {"kind", "class",
52
+ # "message"}} raises RemoteError; anything else is a malformed answer.
51
53
  def value
52
54
  raw = raw_value
53
- unless raw.is_a?(Array) && (raw[0] == "ok" || raw[0] == "error")
54
- raise ::Asterism::Error, "malformed answer from #{@path}"
55
+ raise ::Asterism::Error, "malformed answer from #{@path}" unless raw.is_a?(Hash)
56
+ if raw.key?("error")
57
+ e = raw["error"]
58
+ raise ::Asterism::Error, "malformed answer from #{@path}" unless e.is_a?(Hash)
59
+ kind = e["kind"]
60
+ raise ::Asterism::RemoteError.new(e["class"], e["message"], kind.is_a?(String) ? kind : nil)
55
61
  end
56
- raise ::Asterism::RemoteError.new(raw[1], raw[2]) if raw[0] == "error"
57
- raw[1]
62
+ raise ::Asterism::Error, "malformed answer from #{@path}" unless raw.key?("value")
63
+ raw["value"]
58
64
  end
59
65
 
60
- # The decoded answer (meta replies are not ["ok", value] pairs).
66
+ # The decoded answer (meta and profile replies are not value maps).
61
67
  def raw_value
62
68
  ::Asterism.wait_until { done? } unless done?
63
69
  if @reply.nil?
data/mrblib/profile.rb CHANGED
@@ -7,11 +7,14 @@
7
7
  #
8
8
  # Key: asterism/<node>/@profile (a queryable of every application connected
9
9
  # as that node). The reply is a MessagePack Hash:
10
+ # "protocol" the wire protocol the node speaks (Asterism::PROTOCOL, 1);
11
+ # a node without it speaks protocol 0
10
12
  # "kind" what Ruby runs the node: "family_mruby", "picoruby",
11
13
  # "cruby", "console" (others are allowed)
12
14
  # "host" where it runs, optional ("atoms3r", "tab5", "sim", ...)
13
15
  # "name" a display name, optional
14
- # "icon" PNG bytes, optional (8 KB and 256x256 at most)
16
+ # "icon" PNG bytes as a MessagePack bin, optional (8 KB and
17
+ # 256x256 at most)
15
18
  # "icon_hash" the icon's summary (Profile.png_info): a reader that has
16
19
  # that icon already asks again with the parameter icon=0 and
17
20
  # gets the rest without it
@@ -87,6 +90,13 @@ module Asterism
87
90
  nil
88
91
  end
89
92
 
93
+ # The bytes as a binary String (String#b), so that they are sent as a
94
+ # MessagePack bin; as they are where String#b is missing.
95
+ # @api private
96
+ def self.binary(s)
97
+ s.respond_to?(:b) ? s.b : s
98
+ end
99
+
90
100
  # @api private
91
101
  def self.type?(b, pos, c0, c1, c2, c3)
92
102
  b.getbyte(pos + 4) == c0 && b.getbyte(pos + 5) == c1 && b.getbyte(pos + 6) == c2 && b.getbyte(pos + 7) == c3
@@ -107,6 +117,8 @@ module Asterism
107
117
  kind = h["kind"]
108
118
  return nil unless kind.is_a?(String) && kind?(kind)
109
119
  out = { "kind" => kind }
120
+ pr = h["protocol"]
121
+ out["protocol"] = pr if pr.is_a?(Integer) && pr >= 0
110
122
  host = h["host"]
111
123
  out["host"] = host if host.is_a?(String) && !host.empty? && host.bytesize <= HOST_MAX
112
124
  name = h["name"]
@@ -270,7 +282,7 @@ module Asterism
270
282
  begin
271
283
  g = session!.get("#{ROOT}/#{path}", timeout_ms: ms, params: icon ? nil : "icon=0")
272
284
  rescue Asterism::Zenoh::Error => e
273
- lost(e.message)
285
+ lost_if_closed(e.message)
274
286
  raise Disconnected, e.message
275
287
  end
276
288
  Future.new(path, "profile", g, now_ms + ms, ms)
@@ -301,7 +313,7 @@ module Asterism
301
313
  # @api private
302
314
  def self.profile_hash(with_icon)
303
315
  set = @profile_set || {}
304
- h = { "kind" => set["kind"] || default_profile_kind }
316
+ h = { "protocol" => PROTOCOL, "kind" => set["kind"] || default_profile_kind }
305
317
  h["host"] = set["host"] if set["host"]
306
318
  h["name"] = set["name"] if set["name"]
307
319
  icon = profile_icon
@@ -324,7 +336,8 @@ module Asterism
324
336
  bytes = path ? read_icon_file(path) : nil
325
337
  end
326
338
  info = bytes ? Profile.png_info(bytes) : nil
327
- @profile_icon = info ? [bytes, info[2]] : false
339
+ # A binary String: it goes as a MessagePack bin.
340
+ @profile_icon = info ? [Profile.binary(bytes), info[2]] : false
328
341
  end
329
342
  @profile_icon ? @profile_icon : nil
330
343
  end
data/mrblib/proxy.rb CHANGED
@@ -3,9 +3,9 @@ module Asterism
3
3
  # Any method it does not have itself becomes a call that waits for the
4
4
  # answer. respond_to? and remote_methods come from the object's meta.
5
5
  #
6
- # Its own methods (not forwarded): async, asterism_path, asterism_meta,
7
- # asterism_refresh, remote_methods, respond_to?, methods, inspect, to_s
8
- # and those of Object.
6
+ # Its own methods (not forwarded): async, asterism_call, asterism_path,
7
+ # asterism_meta, asterism_refresh, remote_methods, respond_to?, methods,
8
+ # inspect, to_s and those of Object.
9
9
  class Proxy
10
10
  # Conversions Ruby asks for implicitly (puts, Array#flatten, ...): never
11
11
  # forwarded.
@@ -27,6 +27,15 @@ module Asterism
27
27
  ::Asterism.call(@path, name, args, kw, @timeout_ms)
28
28
  end
29
29
 
30
+ # Calls the remote method by its name (a String or Symbol): for the
31
+ # names the proxy cannot forward (those Object and Kernel define:
32
+ # display, hash, class, fail, ...) and for names that are not Ruby
33
+ # identifiers (from objects written in other languages).
34
+ def asterism_call(name, *args, **kw, &blk)
35
+ raise ::ArgumentError, "a block cannot be sent to #{@path}" if blk
36
+ ::Asterism.call(@path, name.to_s, args, kw, @timeout_ms)
37
+ end
38
+
30
39
  # In Ruby rather than through respond_to_missing?: Object#respond_to? is
31
40
  # C, and calling back into Ruby from it (which then waits for the meta)
32
41
  # costs another interpreter entry on the C stack.
@@ -52,7 +61,8 @@ module Asterism
52
61
  remote_methods
53
62
  end
54
63
 
55
- # The meta reply, fetched once: {"methods" => [[name, arity], ...]}.
64
+ # The meta reply, fetched once:
65
+ # {"methods" => [{"name" => name, "arity" => n}, ...]}.
56
66
  def asterism_meta
57
67
  @meta ||= ::Asterism.meta(@path, @timeout_ms)
58
68
  end
@@ -67,7 +77,9 @@ module Asterism
67
77
  def remote_names
68
78
  list = asterism_meta["methods"]
69
79
  return [] unless list.is_a?(Array)
70
- list.map { |pair| pair.is_a?(Array) ? pair[0].to_s : pair.to_s }
80
+ names = []
81
+ list.each { |m| names << m["name"].to_s if m.is_a?(Hash) && m["name"].is_a?(String) }
82
+ names
71
83
  end
72
84
 
73
85
  # The same object, calls that do not wait: each returns a Future.
@@ -100,6 +112,12 @@ module Asterism
100
112
  !::Asterism::Proxy::LOCAL_ONLY.include?(name.to_sym)
101
113
  end
102
114
 
115
+ # Proxy#asterism_call that does not wait: returns a Future.
116
+ def asterism_call(name, *args, **kw, &blk)
117
+ raise ::ArgumentError, "a block cannot be sent to #{@path}" if blk
118
+ ::Asterism.call_async(@path, name.to_s, args, kw, @timeout_ms)
119
+ end
120
+
103
121
  def inspect
104
122
  "#<Asterism::AsyncProxy #{@path}>"
105
123
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asterism
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katsuhiko Kageyama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-12 00:00:00.000000000 Z
11
+ date: 2026-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asterism-zenoh
@@ -16,14 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.4.0
19
+ version: '0.4'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.4.1
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
- version: 0.4.0
29
+ version: '0.4'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.4.1
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: msgpack
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -140,6 +146,7 @@ files:
140
146
  - data/msgs/visualization_msgs/msg/UVCoordinate.rb
141
147
  - lib/asterism.rb
142
148
  - lib/asterism/cruby.rb
149
+ - lib/asterism/cruby/credentials.rb
143
150
  - lib/asterism/cruby/objects.rb
144
151
  - lib/asterism/cruby/ros.rb
145
152
  - lib/asterism/cruby/runner.rb