1818#include < rcl/graph.h>
1919#include < rcl/rcl.h>
2020
21+ #include < rcpputils/scope_exit.hpp>
2122#include < string>
2223
2324#include " macros.h"
2627
2728namespace rclnodejs {
2829
30+ typedef rcl_ret_t (*rcl_get_info_by_topic_func_t )(
31+ const rcl_node_t * node, rcutils_allocator_t * allocator,
32+ const char * topic_name, bool no_mangle,
33+ rcl_topic_endpoint_info_array_t * info_array);
34+
2935Napi::Value GetPublisherNamesAndTypesByNode (const Napi::CallbackInfo& info) {
3036 Napi::Env env = info.Env ();
3137
@@ -193,59 +199,59 @@ Napi::Value GetServiceNamesAndTypes(const Napi::CallbackInfo& info) {
193199 return result_list;
194200}
195201
196- Napi::Value GetNodeNames (const Napi::CallbackInfo& info) {
197- Napi::Env env = info.Env ();
198-
199- RclHandle* node_handle = RclHandle::Unwrap (info[0 ].As <Napi::Object>());
200- rcl_node_t * node = reinterpret_cast <rcl_node_t *>(node_handle->ptr ());
201- rcutils_string_array_t node_names =
202- rcutils_get_zero_initialized_string_array ();
203- rcutils_string_array_t node_namespaces =
204- rcutils_get_zero_initialized_string_array ();
205- rcl_allocator_t allocator = rcl_get_default_allocator ();
206-
207- THROW_ERROR_IF_NOT_EQUAL (
208- RCL_RET_OK,
209- rcl_get_node_names (node, allocator, &node_names, &node_namespaces),
210- " Failed to get_node_names." );
211-
212- Napi::Array result_list = Napi::Array::New (env, node_names.size );
213-
214- for (size_t i = 0 ; i < node_names.size ; ++i) {
215- Napi::Object item = Napi::Object::New (env);
216-
217- item.Set (" name" , Napi::String::New (env, node_names.data [i]));
218- item.Set (" namespace" , Napi::String::New (env, node_namespaces.data [i]));
219-
220- result_list.Set (i, item);
202+ Napi::Value GetInfoByTopic (Napi::Env env, rcl_node_t * node,
203+ const char * topic_name, bool no_mangle,
204+ const char * type,
205+ rcl_get_info_by_topic_func_t rcl_get_info_by_topic) {
206+ rcutils_allocator_t allocator = rcutils_get_default_allocator ();
207+ rcl_topic_endpoint_info_array_t info_array =
208+ rcl_get_zero_initialized_topic_endpoint_info_array ();
209+
210+ RCPPUTILS_SCOPE_EXIT ({
211+ rcl_ret_t fini_ret =
212+ rcl_topic_endpoint_info_array_fini (&info_array, &allocator);
213+ if (RCL_RET_OK != fini_ret) {
214+ rcl_reset_error ();
215+ }
216+ });
217+
218+ rcl_ret_t ret = rcl_get_info_by_topic (node, &allocator, topic_name, no_mangle,
219+ &info_array);
220+ if (RCL_RET_OK != ret) {
221+ if (RCL_RET_UNSUPPORTED == ret) {
222+ Napi::Error::New (
223+ env, std::string (" Failed to get information by topic for " ) + type +
224+ " : function not supported by RMW_IMPLEMENTATION" )
225+ .ThrowAsJavaScriptException ();
226+ return env.Undefined ();
227+ }
228+ Napi::Error::New (
229+ env, std::string (" Failed to get information by topic for " ) + type)
230+ .ThrowAsJavaScriptException ();
231+ return env.Undefined ();
221232 }
222233
223- rcutils_ret_t fini_names_ret = rcutils_string_array_fini (&node_names);
224- rcutils_ret_t fini_namespaces_ret =
225- rcutils_string_array_fini (&node_namespaces);
234+ return ConvertToJSTopicEndpointInfoList (env, &info_array);
235+ }
226236
227- THROW_ERROR_IF_NOT_EQUAL (RCL_RET_OK, fini_names_ret,
228- " Failed to destroy node_names" );
229- THROW_ERROR_IF_NOT_EQUAL (RCL_RET_OK, fini_namespaces_ret,
230- " Failed to destroy node_namespaces" );
237+ Napi::Value GetPublishersInfoByTopic (const Napi::CallbackInfo& info) {
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+ bool no_mangle = info[2 ].As <Napi::Boolean>();
231242
232- return result_list;
243+ return GetInfoByTopic (info.Env (), node, topic_name.c_str (), no_mangle,
244+ " publishers" , rcl_get_publishers_info_by_topic);
233245}
234246
235- Napi::Value ServiceServerIsAvailable (const Napi::CallbackInfo& info) {
236- Napi::Env env = info.Env ();
237-
247+ Napi::Value GetSubscriptionsInfoByTopic (const Napi::CallbackInfo& info) {
238248 RclHandle* node_handle = RclHandle::Unwrap (info[0 ].As <Napi::Object>());
239249 rcl_node_t * node = reinterpret_cast <rcl_node_t *>(node_handle->ptr ());
240- RclHandle* client_handle = RclHandle::Unwrap (info[1 ].As <Napi::Object>());
241- rcl_client_t * client = reinterpret_cast <rcl_client_t *>(client_handle->ptr ());
242-
243- bool is_available;
244- THROW_ERROR_IF_NOT_EQUAL (
245- RCL_RET_OK, rcl_service_server_is_available (node, client, &is_available),
246- " Failed to get service state." );
250+ std::string topic_name = info[1 ].As <Napi::String>().Utf8Value ();
251+ bool no_mangle = info[2 ].As <Napi::Boolean>();
247252
248- return Napi::Boolean::New (env, is_available);
253+ return GetInfoByTopic (info.Env (), node, topic_name.c_str (), no_mangle,
254+ " subscriptions" , rcl_get_subscriptions_info_by_topic);
249255}
250256
251257Napi::Object InitGraphBindings (Napi::Env env, Napi::Object exports) {
@@ -261,9 +267,10 @@ Napi::Object InitGraphBindings(Napi::Env env, Napi::Object exports) {
261267 Napi::Function::New (env, GetTopicNamesAndTypes));
262268 exports.Set (" getServiceNamesAndTypes" ,
263269 Napi::Function::New (env, GetServiceNamesAndTypes));
264- exports.Set (" getNodeNames" , Napi::Function::New (env, GetNodeNames));
265- exports.Set (" serviceServerIsAvailable" ,
266- Napi::Function::New (env, ServiceServerIsAvailable));
270+ exports.Set (" getPublishersInfoByTopic" ,
271+ Napi::Function::New (env, GetPublishersInfoByTopic));
272+ exports.Set (" getSubscriptionsInfoByTopic" ,
273+ Napi::Function::New (env, GetSubscriptionsInfoByTopic));
267274 return exports;
268275}
269276
0 commit comments