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/file_path.hpp"
21#include "iox2/bb/layout.hpp"
22#include "iox2/bb/slice.hpp"
25#include "iox2/marker.hpp"
27#include "iox2/payload_info.hpp"
30#include "iox2/service_type.hpp"
31#include "iox2/type_variant.hpp"
32
33#include <cstring>
34#include <type_traits>
35
36namespace iox2 {
37template <typename Payload, typename UserHeader, ServiceType S>
38class ServiceBuilderPublishSubscribe;
39
49template <typename Payload, typename UserHeader, ServiceType S>
50auto set_payload_type_details(ServiceBuilderPublishSubscribe<Payload, UserHeader, S>& builder, const TypeDetail& value)
51 -> std::enable_if_t<std::is_same<Payload, bb::Slice<CustomPayloadMarker>>::value>;
52
62template <typename Payload, typename UserHeader, ServiceType S>
63auto set_user_header_type_details(ServiceBuilderPublishSubscribe<Payload, UserHeader, S>& builder,
64 const TypeDetail& value)
65 -> std::enable_if_t<std::is_same<UserHeader, CustomHeaderMarker>::value>;
66
68template <typename Payload, typename UserHeader, ServiceType S>
70 public:
75#ifdef DOXYGEN_MACRO_FIX
76 auto payload_alignment(const uint64_t value) -> decltype(auto);
77#else
79#endif
80
83#ifdef DOXYGEN_MACRO_FIX
84 auto enable_safe_overflow(const bool value) -> decltype(auto);
85#else
87#endif
88
92#ifdef DOXYGEN_MACRO_FIX
93 auto subscriber_max_borrowed_samples(const uint64_t value) -> decltype(auto);
94#else
96#endif
97
101#ifdef DOXYGEN_MACRO_FIX
102 auto history_size(const uint64_t value) -> decltype(auto);
103#else
105#endif
106
109#ifdef DOXYGEN_MACRO_FIX
110 auto subscriber_max_buffer_size(const uint64_t value) -> decltype(auto);
111#else
113#endif
114
118#ifdef DOXYGEN_MACRO_FIX
119 auto max_subscribers(const uint64_t value) -> decltype(auto);
120#else
122#endif
123
127#ifdef DOXYGEN_MACRO_FIX
128 auto max_publishers(const uint64_t value) -> decltype(auto);
129#else
131#endif
132
136#ifdef DOXYGEN_MACRO_FIX
137 auto max_nodes(const uint64_t value) -> decltype(auto);
138#else
140#endif
141
142 public:
146 template <typename U = Payload, typename = std::enable_if_t<has_flatbuffer_marker<U>(), void>>
148
150 template <typename NewHeader>
152
157
162
167 auto open_or_create_with_attributes(const AttributeVerifier& required_attributes) && -> bb::
168 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeOpenOrCreateError>;
169
172
175 auto open_with_attributes(const AttributeVerifier& required_attributes) && -> bb::
176 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeOpenError>;
177
180
185
186 private:
187 template <ServiceType>
188 friend class ServiceBuilder;
189
190 template <typename P, typename U, ServiceType St>
192 -> std::enable_if_t<std::is_same<P, bb::Slice<CustomPayloadMarker>>::value>;
193 template <typename P, typename U, ServiceType St>
195 -> std::enable_if_t<std::is_same<U, CustomHeaderMarker>::value>;
196
197 explicit ServiceBuilderPublishSubscribe(iox2_service_builder_h handle);
198
199 template <typename U = Payload>
200 auto set_type_definition_name_hint() -> std::enable_if_t<has_flatbuffer_marker<U>(), void>;
201 template <typename U = Payload>
202 auto set_type_definition_name_hint() -> std::enable_if_t<!has_flatbuffer_marker<U>(), void>;
203
204 void set_parameters();
205 void derive_payload_type_details();
206 void override_payload_type_details(const TypeDetail& value);
207 void derive_user_header_type_details();
208 void override_user_header_type_details(const TypeDetail& value);
209
210 iox2_service_builder_pub_sub_h m_handle = nullptr;
211 bool m_has_flatbuffer_schema_defined = false;
212 bb::Optional<TypeDetail> m_user_header_type_details_override;
213 bb::Optional<TypeDetail> m_payload_type_details_override;
214};
215
216template <typename Payload, typename UserHeader, ServiceType S>
218 iox2_service_builder_h handle)
219 : m_handle { iox2_service_builder_pub_sub(handle) } {
220}
221
222template <typename Payload, typename UserHeader, ServiceType S>
223template <typename U>
224inline auto ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::set_type_definition_name_hint()
225 -> std::enable_if_t<has_flatbuffer_marker<U>(), void> {
226 auto type_name = iox2::internal::get_type_name<typename Payload::ValueType>();
227 iox2_service_builder_pub_sub_type_definition_name_hint(
228 &m_handle, type_name.unchecked_access().c_str(), type_name.size(), "", 0);
229}
230
231template <typename Payload, typename UserHeader, ServiceType S>
232template <typename U>
233inline auto ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::set_type_definition_name_hint()
234 -> std::enable_if_t<!has_flatbuffer_marker<U>(), void> {
235}
236
237template <typename Payload, typename UserHeader, ServiceType S>
238inline void ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::set_parameters() {
239 if (m_enable_safe_overflow.has_value()) {
240 iox2_service_builder_pub_sub_set_enable_safe_overflow(&m_handle, m_enable_safe_overflow.value());
241 }
242 if (m_subscriber_max_borrowed_samples.has_value()) {
243 iox2_service_builder_pub_sub_set_subscriber_max_borrowed_samples(&m_handle,
244 m_subscriber_max_borrowed_samples.value());
245 }
246 if (m_history_size.has_value()) {
247 iox2_service_builder_pub_sub_set_history_size(&m_handle, m_history_size.value());
248 }
249 if (m_subscriber_max_buffer_size.has_value()) {
250 iox2_service_builder_pub_sub_set_subscriber_max_buffer_size(&m_handle, m_subscriber_max_buffer_size.value());
251 }
252 if (m_max_subscribers.has_value()) {
253 iox2_service_builder_pub_sub_set_max_subscribers(&m_handle, m_max_subscribers.value());
254 }
255 if (m_max_publishers.has_value()) {
256 iox2_service_builder_pub_sub_set_max_publishers(&m_handle, m_max_publishers.value());
257 }
258 if (m_payload_alignment.has_value()) {
259 iox2_service_builder_pub_sub_set_payload_alignment(&m_handle, m_payload_alignment.value());
260 }
261 if (m_max_nodes.has_value()) {
262 iox2_service_builder_pub_sub_set_max_nodes(&m_handle, m_max_nodes.value());
263 }
264
265 if (m_user_header_type_details_override.has_value()) {
266 override_user_header_type_details(m_user_header_type_details_override.value());
267 } else {
268 derive_user_header_type_details();
269 }
270
271 if (m_payload_type_details_override.has_value()) {
272 override_payload_type_details(m_payload_type_details_override.value());
273 } else {
274 derive_payload_type_details();
275 }
276
277 set_type_definition_name_hint();
278}
279
280template <typename Payload, typename UserHeader, ServiceType S>
281inline void ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::derive_user_header_type_details() {
282 // user header type details derived from the compile-time UserHeader
283 const auto header_layout = bb::Layout::from<UserHeader>();
284 const auto user_header_type_name = internal::get_type_name<UserHeader>();
285
286 const auto result =
287 iox2_service_builder_pub_sub_set_user_header_type_details(&m_handle,
288 iox2_type_variant_e_FIXED_SIZE,
289 user_header_type_name.unchecked_access().c_str(),
290 user_header_type_name.size(),
291 header_layout.size(),
292 header_layout.alignment());
293
294 if (result != IOX2_OK) {
295 IOX2_PANIC("This should never happen! Implementation failure while setting the User-Header-Type.");
296 }
297}
298
299template <typename Payload, typename UserHeader, ServiceType S>
300inline void
301ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::override_user_header_type_details(const TypeDetail& value) {
302 // user header type details provided at runtime
303 const auto type_variant =
304 value.variant() == TypeVariant::FixedSize ? iox2_type_variant_e_FIXED_SIZE : iox2_type_variant_e_DYNAMIC;
305
306 const auto result = iox2_service_builder_pub_sub_set_user_header_type_details(
307 &m_handle, type_variant, value.type_name(), std::strlen(value.type_name()), value.size(), value.alignment());
308
309 if (result != IOX2_OK) {
310 IOX2_PANIC("This should never happen! Implementation failure while setting the User-Header-Type.");
311 }
312}
313
314template <typename Payload, typename UserHeader, ServiceType S>
315inline void ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::derive_payload_type_details() {
316 using ValueType = typename PayloadInfo<Payload>::ValueType;
317
318 // payload type details derived from the compile-time Payload
319 const auto payload_type_name = internal::get_type_name<Payload>();
320 const auto type_variant =
321 bb::IsSlice<Payload>::VALUE ? iox2_type_variant_e_DYNAMIC : iox2_type_variant_e_FIXED_SIZE;
322
323 const auto result =
324 iox2_service_builder_pub_sub_set_payload_type_details(&m_handle,
325 type_variant,
326 payload_type_name.unchecked_access().c_str(),
327 payload_type_name.size(),
328 sizeof(ValueType),
329 alignof(ValueType));
330
331 if (result != IOX2_OK) {
332 IOX2_PANIC("This should never happen! Implementation failure while setting the Payload-Type.");
333 }
334}
335
336template <typename Payload, typename UserHeader, ServiceType S>
337inline void
338ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::override_payload_type_details(const TypeDetail& value) {
339 // payload type details provided at runtime
340 const auto type_variant =
341 value.variant() == TypeVariant::FixedSize ? iox2_type_variant_e_FIXED_SIZE : iox2_type_variant_e_DYNAMIC;
342
343 const auto result = iox2_service_builder_pub_sub_set_payload_type_details(
344 &m_handle, type_variant, value.type_name(), std::strlen(value.type_name()), value.size(), value.alignment());
345
346 if (result != IOX2_OK) {
347 IOX2_PANIC("This should never happen! Implementation failure while setting the Payload-Type.");
348 }
349}
350
351
352template <typename Payload, typename UserHeader, ServiceType S>
353template <typename NewHeader>
356 // required here since we just change the template header type but the builder structure stays the same
357 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
358 return std::move(*reinterpret_cast<ServiceBuilderPublishSubscribe<Payload, NewHeader, S>*>(this));
359}
360
361
362template <typename Payload, typename UserHeader, ServiceType S>
363template <typename U, typename>
366 iox2_service_builder_pub_sub_set_flatbuffer_schema_path(&m_handle, value.as_string().unchecked_access().c_str());
367 m_has_flatbuffer_schema_defined = true;
368 return std::move(*this);
369}
370
371template <typename Payload, typename UserHeader, ServiceType S>
376
377template <typename Payload, typename UserHeader, ServiceType S>
379 const TypeDetail& value)
380 -> std::enable_if_t<std::is_same<UserHeader, CustomHeaderMarker>::value> {
381 builder.m_user_header_type_details_override = bb::Optional<TypeDetail>(value);
382}
383
384template <typename Payload, typename UserHeader, ServiceType S>
386 const TypeDetail& value)
387 -> std::enable_if_t<std::is_same<Payload, bb::Slice<CustomPayloadMarker>>::value> {
388 builder.m_payload_type_details_override = bb::Optional<TypeDetail>(value);
389}
390
391template <typename Payload, typename UserHeader, ServiceType S>
393 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeOpenOrCreateError> {
394 set_parameters();
395
396 iox2_port_factory_pub_sub_h port_factory_handle {};
397 auto result = iox2_service_builder_pub_sub_open_or_create(m_handle, nullptr, &port_factory_handle);
398
399 if (result == IOX2_OK) {
400 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
401 }
402
403 return bb::err(bb::into<PublishSubscribeOpenOrCreateError>(result));
404}
405
406template <typename Payload, typename UserHeader, ServiceType S>
408 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeOpenError> {
409 set_parameters();
410
411 iox2_port_factory_pub_sub_h port_factory_handle {};
412 auto result = iox2_service_builder_pub_sub_open(m_handle, nullptr, &port_factory_handle);
413
414 if (result == IOX2_OK) {
415 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
416 }
417
418 return bb::err(bb::into<PublishSubscribeOpenError>(result));
419}
420
421template <typename Payload, typename UserHeader, ServiceType S>
423 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeCreateError> {
424 set_parameters();
425
426 iox2_port_factory_pub_sub_h port_factory_handle {};
427 auto result = iox2_service_builder_pub_sub_create(m_handle, nullptr, &port_factory_handle);
428
429 if (result == IOX2_OK) {
430 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
431 }
432
433 return bb::err(bb::into<PublishSubscribeCreateError>(result));
434}
435
436template <typename Payload, typename UserHeader, ServiceType S>
438 const AttributeVerifier&
441 set_parameters();
442
443 iox2_port_factory_pub_sub_h port_factory_handle {};
444 auto result = iox2_service_builder_pub_sub_open_or_create_with_attributes(
445 m_handle, &required_attributes.m_handle, nullptr, &port_factory_handle);
446
447 if (result == IOX2_OK) {
448 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
449 }
450
451 return bb::err(bb::into<PublishSubscribeOpenOrCreateError>(result));
452}
453
454template <typename Payload, typename UserHeader, ServiceType S>
456 const AttributeVerifier&
459 set_parameters();
460
461 iox2_port_factory_pub_sub_h port_factory_handle {};
462 auto result = iox2_service_builder_pub_sub_open_with_attributes(
463 m_handle, &required_attributes.m_handle, nullptr, &port_factory_handle);
464
465 if (result == IOX2_OK) {
466 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
467 }
468
469 return bb::err(bb::into<PublishSubscribeOpenError>(result));
470}
471
472template <typename Payload, typename UserHeader, ServiceType S>
476 set_parameters();
477
478 iox2_port_factory_pub_sub_h port_factory_handle {};
479 auto result = iox2_service_builder_pub_sub_create_with_attributes(
480 m_handle, &attributes.m_handle, nullptr, &port_factory_handle);
481
482 if (result == IOX2_OK) {
483 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
484 }
485
486 return bb::err(bb::into<PublishSubscribeCreateError>(result));
487}
488} // namespace iox2
489
490#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 flatbuffer_schema_path(const bb::FilePath &value) &&-> ServiceBuilderPublishSubscribe< U, UserHeader, S > &&
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.
Represents a path to a file. It is not allowed to end with a path separator since this would then be ...
Definition file_path.hpp:44
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