Skip to content

Commit 860673b

Browse files
author
Minggang Wang
committed
Add node graph API
Fix #438
1 parent d921071 commit 860673b

File tree

2 files changed

+208
-0
lines changed

2 files changed

+208
-0
lines changed

lib/node.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,55 @@ class Node {
405405
namespace() {
406406
return rclnodejs.getNamespace(this.handle);
407407
}
408+
409+
/**
410+
* Get the list of published topics discovered by the provided node for the remote node name.
411+
* @param {string} nodeName - The name of the node.
412+
* @param {string} namespace - The name of the namespace.
413+
* @param {boolean} noDemangle - If true topic names and types returned will not be demangled, default: false.
414+
* @return {array} - An array of the names and types.
415+
*/
416+
getPublisherNamesAndTypesByNode(nodeName, namespace, noDemangle = false) {
417+
return rclnodejs.getPublisherNamesAndTypesByNode(this.handle, nodeName, namespace, noDemangle);
418+
}
419+
420+
/**
421+
* Get the list of published topics discovered by the provided node for the remote node name.
422+
* @param {string} nodeName - The name of the node.
423+
* @param {string} namespace - The name of the namespace.
424+
* @param {boolean} noDemangle - If true topic names and types returned will not be demangled, default: false.
425+
* @return {array} - An array of the names and types.
426+
*/
427+
getSubscriptionNamesAndTypesByNode(nodeName, namespace, noDemangle = false) {
428+
return rclnodejs.getSubscriptionNamesAndTypesByNode(this.handle, nodeName, namespace, noDemangle);
429+
}
430+
431+
/**
432+
* Get the list of service topics discovered by the provided node for the remote node name.
433+
* @param {string} nodeName - The name of the node.
434+
* @param {string} namespace - The name of the namespace.
435+
* @return {array} - An array of the names and types.
436+
*/
437+
getServiceNamesAndTypesByNode(nodeName, namespace) {
438+
return rclnodejs.getServiceNamesAndTypesByNode(this.handle, nodeName, namespace);
439+
}
440+
441+
/**
442+
* Get the list of topics discovered by the provided node.
443+
* @param {boolean} noDemangle - If true topic names and types returned will not be demangled, default: false.
444+
* @return {array} - An array of the names and types.
445+
*/
446+
getTopicNamesAndTypes(noDemangle = false) {
447+
return rclnodejs.getTopicNamesAndTypes(this.handle, noDemangle);
448+
}
449+
450+
/**
451+
* Get the list of services discovered by the provided node.
452+
* @return {array} - An array of the names and types.
453+
*/
454+
getServiceNamesAndTypes() {
455+
return rclnodejs.getServiceNamesAndTypes(this.handle);
456+
}
408457
}
409458

410459
module.exports = Node;

src/rcl_bindings.cpp

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <rcl/error_handling.h>
1818
#include <rcl/expand_topic_name.h>
19+
#include <rcl/graph.h>
1920
#include <rcl/node.h>
2021
#include <rcl/rcl.h>
2122
#include <rcl/validate_topic_name.h>
@@ -1051,6 +1052,159 @@ NAN_METHOD(IsContextValid) {
10511052
info.GetReturnValue().Set(Nan::New(is_valid));
10521053
}
10531054

