iceoryx2
C++ Language Bindings
Loading...
Searching...
No Matches
service_builder_publish_subscribe.hpp
Go to the documentation of this file.
1// Copyright (c) 2024 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13#ifndef IOX2_SERVICE_BUILDER_PUBLISH_SUBSCRIBE_HPP
14#define IOX2_SERVICE_BUILDER_PUBLISH_SUBSCRIBE_HPP
15
19#include "iox2/bb/expected.hpp"
20#include "iox2/bb/layout.hpp"
21#include "iox2/bb/slice.hpp"
27#include "iox2/payload_info.hpp"
30#include "iox2/service_type.hpp"
31#include "iox2/type_name.hpp"
32#include "iox2/type_variant.hpp"
33
34#include <cstring>
35#include <type_traits>
36
37namespace iox2 {
38template <typename Payload, typename UserHeader, ServiceType S>
39class ServiceBuilderPublishSubscribe;
40
50template <typename Payload, typename UserHeader, ServiceType S>
51auto set_payload_type_details(ServiceBuilderPublishSubscribe<Payload, UserHeader, S>& builder, const TypeDetail& value)
52 -> std::enable_if_t<std::is_same<Payload, bb::Slice<CustomPayloadMarker>>::value>;
53
63template <typename Payload, typename UserHeader, ServiceType S>
64auto set_user_header_type_details(ServiceBuilderPublishSubscribe<Payload, UserHeader, S>& builder,
65 const TypeDetail& value)
66 -> std::enable_if_t<std::is_same<UserHeader, CustomHeaderMarker>::value>;
67
69template <typename Payload, typename UserHeader, ServiceType S>
71 public:
76#ifdef DOXYGEN_MACRO_FIX
77 auto payload_alignment(const uint64_t value) -> decltype(auto);
78#else
80#endif
81
84#ifdef DOXYGEN_MACRO_FIX
85 auto enable_safe_overflow(const bool value) -> decltype(auto);
86#else
88#endif
89
93#ifdef DOXYGEN_MACRO_FIX
94 auto subscriber_max_borrowed_samples(const uint64_t value) -> decltype(auto);
95#else
97#endif
98
102#ifdef DOXYGEN_MACRO_FIX
103 auto history_size(const uint64_t value) -> decltype(auto);
104#else
106#endif
107
110#ifdef DOXYGEN_MACRO_FIX
111 auto subscriber_max_buffer_size(const uint64_t value) -> decltype(auto);
112#else
114#endif
115
119#ifdef DOXYGEN_MACRO_FIX
120 auto max_subscribers(const uint64_t value) -> decltype(auto);
121#else
123#endif
124
128#ifdef DOXYGEN_MACRO_FIX
129 auto max_publishers(const uint64_t value) -> decltype(auto);
130#else
132#endif
133
137#ifdef DOXYGEN_MACRO_FIX
138 auto max_nodes(const uint64_t value) -> decltype(auto);
139#else
141#endif
142
143 public:
145 template <typename NewHeader>
147
152
157
162 auto open_or_create_with_attributes(const AttributeVerifier& required_attributes) && -> bb::
163 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeOpenOrCreateError>;
164
167
170 auto open_with_attributes(const AttributeVerifier& required_attributes) && -> bb::
171 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeOpenError>;
172
175
180
181 private:
182 template <ServiceType>
183 friend class ServiceBuilder;
184
185 template <typename P, typename U, ServiceType St>
187 -> std::enable_if_t<std::is_same<P, bb::Slice<CustomPayloadMarker>>::value>;
188 template <typename P, typename U, ServiceType St>
190 -> std::enable_if_t<std::is_same<U, CustomHeaderMarker>::value>;
191
192 explicit ServiceBuilderPublishSubscribe(iox2_service_builder_h handle);
193
194 void set_parameters();
195 void derive_payload_type_details();
196 void override_payload_type_details(const TypeDetail& value);
197 void derive_user_header_type_details();
198 void override_user_header_type_details(const TypeDetail& value);
199
200 iox2_service_builder_pub_sub_h m_handle = nullptr;
201 bb::Optional<TypeDetail> m_user_header_type_details_override;
202 bb::Optional<TypeDetail> m_payload_type_details_override;
203};
204
205template <typename Payload, typename UserHeader, ServiceType S>
207 iox2_service_builder_h handle)
208 : m_handle { iox2_service_builder_pub_sub(handle) } {
209}
210
211template <typename Payload, typename UserHeader, ServiceType S>
212inline void ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::set_parameters() {
213 if (m_enable_safe_overflow.has_value()) {
214 iox2_service_builder_pub_sub_set_enable_safe_overflow(&m_handle, m_enable_safe_overflow.value());
215 }
216 if (m_subscriber_max_borrowed_samples.has_value()) {
217 iox2_service_builder_pub_sub_set_subscriber_max_borrowed_samples(&m_handle,
218 m_subscriber_max_borrowed_samples.value());
219 }
220 if (m_history_size.has_value()) {
221 iox2_service_builder_pub_sub_set_history_size(&m_handle, m_history_size.value());
222 }
223 if (m_subscriber_max_buffer_size.has_value()) {
224 iox2_service_builder_pub_sub_set_subscriber_max_buffer_size(&m_handle, m_subscriber_max_buffer_size.value());
225 }
226 if (m_max_subscribers.has_value()) {
227 iox2_service_builder_pub_sub_set_max_subscribers(&m_handle, m_max_subscribers.value());
228 }
229 if (m_max_publishers.has_value()) {
230 iox2_service_builder_pub_sub_set_max_publishers(&m_handle, m_max_publishers.value());
231 }
232 if (m_payload_alignment.has_value()) {
233 iox2_service_builder_pub_sub_set_payload_alignment(&m_handle, m_payload_alignment.value());
234 }
235 if (m_max_nodes.has_value()) {
236 iox2_service_builder_pub_sub_set_max_nodes(&m_handle, m_max_nodes.value());
237 }
238
239 if (m_user_header_type_details_override.has_value()) {
240 override_user_header_type_details(m_user_header_type_details_override.value());
241 } else {
242 derive_user_header_type_details();
243 }
244
245 if (m_payload_type_details_override.has_value()) {
246 override_payload_type_details(m_payload_type_details_override.value());
247 } else {
248 derive_payload_type_details();
249 }
250}
251
252template <typename Payload, typename UserHeader, ServiceType S>
253inline void ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::derive_user_header_type_details() {
254 // user header type details derived from the compile-time UserHeader
255 const auto header_layout = bb::Layout::from<UserHeader>();
256 const auto user_header_type_name = internal::get_type_name<UserHeader>();
257
258 const auto result =
259 iox2_service_builder_pub_sub_set_user_header_type_details(&m_handle,
260 iox2_type_variant_e_FIXED_SIZE,
261 user_header_type_name.unchecked_access().c_str(),
262 user_header_type_name.size(),
263 header_layout.size(),
264 header_layout.alignment());
265
266 if (result != IOX2_OK) {
267 IOX2_PANIC("This should never happen! Implementation failure while setting the User-Header-Type.");
268 }
269}
270
271template <typename Payload, typename UserHeader, ServiceType S>
272inline void
273ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::override_user_header_type_details(const TypeDetail& value) {
274 // user header type details provided at runtime
275 const auto type_variant =
276 value.variant() == TypeVariant::FixedSize ? iox2_type_variant_e_FIXED_SIZE : iox2_type_variant_e_DYNAMIC;
277
278 const auto result = iox2_service_builder_pub_sub_set_user_header_type_details(
279 &m_handle, type_variant, value.type_name(), std::strlen(value.type_name()), value.size(), value.alignment());
280
281 if (result != IOX2_OK) {
282 IOX2_PANIC("This should never happen! Implementation failure while setting the User-Header-Type.");
283 }
284}
285
286template <typename Payload, typename UserHeader, ServiceType S>
287inline void ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::derive_payload_type_details() {
288 using ValueType = typename PayloadInfo<Payload>::ValueType;
289
290 // payload type details derived from the compile-time Payload
291 const auto payload_type_name = internal::get_type_name<Payload>();
292 const auto type_variant =
293 bb::IsSlice<Payload>::VALUE ? iox2_type_variant_e_DYNAMIC : iox2_type_variant_e_FIXED_SIZE;
294
295 const auto result =
296 iox2_service_builder_pub_sub_set_payload_type_details(&m_handle,
297 type_variant,
298 payload_type_name.unchecked_access().c_str(),
299 payload_type_name.size(),
300 sizeof(ValueType),
301 alignof(ValueType));
302
303 if (result != IOX2_OK) {
304 IOX2_PANIC("This should never happen! Implementation failure while setting the Payload-Type.");
305 }
306}
307
308template <typename Payload, typename UserHeader, ServiceType S>
309inline void
310ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::override_payload_type_details(const TypeDetail& value) {
311 // payload type details provided at runtime
312 const auto type_variant =
313 value.variant() == TypeVariant::FixedSize ? iox2_type_variant_e_FIXED_SIZE : iox2_type_variant_e_DYNAMIC;
314
315 const auto result = iox2_service_builder_pub_sub_set_payload_type_details(
316 &m_handle, type_variant, value.type_name(), std::strlen(value.type_name()), value.size(), value.alignment());
317
318 if (result != IOX2_OK) {
319 IOX2_PANIC("This should never happen! Implementation failure while setting the Payload-Type.");
320 }
321}
322
323
324template <typename Payload, typename UserHeader, ServiceType S>
325template <typename NewHeader>
328 // required here since we just change the template header type but the builder structure stays the same
329 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
330 return std::move(*reinterpret_cast<ServiceBuilderPublishSubscribe<Payload, NewHeader, S>*>(this));
331}
332
333template <typename Payload, typename UserHeader, ServiceType S>
338
339template <typename Payload, typename UserHeader, ServiceType S>
341 const TypeDetail& value)
342 -> std::enable_if_t<std::is_same<UserHeader, CustomHeaderMarker>::value> {
343 builder.m_user_header_type_details_override = bb::Optional<TypeDetail>(value);
344}
345
346template <typename Payload, typename UserHeader, ServiceType S>
348 const TypeDetail& value)
349 -> std::enable_if_t<std::is_same<Payload, bb::Slice<CustomPayloadMarker>>::value> {
350 builder.m_payload_type_details_override = bb::Optional<TypeDetail>(value);
351}
352
353template <typename Payload, typename UserHeader, ServiceType S>
355 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeOpenOrCreateError> {
356 set_parameters();
357
358 iox2_port_factory_pub_sub_h port_factory_handle {};
359 auto result = iox2_service_builder_pub_sub_open_or_create(m_handle, nullptr, &port_factory_handle);
360
361 if (result == IOX2_OK) {
362 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
363 }
364
365 return bb::err(bb::into<PublishSubscribeOpenOrCreateError>(result));
366}
367
368template <typename Payload, typename UserHeader, ServiceType S>
370 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeOpenError> {
371 set_parameters();
372
373 iox2_port_factory_pub_sub_h port_factory_handle {};
374 auto result = iox2_service_builder_pub_sub_open(m_handle, nullptr, &port_factory_handle);
375
376 if (result == IOX2_OK) {
377 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
378 }
379
380 return bb::err(bb::into<PublishSubscribeOpenError>(result));
381}
382
383template <typename Payload, typename UserHeader, ServiceType S>
385 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeCreateError> {
386 set_parameters();
387
388 iox2_port_factory_pub_sub_h port_factory_handle {};
389 auto result = iox2_service_builder_pub_sub_create(m_handle, nullptr, &port_factory_handle);
390
391 if (result == IOX2_OK) {
392 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
393 }
394
395 return bb::err(bb::into<PublishSubscribeCreateError>(result));
396}
397
398template <typename Payload, typename UserHeader, ServiceType S>
400 const AttributeVerifier&
403 set_parameters();
404
405 iox2_port_factory_pub_sub_h port_factory_handle {};
406 auto result = iox2_service_builder_pub_sub_open_or_create_with_attributes(
407 m_handle, &required_attributes.m_handle, nullptr, &port_factory_handle);
408
409 if (result == IOX2_OK) {
410 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
411 }
412
413 return bb::err(bb::into<PublishSubscribeOpenOrCreateError>(result));
414}
415
416template <typename Payload, typename UserHeader, ServiceType S>
418 const AttributeVerifier&
421 set_parameters();
422
423 iox2_port_factory_pub_sub_h port_factory_handle {};
424 auto result = iox2_service_builder_pub_sub_open_with_attributes(
425 m_handle, &required_attributes.m_handle, nullptr, &port_factory_handle);
426
427 if (result == IOX2_OK) {
428 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
429 }
430
431 return bb::err(bb::into<PublishSubscribeOpenError>(result));
432}
433
434template <typename Payload, typename UserHeader, ServiceType S>
438 set_parameters();
439
440 iox2_port_factory_pub_sub_h port_factory_handle {};
441 auto result = iox2_service_builder_pub_sub_create_with_attributes(
442 m_handle, &attributes.m_handle, nullptr, &port_factory_handle);
443
444 if (result == IOX2_OK) {
445 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
446 }
447
448 return bb::err(bb::into<PublishSubscribeCreateError>(result));
449}
450} // namespace iox2
451
452#endif
#define IOX2_PANIC(message)
calls panic handler and does not return
#define IOX2_BUILDER_OPTIONAL(type, name)
Definition builder.hpp:47
Builder to create new [MessagingPattern::PublishSubscribe] based [Service]s.
auto user_header() &&-> ServiceBuilderPublishSubscribe< Payload, NewHeader, S > &&
Sets the user header type of the [Service].
auto open_or_create_with_attributes(const AttributeVerifier &required_attributes) &&-> bb::Expected< PortFactoryPublishSubscribe< S, Payload, UserHeader >, PublishSubscribeOpenOrCreateError >
auto max_publishers(const uint64_t value) -> decltype(auto)
auto open_with_attributes(const AttributeVerifier &required_attributes) &&-> bb::Expected< PortFactoryPublishSubscribe< S, Payload, UserHeader >, PublishSubscribeOpenError >
auto history_size(const uint64_t value) -> decltype(auto)
auto subscriber_max_borrowed_samples(const uint64_t value) -> decltype(auto)
auto create_with_attributes(const AttributeSpecifier &attributes) &&-> bb::Expected< PortFactoryPublishSubscribe< S, Payload, UserHeader >, PublishSubscribeCreateError >
Creates a new [Service] with a set of attributes.
auto open_or_create() &&-> bb::Expected< PortFactoryPublishSubscribe< S, Payload, UserHeader >, PublishSubscribeOpenOrCreateError >
auto open() &&-> bb::Expected< PortFactoryPublishSubscribe< S, Payload, UserHeader >, PublishSubscribeOpenError >
Opens an existing [Service].
auto max_nodes(const uint64_t value) -> decltype(auto)
auto max_subscribers(const uint64_t value) -> decltype(auto)
auto payload_alignment(const uint64_t value) -> decltype(auto)
auto resume_build() &-> ServiceBuilderPublishSubscribe< Payload, UserHeader, S > &&
auto enable_safe_overflow(const bool value) -> decltype(auto)
friend auto set_user_header_type_details(ServiceBuilderPublishSubscribe< P, U, St > &builder, const TypeDetail &value) -> std::enable_if_t< std::is_same< U, CustomHeaderMarker >::value >
auto subscriber_max_buffer_size(const uint64_t value) -> decltype(auto)
auto create() &&-> bb::Expected< PortFactoryPublishSubscribe< S, Payload, UserHeader >, PublishSubscribeCreateError >
Creates a new [Service].
friend auto set_payload_type_details(ServiceBuilderPublishSubscribe< P, U, St > &builder, const TypeDetail &value) -> std::enable_if_t< std::is_same< P, bb::Slice< CustomPayloadMarker > >::value >
Builder to create or open [Service]s.
constexpr auto err(const E &error) -> Unexpected< E >
Definition expected.hpp:33
iox2::bb::variation::Optional< T > Optional
Definition optional.hpp:25
iox2::bb::variation::Expected< T, E > Expected
Definition expected.hpp:22
auto set_payload_type_details(ServiceBuilderPublishSubscribe< Payload, UserHeader, S > &builder, const TypeDetail &value) -> std::enable_if_t< std::is_same< Payload, bb::Slice< CustomPayloadMarker > >::value >
PublishSubscribeCreateError
Errors that can occur when a new [MessagingPattern::PublishSubscribe] [Service] shall be created.
auto set_user_header_type_details(ServiceBuilderPublishSubscribe< Payload, UserHeader, S > &builder, const TypeDetail &value) -> std::enable_if_t< std::is_same< UserHeader, CustomHeaderMarker >::value >
@ FixedSize
A fixed size type like [u64].
PublishSubscribeOpenError
Errors that can occur when an existing [MessagingPattern::PublishSubscribe] [Service] shall be opened...
static constexpr bool VALUE
Definition slice.hpp:159