Skip to content

Commit 7f03393

Browse files
authored
Add GetNumEntities() for action client (#1123)
This PR introduces a new method, GetNumEntities(), for the action client to retrieve the counts of various wait set entities. It adds corresponding tests and bindings in both the native C++ layer and the JavaScript API, and updates the documentation accordingly. - Introduces GetNumEntities() in rcl_action_client_bindings.cpp and exposes it as getNumEntities() in the ActionClient class. - Updates tests in both TypeScript and JavaScript to verify the returned counts. - Removes duplicate and unused cancel request functions from client and server bindings. Fix: #1122
1 parent d301436 commit 7f03393

File tree

6 files changed

+111
-43
lines changed

6 files changed

+111
-43
lines changed

lib/action/client.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,19 @@ class ActionClient extends Entity {
371371

372372
this._node._destroyEntity(this, this._node._actionClients);
373373
}
374+
375+
/**
376+
* Get the number of wait set entities that make up an action entity.
377+
* @return {object} - An object containing the number of various entities.
378+
* @property {number} subscriptionsNumber - The number of subscriptions.
379+
* @property {number} guardConditionsNumber - The number of guard conditions.
380+
* @property {number} timersNumber - The number of timers.
381+
* @property {number} clientsNumber - The number of clients.
382+
* @property {number} servicesNumber - The number of services.
383+
*/
384+
getNumEntities() {
385+
return rclnodejs.getNumEntities(this.handle);
386+
}
374387
}
375388

376389
module.exports = ActionClient;

src/rcl_action_client_bindings.cpp

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -126,28 +126,6 @@ Napi::Value ActionSendGoalRequest(const Napi::CallbackInfo& info) {
126126
return Napi::Number::New(env, static_cast<int32_t>(sequence_number));
127127
}
128128