1055+
void ExtractNamesAndTypes(rcl_names_and_types_t names_and_types,
1056+
v8::Local<v8::Array>* result_list) {
1057+
for (int i = 0; i < names_and_types.names.size; ++i) {
1058+
auto item = v8::Object::New(v8::Isolate::GetCurrent());
1059+
std::string topic_name = names_and_types.names.data[i];
1060+
item->Set(Nan::New("name").ToLocalChecked(),
1061+
Nan::New(names_and_types.names.data[i]).ToLocalChecked());
1062+
1063+
v8::Local<v8::Array> type_list =
1064+
Nan::New<v8::Array>(names_and_types.types[i].size);
1065+
for (int j = 0; j < names_and_types.types[i].size; ++j) {
1066+
Nan::Set(
1067+
type_list, j,
1068+
Nan::New(names_and_types.types[i].data[j]).ToLocalChecked());
1069+
}
1070+
item->Set(Nan::New("types").ToLocalChecked(), type_list);
1071+
Nan::Set(*result_list, i, item);
1072+
}
1073+
}
1074+
1075+
NAN_METHOD(GetPublisherNamesAndTypesByNode) {
1076+
RclHandle* node_handle = RclHandle::Unwrap<RclHandle>(info[0]->ToObject());
1077+
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
1078+
std::string node_name = *Nan::Utf8String(info[1]->ToString());
1079+
std::string node_namespace = *Nan::Utf8String(info[2]->ToString());
1080+
bool no_demangle = Nan::To<bool>(info[3]).FromJust();
1081+
1082+
rcl_names_and_types_t topic_names_and_types =
1083+
rcl_get_zero_initialized_names_and_types();
1084+
rcl_allocator_t allocator = rcl_get_default_allocator();
1085+
THROW_ERROR_IF_NOT_EQUAL(
1086+
RCL_RET_OK,
1087+
rcl_get_publisher_names_and_types_by_node(node, &allocator, no_demangle,
1088+
node_name.c_str(), node_namespace.c_str(), &topic_names_and_types),
1089+
"Failed to get_publisher_names_and_types.");
1090+
1091+
v8::Local<v8::Array> result_list =
1092+
Nan::New<v8::Array>(topic_names_and_types.names.size);
1093+
ExtractNamesAndTypes(topic_names_and_types, &result_list);
1094+
1095+
THROW_ERROR_IF_NOT_EQUAL(
1096+
RCL_RET_OK,
1097+
rcl_names_and_types_fini(&topic_names_and_types),
1098+
"Failed to destroy topic_names_and_types");
1099+
1100+
info.GetReturnValue().Set(result_list);
1101+
}
1102+
1103+
NAN_METHOD(GetSubscriptionNamesAndTypesByNode) {
1104+
RclHandle* node_handle = RclHandle::Unwrap<RclHandle>(info[0]->ToObject());
1105+
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
1106+
std::string node_name = *Nan::Utf8String(info[1]->ToString());
1107+
std::string node_namespace = *Nan::Utf8String(info[2]->ToString());
1108+
bool no_demangle = Nan::To<bool>(info[3]).FromJust();
1109+
1110+
rcl_names_and_types_t topic_names_and_types =
1111+
rcl_get_zero_initialized_names_and_types();
1112+
rcl_allocator_t allocator = rcl_get_default_allocator();
1113+
THROW_ERROR_IF_NOT_EQUAL(
1114+
RCL_RET_OK,
1115+
rcl_get_subscriber_names_and_types_by_node(node, &allocator, no_demangle,
1116+
node_name.c_str(), node_namespace.c_str(), &topic_names_and_types),
1117+
"Failed to get_publisher_names_and_types.");
1118+
1119+
v8::Local<v8::Array> result_list =
1120+
Nan::New<v8::Array>(topic_names_and_types.names.size);
1121+
ExtractNamesAndTypes(topic_names_and_types, &result_list);
1122+
1123+
THROW_ERROR_IF_NOT_EQUAL(
1124+
RCL_RET_OK,
1125+
rcl_names_and_types_fini(&topic_names_and_types),
1126+
"Failed to destroy topic_names_and_types");
1127+
1128+
info.GetReturnValue().Set(result_list);
1129+
}
1130+
1131+
NAN_METHOD(GetServiceNamesAndTypesByNode) {
1132+
RclHandle* node_handle = RclHandle::Unwrap<RclHandle>(info[0]->ToObject());
1133+
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
1134+
std::string node_name = *Nan::Utf8String(info[1]->ToString());
1135+
std::string node_namespace = *Nan::Utf8String(info[2]->ToString());
1136+
1137+
rcl_names_and_types_t service_names_and_types =
1138+
rcl_get_zero_initialized_names_and_types();
1139+
rcl_allocator_t allocator = rcl_get_default_allocator();
1140+
THROW_ERROR_IF_NOT_EQUAL(
1141+
RCL_RET_OK,
1142+
rcl_get_service_names_and_types_by_node(node, &allocator,
1143+
node_name.c_str(), node_namespace.c_str(), &service_names_and_types),
1144+
"Failed to get_publisher_names_and_types.");
1145+
1146+
v8::Local<v8::Array> result_list =
1147+
Nan::New<v8::Array>(service_names_and_types.names.size);
1148+
ExtractNamesAndTypes(service_names_and_types, &result_list);
1149+
1150+
THROW_ERROR_IF_NOT_EQUAL(
1151+
RCL_RET_OK,
1152+
rcl_names_and_types_fini(&service_names_and_types),
1153+
"Failed to destroy topic_names_and_types");
1154+
1155+
info.GetReturnValue().Set(result_list);
1156+
}
1157+
1158+
NAN_METHOD(GetTopicNamesAndTypes) {
1159+
RclHandle* node_handle = RclHandle::Unwrap<RclHandle>(info[0]->ToObject());
1160+
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
1161+
bool no_demangle = Nan::To<bool>(info[1]).FromJust();
1162+
rcl_names_and_types_t topic_names_and_types =
1163+
rcl_get_zero_initialized_names_and_types();
1164+
rcl_allocator_t allocator = rcl_get_default_allocator();
1165+
1166+
THROW_ERROR_IF_NOT_EQUAL(
1167+
RCL_RET_OK,
1168+
rcl_get_topic_names_and_types(node, &allocator, no_demangle,
1169+
&topic_names_and_types),
1170+
"Failed to get_publisher_names_and_types.");
1171+
1172+
v8::Local<v8::Array> result_list =
1173+
Nan::New<v8::Array>(topic_names_and_types.names.size);
1174+
ExtractNamesAndTypes(topic_names_and_types, &result_list);
1175+
1176+
THROW_ERROR_IF_NOT_EQUAL(
1177+
RCL_RET_OK,
1178+
rcl_names_and_types_fini(&topic_names_and_types),
1179+
"Failed to destroy topic_names_and_types");
1180+
1181+
info.GetReturnValue().Set(result_list);
1182+
}
1183+
1184+
NAN_METHOD(GetServiceNamesAndTypes) {
1185+
RclHandle* node_handle = RclHandle::Unwrap<RclHandle>(info[0]->ToObject());
1186+
rcl_node_t* node = reinterpret_cast<rcl_node_t*>(node_handle->ptr());
1187+
rcl_names_and_types_t service_names_and_types =
1188+
rcl_get_zero_initialized_names_and_types();
1189+
rcl_allocator_t allocator = rcl_get_default_allocator();
1190+
1191+
THROW_ERROR_IF_NOT_EQUAL(
1192+
RCL_RET_OK,
1193+
rcl_get_service_names_and_types(node, &allocator, &service_names_and_types),
1194+
"Failed to get_publisher_names_and_types.");
1195+
1196+
v8::Local<v8::Array> result_list =
1197+
Nan::New<v8::Array>(service_names_and_types.names.size);
1198+
ExtractNamesAndTypes(service_names_and_types, &result_list);
1199+
1200+
THROW_ERROR_IF_NOT_EQUAL(
1201+
RCL_RET_OK,
1202+
rcl_names_and_types_fini(&service_names_and_types),
1203+
"Failed to destroy topic_names_and_types");
1204+
1205+
info.GetReturnValue().Set(result_list);
1206+
}
1207+
10541208
uint32_t GetBindingMethodsCount(BindingMethod* methods) {
10551209
uint32_t count = 0;
10561210
while (methods[count].function) {
@@ -1109,6 +1263,11 @@ BindingMethod binding_methods[] = {
11091263
{"isEnableFor", IsEnableFor},
11101264
{"createContext", CreateContext},
11111265
{"ok", IsContextValid},
1266+
{"getPublisherNamesAndTypesByNode", GetPublisherNamesAndTypesByNode},
1267+
{"getSubscriptionNamesAndTypesByNode", GetSubscriptionNamesAndTypesByNode},
1268+
{"getServiceNamesAndTypesByNode", GetServiceNamesAndTypesByNode},
1269+
{"getTopicNamesAndTypes", GetTopicNamesAndTypes},
1270+
{"getServiceNamesAndTypes", GetServiceNamesAndTypes},
11121271
{"", nullptr}};
11131272

11141273
} // namespace rclnodejs

0 commit comments

Comments
 (0)