Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ class Service extends Entity {
true
);
}

/**
* Get the options of this service.
* @return {object} The options of this service.
*/
getOptions() {
return rclnodejs.getOptions(this._handle);
}
}

module.exports = Service;
14 changes: 14 additions & 0 deletions src/rcl_service_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Napi::Value CreateService(const Napi::CallbackInfo& info) {
if (qos_profile) {
service_ops.qos = *qos_profile;
}

THROW_ERROR_IF_NOT_EQUAL(
rcl_service_init(service, node, ts, service_name.c_str(), &service_ops),
RCL_RET_OK, rcl_get_error_string().str);
Expand Down Expand Up @@ -173,6 +174,18 @@ Napi::Value ConfigureServiceIntrospection(const Napi::CallbackInfo& info) {
}
#endif

Napi::Value GetOptions(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();

rcl_service_t* service = reinterpret_cast<rcl_service_t*>(
RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());

const rcl_service_options_t* options = rcl_service_get_options(service);
auto qos_profile = ConvertToQoS(env, &options->qos);
Copy link

Copilot AI May 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider using the fully qualified name 'rclnodejs::ConvertToQoS' for clarity and consistency with its usage elsewhere in the codebase.

Suggested change
auto qos_profile = ConvertToQoS(env, &options->qos);
auto qos_profile = rclnodejs::ConvertToQoS(env, &options->qos);

Copilot uses AI. Check for mistakes.

return qos_profile;
}

Napi::Object InitServiceBindings(Napi::Env env, Napi::Object exports) {
exports.Set("createService", Napi::Function::New(env, CreateService));
exports.Set("rclTakeRequest", Napi::Function::New(env, RclTakeRequest));
Expand All @@ -183,6 +196,7 @@ Napi::Object InitServiceBindings(Napi::Env env, Napi::Object exports) {
exports.Set("configureServiceIntrospection",
Napi::Function::New(env, ConfigureServiceIntrospection));
#endif
exports.Set("getOptions", Napi::Function::New(env, GetOptions));
return exports;
}

Expand Down
38 changes: 19 additions & 19 deletions src/rcl_utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,24 +88,6 @@ Napi::Value ConvertToHashObject(Napi::Env env,
return obj;
}

Napi::Value ConvertToQoS(Napi::Env env, const rmw_qos_profile_t* qos_profile) {
Napi::Object qos = Napi::Object::New(env);
qos.Set("depth", Napi::Number::New(env, qos_profile->depth));
qos.Set("history", Napi::Number::New(env, qos_profile->history));
qos.Set("reliability", Napi::Number::New(env, qos_profile->reliability));
qos.Set("durability", Napi::Number::New(env, qos_profile->durability));
qos.Set("lifespan", ConvertRMWTimeToDuration(env, &qos_profile->lifespan));
qos.Set("deadline", ConvertRMWTimeToDuration(env, &qos_profile->deadline));
qos.Set("liveliness", Napi::Number::New(env, qos_profile->liveliness));
qos.Set(
"liveliness_lease_duration",
ConvertRMWTimeToDuration(env, &qos_profile->liveliness_lease_duration));
qos.Set(
"avoid_ros_namespace_conventions",
Napi::Boolean::New(env, qos_profile->avoid_ros_namespace_conventions));
return qos;
}

Napi::Value ConvertToJSTopicEndpoint(
Napi::Env env, const rmw_topic_endpoint_info_t* topic_endpoint_info) {
Napi::Array endpoint_gid = Napi::Array::New(env, RMW_GID_STORAGE_SIZE);
Expand All @@ -128,7 +110,7 @@ Napi::Value ConvertToJSTopicEndpoint(
env, static_cast<int>(topic_endpoint_info->endpoint_type)));
endpoint.Set("endpoint_gid", endpoint_gid);
endpoint.Set("qos_profile",
ConvertToQoS(env, &topic_endpoint_info->qos_profile));
rclnodejs::ConvertToQoS(env, &topic_endpoint_info->qos_profile));
return endpoint;
}

Expand Down Expand Up @@ -246,6 +228,24 @@ void ExtractNamesAndTypes(rcl_names_and_types_t names_and_types,
}
}

Napi::Value ConvertToQoS(Napi::Env env, const rmw_qos_profile_t* qos_profile) {
Napi::Object qos = Napi::Object::New(env);
qos.Set("depth", Napi::Number::New(env, qos_profile->depth));
qos.Set("history", Napi::Number::New(env, qos_profile->history));
qos.Set("reliability", Napi::Number::New(env, qos_profile->reliability));
qos.Set("durability", Napi::Number::New(env, qos_profile->durability));
qos.Set("lifespan", ConvertRMWTimeToDuration(env, &qos_profile->lifespan));
qos.Set("deadline", ConvertRMWTimeToDuration(env, &qos_profile->deadline));
qos.Set("liveliness", Napi::Number::New(env, qos_profile->liveliness));
qos.Set(
"liveliness_lease_duration",
ConvertRMWTimeToDuration(env, &qos_profile->liveliness_lease_duration));
qos.Set(
"avoid_ros_namespace_conventions",
Napi::Boolean::New(env, qos_profile->avoid_ros_namespace_conventions));
return qos;
}

Napi::Array ConvertToJSTopicEndpointInfoList(
Napi::Env env, const rmw_topic_endpoint_info_array_t* info_array) {
Napi::Array list = Napi::Array::New(env, info_array->size);
Expand Down
2 changes: 2 additions & 0 deletions src/rcl_utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ void ExtractNamesAndTypes(rcl_names_and_types_t names_and_types,
Napi::Array ConvertToJSTopicEndpointInfoList(
Napi::Env env, const rmw_topic_endpoint_info_array_t* info_array);

Napi::Value ConvertToQoS(Napi::Env env, const rmw_qos_profile_t* qos_profile);

} // namespace rclnodejs

#endif // SRC_RCL_UTILITIES_H_
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

const assert = require('assert');
const rclnodejs = require('../index.js');
const { QoS } = rclnodejs;

describe('Test creating a service with an async callback', function () {
describe('Test service class', function () {
this.timeout(60 * 1000);

before(function () {
Expand Down Expand Up @@ -67,4 +68,29 @@ describe('Test creating a service with an async callback', function () {
rclnodejs.spin(serviceNode);
rclnodejs.spin(clientNode);
});

it('Get service options', function () {
const node = rclnodejs.createNode('test_node');
const service = node.createService(
'example_interfaces/srv/AddTwoInts',
'add_two_ints',
{ qos: rclnodejs.QoS.profileSystemDefault },
(request, response) => {
let result = response.template;
result.sum = request.a + request.b;
}
);

const options = service.getOptions();
assert.strictEqual(options.depth, 0);
assert.strictEqual(
options.durability,
QoS.DurabilityPolicy.RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT
);
assert.strictEqual(
options.reliability,
QoS.ReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT
);
node.destroy();
});
});
1 change: 1 addition & 0 deletions test/types/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ expectType<void>(
)
);
expectType<boolean>(service.isDestroyed());
expectType<object>(service.getOptions());

// ---- Client ----
const client = node.createClient(
Expand Down
6 changes: 6 additions & 0 deletions types/service.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,11 @@ declare module 'rclnodejs' {
serviceEventPubQOS: QoS,
introspectionState: ServiceIntrospectionStates
): void;

/**
* Get the options of this service.
* @return The options of this service.
*/
getOptions(): object;
}
}
Loading