129-
Napi::Value ActionTakeCancelRequest(const Napi::CallbackInfo& info) {
130-
Napi::Env env = info.Env();
131-
132-
RclHandle* action_server_handle =
133-
RclHandle::Unwrap(info[0].As<Napi::Object>());
134-
rcl_action_server_t* action_server =
135-
reinterpret_cast<rcl_action_server_t*>(action_server_handle->ptr());
136-
rmw_request_id_t* header =
137-
reinterpret_cast<rmw_request_id_t*>(malloc(sizeof(rmw_request_id_t)));
138-
139-
void* taken_request = info[1].As<Napi::Buffer<char>>().Data();
140-
rcl_ret_t ret =
141-
rcl_action_take_cancel_request(action_server, header, taken_request);
142-
if (ret != RCL_RET_ACTION_SERVER_TAKE_FAILED) {
143-
auto js_obj = RclHandle::NewInstance(env, header, nullptr,
144-
[](void* ptr) { free(ptr); });
145-
return js_obj;
146-
}
147-
148-
return env.Undefined();
149-
}
150-
151129
Napi::Value ActionSendResultRequest(const Napi::CallbackInfo& info) {
152130
Napi::Env env = info.Env();
153131

@@ -211,20 +189,73 @@ Napi::Value ActionTakeStatus(const Napi::CallbackInfo& info) {
211189
return env.Undefined();
212190
}
213191

192+
Napi::Value GetNumEntities(const Napi::CallbackInfo& info) {
193+
Napi::Env env = info.Env();
194+
RclHandle* action_client_handle =
195+
RclHandle::Unwrap(info[0].As<Napi::Object>());
196+
rcl_action_client_t* action_client =
197+
reinterpret_cast<rcl_action_client_t*>(action_client_handle->ptr());
198+
199+
size_t num_subscriptions = 0u;
200+
size_t num_guard_conditions = 0u;
201+
size_t num_timers = 0u;
202+
size_t num_clients = 0u;
203+
size_t num_services = 0u;
204+
205+
rcl_ret_t ret;
206+
ret = rcl_action_client_wait_set_get_num_entities(
207+
action_client, &num_subscriptions, &num_guard_conditions, &num_timers,
208+
&num_clients, &num_services);
209+
if (RCL_RET_OK != ret) {
210+
rcl_reset_error();
211+
std::string error_text{
212+
"Failed to get number of entities for 'rcl_action_client_t'"};
213+
Napi::Error::New(env, error_text).ThrowAsJavaScriptException();
214+
return env.Undefined();
215+
}
216+
Napi::Object entities = Napi::Object::New(env);
217+
entities.Set("subscriptionsNumber",
218+
Napi::Number::New(env, num_subscriptions));
219+
entities.Set("guardConditionsNumber",
220+
Napi::Number::New(env, num_guard_conditions));
221+
entities.Set("timersNumber", Napi::Number::New(env, num_timers));
222+
entities.Set("clientsNumber", Napi::Number::New(env, num_clients));
223+
entities.Set("servicesNumber", Napi::Number::New(env, num_services));
224+
return entities;
225+
}
226+
227+
Napi::Value ActionSendCancelRequest(const Napi::CallbackInfo& info) {
228+
Napi::Env env = info.Env();
229+
230+
RclHandle* action_client_handle =
231+
RclHandle::Unwrap(info[0].As<Napi::Object>());
232+
rcl_action_client_t* action_client =
233+
reinterpret_cast<rcl_action_client_t*>(action_client_handle->ptr());
234+
void* buffer = info[1].As<Napi::Buffer<char>>().Data();
235+
236+
int64_t sequence_number;
237+
THROW_ERROR_IF_NOT_EQUAL(
238+
rcl_action_send_cancel_request(action_client, buffer, &sequence_number),
239+
RCL_RET_OK, rcl_get_error_string().str);
240+
241+
return Napi::Number::New(env, static_cast<int32_t>(sequence_number));
242+
}
243+
214244
Napi::Object InitActionClientBindings(Napi::Env env, Napi::Object exports) {
215245
exports.Set("actionCreateClient",
216246
Napi::Function::New(env, ActionCreateClient));
217247
exports.Set("actionServerIsAvailable",
218248
Napi::Function::New(env, ActionServerIsAvailable));
219249
exports.Set("actionSendGoalRequest",
220250
Napi::Function::New(env, ActionSendGoalRequest));
221-
exports.Set("actionTakeCancelRequest",
222-
Napi::Function::New(env, ActionTakeCancelRequest));
223251
exports.Set("actionSendResultRequest",
224252
Napi::Function::New(env, ActionSendResultRequest));
225253
exports.Set("actionTakeFeedback",
226254
Napi::Function::New(env, ActionTakeFeedback));
227255
exports.Set("actionTakeStatus", Napi::Function::New(env, ActionTakeStatus));
256+
exports.Set("getNumEntities", Napi::Function::New(env, GetNumEntities));
257+
exports.Set("actionSendCancelRequest",
258+
Napi::Function::New(env, ActionSendCancelRequest));
228259
return exports;
229260
}
230261

src/rcl_action_server_bindings.cpp

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,6 @@ Napi::Value ActionCreateServer(const Napi::CallbackInfo& info) {
9696
}
9797
}
9898

