Skip to content

Commit d90996a

Browse files
committed
Add some missing methods from rcl (#1106)
This PR adds missing methods to count publishers, subscriptions, clients, and services in rclnodejs, along with corresponding tests and binding implementations. - New tests have been implemented to verify the newly added methods. - Binding functions in C++ for subscriptions, publishers, nodes, and contexts have been extended. | File | Description | | ----------------------------------- | ---------------------------------------------------- | | test/test-subscription.js | Added test to verify publisher count on a subscription. | | test/test-publisher.js | Added test to verify subscription count on a publisher. | | test/test-node.js | Added tests for counting clients and services on a node. | | test/test-context.js | Added test to verify the context's domain ID. | | src/rcl_subscription_bindings.cpp | Added GetPublisherCount binding. | | src/rcl_publisher_bindings.cpp | Added GetSubscriptionCount binding. | | src/rcl_node_bindings.cpp | Added countPublishers, countSubscribers, countClients, and countServices bindings. | | src/rcl_graph_bindings.cpp | Removed redundant count functions. | | src/rcl_context_bindings.cpp | Added GetDomainId binding. | | lib/subscription.js | Added publisherCount getter. | | lib/publisher.js | Added subscriptionCount getter. | | lib/node.js | Added countClients and countServices methods. | | lib/context.js | Added domainId getter. | Fix: #1107
1 parent dbf1ada commit d90996a

13 files changed

+225
-32
lines changed

lib/context.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ class Context {
219219
}
220220
return defaultContext;
221221
}
222+
223+
/**
224+
* Get the domain ID of this context.
225+
* @returns {Number} domain ID of this context
226+
*/
227+
get domainId() {
228+
return rclnodejs.getDomainId(this.handle);
229+
}
222230
}
223231

224232
Context._instances = [];

lib/node.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,24 @@ class Node extends rclnodejs.ShadowNode {
10611061
return rclnodejs.countSubscribers(this.handle, expandedTopic);
10621062
}
10631063

1064+
/**
1065+
* Get the number of clients on a given service name.
1066+
* @param {string} serviceName - the service name
1067+
* @returns {Number}
1068+
*/
1069+
countClients(serviceName) {
1070+
return rclnodejs.countClients(this.handle, serviceName);
1071+
}
1072+
1073+
/**
1074+
* Get the number of services on a given service name.
1075+
* @param {string} serviceName - the service name
1076+
* @returns {Number}
1077+
*/
1078+
countServices(serviceName) {
1079+
return rclnodejs.countServices(this.handle, serviceName);
1080+
}
1081+
10641082
/**
10651083
* Get the list of parameter-overrides found on the commandline and
10661084
* in the NodeOptions.parameter_overrides property.

lib/publisher.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ class Publisher extends Entity {
7272
);
7373
return new Publisher(handle, typeClass, topic, options);
7474
}
75+
76+
/**
77+
* Get the number of subscriptions to this publisher.
78+
* @returns {number} The number of subscriptions
79+
*/
80+
get subscriptionCount() {
81+
return rclnodejs.getSubscriptionCount(this._handle);
82+
}
7583
}
7684

7785
module.exports = Publisher;

lib/subscription.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ class Subscription extends Entity {
116116
? rclnodejs.clearContentFilter(this.handle)
117117
: true;
118118
}
119+
120+
/**
121+
* Get the number of publishers to this subscription.
122+
* @returns {number} The number of publishers
123+
*/
124+
get publisherCount() {
125+
return rclnodejs.getPublisherCount(this._handle);
126+
}
119127
}
120128

121129
module.exports = Subscription;

src/rcl_context_bindings.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,29 @@ Napi::Value IsContextValid(const Napi::CallbackInfo& info) {
127127
return Napi::Boolean::New(env, is_valid);
128128
}
129129

130+
Napi::Value GetDomainId(const Napi::CallbackInfo& info) {
131+
Napi::Env env = info.Env();
132+
133+
RclHandle* context_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
134+
rcl_context_t* context =
135+
reinterpret_cast<rcl_context_t*>(context_handle->ptr());
136+
size_t domain_id;
137+
rcl_ret_t ret = rcl_context_get_domain_id(context, &domain_id);
138+
if (RCL_RET_OK != ret) {
139+
Napi::Error::New(env, rcl_get_error_string().str)
140+
.ThrowAsJavaScriptException();
141+
return env.Undefined();
142+
}
143+
144+
return Napi::Number::New(env, domain_id);
145+
}
146+
130147
Napi::Object InitContextBindings(Napi::Env env, Napi::Object exports) {
131148
exports.Set("init", Napi::Function::New(env, Init));
132149
exports.Set("shutdown", Napi::Function::New(env, Shutdown));
133150
exports.Set("createContext", Napi::Function::New(env, CreateContext));
134151
exports.Set("isContextValid", Napi::Function::New(env, IsContextValid));
152+
exports.Set("getDomainId", Napi::Function::New(env, GetDomainId));
135153
return exports;
136154
}
137155

