1818#include < rcl/graph.h>
1919#include < rcl/rcl.h>
2020
21+ #include < rcpputils/scope_exit.hpp>
22+ // NOLINTNEXTLINE
2123#include < string>
2224
2325#include " macros.h"
2628
2729namespace rclnodejs {
2830
31+ typedef rcl_ret_t (*rcl_get_info_by_topic_func_t )(
32+ const rcl_node_t * node, rcutils_allocator_t * allocator,
33+ const char * topic_name, bool no_mangle,
34+ rcl_topic_endpoint_info_array_t * info_array);
35+
2936Napi::Value GetPublisherNamesAndTypesByNode (const Napi::CallbackInfo& info) {
3037 Napi::Env env = info.Env ();
3138
@@ -193,59 +200,61 @@ Napi::Value GetServiceNamesAndTypes(const Napi::CallbackInfo& info) {
193200 return result_list;
194201}
195202
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);
203+ Napi::Value GetInfoByTopic (Napi::Env env, rcl_node_t * node,
204+ const char * topic_name, bool no_mangle,
205+ const char * type,
206+ rcl_get_info_by_topic_func_t rcl_get_info_by_topic) {
207+ rcutils_allocator_t allocator = rcutils_get_default_allocator ();
208+ rcl_topic_endpoint_info_array_t info_array =
209+ rcl_get_zero_initialized_topic_endpoint_info_array ();
210+
211+ RCPPUTILS_SCOPE_EXIT ({
212+ rcl_ret_t fini_ret =
213+ rcl_topic_endpoint_info_array_fini (&info_array, &allocator);
214+ if (RCL_RET_OK != fini_ret) {
215+ Napi::Error::New (env, rcl_get_error_string ().str )
216+ .ThrowAsJavaScriptException ();
217+ rcl_reset_error ();
218+ }
219+ });
220+
221+ rcl_ret_t ret = rcl_get_info_by_topic (node, &allocator, topic_name, no_mangle,
222+ &info_array);
223+ if (RCL_RET_OK != ret) {
224+ if (RCL_RET_UNSUPPORTED == ret) {
225+ Napi::Error::New (
226+ env, std::string (" Failed to get information by topic for " ) + type +
227+ " : function not supported by RMW_IMPLEMENTATION" )
228+ .ThrowAsJavaScriptException ();
229+ return env.Undefined ();
230+ }
231+ Napi::Error::New (
232+ env, std::string (" Failed to get information by topic for " ) + type)
233+ .ThrowAsJavaScriptException ();
234+ return env.Undefined ();
221235 }
222236
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);
237+ return ConvertToJSTopicEndpointInfoList (env, &info_array);
238+ }
226239
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" );
240+ Napi::Value GetPublishersInfoByTopic (const Napi::CallbackInfo& info) {
241+ RclHandle* node_handle = RclHandle::Unwrap (info[0 ].As <Napi::Object>());
242+ rcl_node_t * node = reinterpret_cast <rcl_node_t *>(node_handle->ptr ());
243+ std::string topic_name = info[1 ].As <Napi::String>().Utf8Value ();
244+ bool no_mangle = info[2 ].As <Napi::Boolean>();
231245
232- return result_list;
246+ return GetInfoByTopic (info.Env (), node, topic_name.c_str (), no_mangle,
247+ " publishers" , rcl_get_publishers_info_by_topic);
233248}
234249
235- Napi::Value ServiceServerIsAvailable (const Napi::CallbackInfo& info) {
236- Napi::Env env = info.Env ();
237-
250+ Napi::Value GetSubscriptionsInfoByTopic (const Napi::CallbackInfo& info) {
238251 RclHandle* node_handle = RclHandle::Unwrap (info[0 ].As <Napi::Object>());
239252 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." );
253+ std::string topic_name = info[1 ].As <Napi::String>().Utf8Value ();
254+ bool no_mangle = info[2 ].As <Napi::Boolean>();
247255
248- return Napi::Boolean::New (env, is_available);
256+ return GetInfoByTopic (info.Env (), node, topic_name.c_str (), no_mangle,
257+ " subscriptions" , rcl_get_subscriptions_info_by_topic);
249258}
250259
251260Napi::Object InitGraphBindings (Napi::Env env, Napi::Object exports) {
@@ -261,9 +270,10 @@ Napi::Object InitGraphBindings(Napi::Env env, Napi::Object exports) {
261270 Napi::Function::New (env, GetTopicNamesAndTypes));
262271 exports.Set (" getServiceNamesAndTypes" ,
263272 Napi::Function::New (env, GetServiceNamesAndTypes));
264- exports.Set (" getNodeNames" , Napi::Function::New (env, GetNodeNames));
265- exports.Set (" serviceServerIsAvailable" ,
266- Napi::Function::New (env, ServiceServerIsAvailable));
273+ exports.Set (" getPublishersInfoByTopic" ,
274+ Napi::Function::New (env, GetPublishersInfoByTopic));
275+ exports.Set (" getSubscriptionsInfoByTopic" ,
276+ Napi::Function::New (env, GetSubscriptionsInfoByTopic));
267277 return exports;
268278}
269279
0 commit comments