99-
Napi::Value ActionSendCancelRequest(const Napi::CallbackInfo& info) {
100-
Napi::Env env = info.Env();
101-
102-
RclHandle* action_client_handle =
103-
RclHandle::Unwrap(info[0].As<Napi::Object>());
104-
rcl_action_client_t* action_client =
105-
reinterpret_cast<rcl_action_client_t*>(action_client_handle->ptr());
106-
void* buffer = info[1].As<Napi::Buffer<char>>().Data();
107-
108-
int64_t sequence_number;
109-
THROW_ERROR_IF_NOT_EQUAL(
110-
rcl_action_send_cancel_request(action_client, buffer, &sequence_number),
111-
RCL_RET_OK, rcl_get_error_string().str);
112-
113-
return Napi::Number::New(env, static_cast<int32_t>(sequence_number));
114-
}
115-
11699
Napi::Value ActionTakeResultRequest(const Napi::CallbackInfo& info) {
117100
Napi::Env env = info.Env();
118101

@@ -432,11 +415,31 @@ Napi::Value ActionServerGoalExists(const Napi::CallbackInfo& info) {
432415
return Napi::Boolean::New(env, exists);
433416
}
434417

418+
Napi::Value ActionTakeCancelRequest(const Napi::CallbackInfo& info) {
419+
Napi::Env env = info.Env();
420+
421+
RclHandle* action_server_handle =
422+
RclHandle::Unwrap(info[0].As<Napi::Object>());
423+
rcl_action_server_t* action_server =
424+
reinterpret_cast<rcl_action_server_t*>(action_server_handle->ptr());
425+
rmw_request_id_t* header =
426+
reinterpret_cast<rmw_request_id_t*>(malloc(sizeof(rmw_request_id_t)));
427+
428+
void* taken_request = info[1].As<Napi::Buffer<char>>().Data();
429+
rcl_ret_t ret =
430+
rcl_action_take_cancel_request(action_server, header, taken_request);
431+
if (ret != RCL_RET_ACTION_SERVER_TAKE_FAILED) {
432+
auto js_obj = RclHandle::NewInstance(env, header, nullptr,
433+
[](void* ptr) { free(ptr); });
434+
return js_obj;
435+
}
436+
437+
return env.Undefined();
438+
}
439+
435440
Napi::Object InitActionServerBindings(Napi::Env env, Napi::Object exports) {
436441
exports.Set("actionCreateServer",
437442
Napi::Function::New(env, ActionCreateServer));
438-
exports.Set("actionSendCancelRequest",
439-
Napi::Function::New(env, ActionSendCancelRequest));
440443
exports.Set("actionTakeResultRequest",
441444
Napi::Function::New(env, ActionTakeResultRequest));
442445
exports.Set("actionTakeGoalRequest",
@@ -464,6 +467,8 @@ Napi::Object InitActionServerBindings(Napi::Env env, Napi::Object exports) {
464467
Napi::Function::New(env, ActionProcessCancelRequest));
465468
exports.Set("actionServerGoalExists",
466469
Napi::Function::New(env, ActionServerGoalExists));
470+
exports.Set("actionTakeCancelRequest",
471+
Napi::Function::New(env, ActionTakeCancelRequest));
467472
return exports;
468473
}
469474

test/test-action-client.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,4 +283,16 @@ describe('rclnodejs action client', function () {
283283

284284
client.destroy();
285285
});
286+
287+
it('Test getNumEntities', function () {
288+
let client = new rclnodejs.ActionClient(node, fibonacci, 'fibonacci');
289+
const numEntities = client.getNumEntities();
290+
assert.strictEqual(numEntities.subscriptionsNumber, 2);
291+
assert.strictEqual(numEntities.guardConditionsNumber, 0);
292+
assert.strictEqual(numEntities.timersNumber, 0);
293+
assert.strictEqual(numEntities.clientsNumber, 3);
294+
assert.strictEqual(numEntities.servicesNumber, 0);
295+
296+
client.destroy();
297+
});
286298
});

test/types/index.test-d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ goalHandlePromise.then((goalHandle) => {
345345
expectType<boolean>(goalHandle.isCanceled());
346346
expectType<boolean>(goalHandle.isAborted());
347347
});
348+
expectType<object>(actionClient.getNumEntities());
348349

349350
// ---- ActionServer -----
350351
const actionServer = new rclnodejs.ActionServer(

types/action_client.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,5 +173,11 @@ declare module 'rclnodejs' {
173173
* Destroy the underlying action client handle.
174174
*/
175175
destroy(): void;
176+
177+
/**
178+
* Get the number of wait set entities that make up an action entity.
179+
* @return - The number of subscriptions, guard_conditions, timers, and clients and services.
180+
*/
181+
getNumEntities(): object;
176182
}
177183
}

0 commit comments

Comments
 (0)