src/rcl_graph_bindings.cpp

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -232,36 +232,6 @@ Napi::Value GetNodeNames(const Napi::CallbackInfo& info) {
232232
return result_list;
233233
}
234234

235-
Napi::Value CountPublishers(const Napi::CallbackInfo& info) {
236-
Napi::Env env = info.Env();
237-
238-
RclHandle* node_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
239-
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
240-
std::string topic_name = info[1].As<Napi::String>().Utf8Value();
241-
242-
size_t count = 0;
243-
THROW_ERROR_IF_NOT_EQUAL(
244-
RCL_RET_OK, rcl_count_publishers(node, topic_name.c_str(), &count),
245-
"Failed to count publishers.");
246-
247-
return Napi::Number::New(env, static_cast<int32_t>(count));
248-
}
249-
250-
Napi::Value CountSubscribers(const Napi::CallbackInfo& info) {
251-
Napi::Env env = info.Env();
252-
253-
RclHandle* node_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
254-
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
255-
std::string topic_name = info[1].As<Napi::String>().Utf8Value();
256-
257-
size_t count = 0;
258-
THROW_ERROR_IF_NOT_EQUAL(
259-
RCL_RET_OK, rcl_count_subscribers(node, topic_name.c_str(), &count),
260-
"Failed to count subscribers.");
261-
262-
return Napi::Number::New(env, static_cast<int32_t>(count));
263-
}
264-
265235
Napi::Value ServiceServerIsAvailable(const Napi::CallbackInfo& info) {
266236
Napi::Env env = info.Env();
267237

@@ -292,8 +262,6 @@ Napi::Object InitGraphBindings(Napi::Env env, Napi::Object exports) {
292262
exports.Set("getServiceNamesAndTypes",
293263
Napi::Function::New(env, GetServiceNamesAndTypes));
294264
exports.Set("getNodeNames", Napi::Function::New(env, GetNodeNames));
295-
exports.Set("countPublishers", Napi::Function::New(env, CountPublishers));
296-
exports.Set("countSubscribers", Napi::Function::New(env, CountSubscribers));
297265
exports.Set("serviceServerIsAvailable",
298266
Napi::Function::New(env, ServiceServerIsAvailable));
299267
return exports;

src/rcl_node_bindings.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,66 @@ Napi::Value ActionGetNamesAndTypes(const Napi::CallbackInfo& info) {
318318
return result_list;
319319
}
320320

321+
Napi::Value CountPublishers(const Napi::CallbackInfo& info) {
322+
Napi::Env env = info.Env();
323+
324+
RclHandle* node_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
325+
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
326+
std::string topic_name = info[1].As<Napi::String>().Utf8Value();
327+
328+
size_t count = 0;
329+
THROW_ERROR_IF_NOT_EQUAL(
330+
RCL_RET_OK, rcl_count_publishers(node, topic_name.c_str(), &count),
331+
"Failed to count publishers.");
332+
333+
return Napi::Number::New(env, static_cast<int32_t>(count));
334+
}
335+
336+
Napi::Value CountSubscribers(const Napi::CallbackInfo& info) {
337+
Napi::Env env = info.Env();
338+
339+
RclHandle* node_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
340+
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
341+
std::string topic_name = info[1].As<Napi::String>().Utf8Value();
342+
343+
size_t count = 0;
344+
THROW_ERROR_IF_NOT_EQUAL(
345+
RCL_RET_OK, rcl_count_subscribers(node, topic_name.c_str(), &count),
346+
"Failed to count subscribers.");
347+
348+
return Napi::Number::New(env, static_cast<int32_t>(count));
349+
}
350+
351+
Napi::Value CountClients(const Napi::CallbackInfo& info) {
352+
Napi::Env env = info.Env();
353+
354+
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(
355+
RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
356+
std::string service_name = info[1].As<Napi::String>().Utf8Value();
357+
358+
size_t count = 0;
359+
THROW_ERROR_IF_NOT_EQUAL(
360+
rcl_count_clients(node, service_name.c_str(), &count), RCL_RET_OK,
361+
rcl_get_error_string().str);
362+
363+
return Napi::Number::New(env, count);
364+
}
365+
366+
Napi::Value CountServices(const Napi::CallbackInfo& info) {
367+
Napi::Env env = info.Env();
368+
369+
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(
370+
RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
371+
std::string service_name = info[1].As<Napi::String>().Utf8Value();
372+
373+
size_t count = 0;
374+
THROW_ERROR_IF_NOT_EQUAL(
375+
rcl_count_services(node, service_name.c_str(), &count), RCL_RET_OK,
376+
rcl_get_error_string().str);
377+
378+
return Napi::Number::New(env, count);
379+
}
380+
321381
Napi::Object InitNodeBindings(Napi::Env env, Napi::Object exports) {
322382
exports.Set("getParameterOverrides",
323383
Napi::Function::New(env, GetParameterOverrides));
@@ -331,6 +391,10 @@ Napi::Object InitNodeBindings(Napi::Env env, Napi::Object exports) {
331391
Napi::Function::New(env, ActionGetServerNamesAndTypesByNode));
332392
exports.Set("actionGetNamesAndTypes",
333393
Napi::Function::New(env, ActionGetNamesAndTypes));
394+
exports.Set("countPublishers", Napi::Function::New(env, CountPublishers));
395+
exports.Set("countSubscribers", Napi::Function::New(env, CountSubscribers));
396+
exports.Set("countClients", Napi::Function::New(env, CountClients));
397+
exports.Set("countServices", Napi::Function::New(env, CountServices));
334398
return exports;
335399
}
336400

src/rcl_publisher_bindings.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,27 @@ Napi::Value PublishRawMessage(const Napi::CallbackInfo& info) {
114114
return env.Undefined();
115115
}
116116

117+
Napi::Value GetSubscriptionCount(const Napi::CallbackInfo& info) {
118+
Napi::Env env = info.Env();
119+
120+
rcl_publisher_t* publisher = reinterpret_cast<rcl_publisher_t*>(
121+
RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
122+
123+
size_t count = 0;
124+
THROW_ERROR_IF_NOT_EQUAL(
125+
rcl_publisher_get_subscription_count(publisher, &count), RCL_RET_OK,
126+
rcl_get_error_string().str);
127+
128+
return Napi::Number::New(env, count);
129+
}
130+
117131
Napi::Object InitPublisherBindings(Napi::Env env, Napi::Object exports) {
118132
exports.Set("createPublisher", Napi::Function::New(env, CreatePublisher));
119133
exports.Set("publish", Napi::Function::New(env, Publish));
120134
exports.Set("getPublisherTopic", Napi::Function::New(env, GetPublisherTopic));
121135
exports.Set("publishRawMessage", Napi::Function::New(env, PublishRawMessage));
136+
exports.Set("getSubscriptionCount",
137+
Napi::Function::New(env, GetSubscriptionCount));
122138
return exports;
123139
}
124140

src/rcl_subscription_bindings.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,20 @@ Napi::Value ClearContentFilter(const Napi::CallbackInfo& info) {
303303
#endif
304304
}
305305

306+
Napi::Value GetPublisherCount(const Napi::CallbackInfo& info) {
307+
Napi::Env env = info.Env();
308+
309+
rcl_subscription_t* subscription = reinterpret_cast<rcl_subscription_t*>(
310+
RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
311+
312+
size_t count = 0;
313+
THROW_ERROR_IF_NOT_EQUAL(
314+
rcl_subscription_get_publisher_count(subscription, &count), RCL_RET_OK,
315+
rcl_get_error_string().str);
316+
317+
return Napi::Number::New(env, count);
318+
}
319+
306320
Napi::Object InitSubscriptionBindings(Napi::Env env, Napi::Object exports) {
307321
exports.Set("rclTake", Napi::Function::New(env, RclTake));
308322
exports.Set("createSubscription",
@@ -314,6 +328,7 @@ Napi::Object InitSubscriptionBindings(Napi::Env env, Napi::Object exports) {
314328
exports.Set("setContentFilter", Napi::Function::New(env, SetContentFilter));
315329
exports.Set("clearContentFilter",
316330
Napi::Function::New(env, ClearContentFilter));
331+
exports.Set("getPublisherCount", Napi::Function::New(env, GetPublisherCount));
317332
return exports;
318333
}
319334

test/test-context.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,10 @@ describe('context test suite', function () {
8080
context.shutdown();
8181
assert.strictEqual(context.nodes.length, 0);
8282
});
83+
84+
it('context number id', async function () {
85+
let context = new rclnodejs.Context();
86+
await rclnodejs.init(context);
87+
assert.strictEqual(typeof context.domainId, 'number');
88+
});
8389
});

0 commit comments

Comments
 (0)