diff --git a/lib/service.js b/lib/service.js index 3083018a..26d8b00d 100644 --- a/lib/service.js +++ b/lib/service.js @@ -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; diff --git a/src/rcl_service_bindings.cpp b/src/rcl_service_bindings.cpp index 25fca39f..0d2449a8 100644 --- a/src/rcl_service_bindings.cpp +++ b/src/rcl_service_bindings.cpp @@ -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); @@ -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( + RclHandle::Unwrap(info[0].As())->ptr()); + + const rcl_service_options_t* options = rcl_service_get_options(service); + auto qos_profile = ConvertToQoS(env, &options->qos); + + 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)); @@ -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; } diff --git a/src/rcl_utilities.cpp b/src/rcl_utilities.cpp index cefe34f4..87850eff 100644 --- a/src/rcl_utilities.cpp +++ b/src/rcl_utilities.cpp @@ -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); @@ -128,7 +110,7 @@ Napi::Value ConvertToJSTopicEndpoint( env, static_cast(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; } @@ -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); diff --git a/src/rcl_utilities.h b/src/rcl_utilities.h index 49119fbf..a29fed64 100644 --- a/src/rcl_utilities.h +++ b/src/rcl_utilities.h @@ -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_ diff --git a/test/test-service-with-async-callback.js b/test/test-service.js similarity index 74% rename from test/test-service-with-async-callback.js rename to test/test-service.js index fcfdacb0..09c7d9ff 100644 --- a/test/test-service-with-async-callback.js +++ b/test/test-service.js @@ -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 () { @@ -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(); + }); }); diff --git a/test/types/index.test-d.ts b/test/types/index.test-d.ts index e6bad0ad..cc50d3da 100644 --- a/test/types/index.test-d.ts +++ b/test/types/index.test-d.ts @@ -202,6 +202,7 @@ expectType( ) ); expectType(service.isDestroyed()); +expectType(service.getOptions()); // ---- Client ---- const client = node.createClient( diff --git a/types/service.d.ts b/types/service.d.ts index f766b05b..4ee2d946 100644 --- a/types/service.d.ts +++ b/types/service.d.ts @@ -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; } }