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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +94 -0
- data/README.md +140 -32
- data/lib/asterism/cruby/credentials.rb +152 -0
- data/lib/asterism/cruby/objects.rb +19 -6
- data/lib/asterism/cruby/ros.rb +1 -1
- data/lib/asterism/cruby/zenoh.rb +13 -2
- data/lib/asterism/cruby.rb +51 -7
- data/lib/asterism/version.rb +4 -3
- data/lib/asterism.rb +1 -1
- data/mrblib/asterism.rb +248 -62
- data/mrblib/future.rb +11 -5
- data/mrblib/profile.rb +17 -4
- data/mrblib/proxy.rb +23 -5
- metadata +11 -4
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
|
-
|
|
54
|
-
|
|
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::
|
|
57
|
-
raw[
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
7
|
-
# asterism_refresh, remote_methods, respond_to?, methods,
|
|
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:
|
|
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
|
-
|
|
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.
|
|
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-
|
|
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
|
|
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
|
|
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
|