iceoryx2
C++ 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 bb::Optional<TypeDetail> m_user_header_type_details_override;
212 bb::Optional<TypeDetail> m_payload_type_details_override;
213};
214
215template <typename Payload, typename UserHeader, ServiceType S>
217 iox2_service_builder_h handle)
218 : m_handle { iox2_service_builder_pub_sub(handle) } {
219}
220
221template <typename Payload, typename UserHeader, ServiceType S>
222template <typename U>
223inline auto ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::set_type_definition_name_hint()
224 -> std::enable_if_t<has_flatbuffer_marker<U>(), void> {
225 auto type_name = iox2::internal::get_type_name<typename Payload::ValueType>();
226 iox2_service_builder_pub_sub_type_definition_name_hint(
227 &m_handle, type_name.unchecked_access().c_str(), type_name.size(), "", 0);
228}
229
230template <typename Payload, typename UserHeader, ServiceType S>
231template <typename U>
232inline auto ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::set_type_definition_name_hint()
233 -> std::enable_if_t<!has_flatbuffer_marker<U>(), void> {
234}
235
236template <typename Payload, typename UserHeader, ServiceType S>
237inline void ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::set_parameters() {
238 if (m_enable_safe_overflow.has_value()) {
239 iox2_service_builder_pub_sub_set_enable_safe_overflow(&m_handle, m_enable_safe_overflow.value());
240 }
241 if (m_subscriber_max_borrowed_samples.has_value()) {
242 iox2_service_builder_pub_sub_set_subscriber_max_borrowed_samples(&m_handle,
243 m_subscriber_max_borrowed_samples.value());
244 }
245 if (m_history_size.has_value()) {
246 iox2_service_builder_pub_sub_set_history_size(&m_handle, m_history_size.value());
247 }
248 if (m_subscriber_max_buffer_size.has_value()) {
249 iox2_service_builder_pub_sub_set_subscriber_max_buffer_size(&m_handle, m_subscriber_max_buffer_size.value());
250 }
251 if (m_max_subscribers.has_value()) {
252 iox2_service_builder_pub_sub_set_max_subscribers(&m_handle, m_max_subscribers.value());
253 }
254 if (m_max_publishers.has_value()) {
255 iox2_service_builder_pub_sub_set_max_publishers(&m_handle, m_max_publishers.value());
256 }
257 if (m_payload_alignment.has_value()) {
258 iox2_service_builder_pub_sub_set_payload_alignment(&m_handle, m_payload_alignment.value());
259 }
260 if (m_max_nodes.has_value()) {
261 iox2_service_builder_pub_sub_set_max_nodes(&m_handle, m_max_nodes.value());
262 }
263
264 if (m_user_header_type_details_override.has_value()) {
265 override_user_header_type_details(m_user_header_type_details_override.value());
266 } else {
267 derive_user_header_type_details();
268 }
269
270 if (m_payload_type_details_override.has_value()) {
271 override_payload_type_details(m_payload_type_details_override.value());
272 } else {
273 derive_payload_type_details();
274 }
275
276 set_type_definition_name_hint();
277}
278
279template <typename Payload, typename UserHeader, ServiceType S>
280inline void ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::derive_user_header_type_details() {
281 // user header type details derived from the compile-time UserHeader
282 const auto header_layout = bb::Layout::from<UserHeader>();
283 const auto user_header_type_name = internal::get_type_name<UserHeader>();
284
285 const auto result =
286 iox2_service_builder_pub_sub_set_user_header_type_details(&m_handle,
287 iox2_type_variant_e_FIXED_SIZE,
288 user_header_type_name.unchecked_access().c_str(),
289 user_header_type_name.size(),
290 header_layout.size(),
291 header_layout.alignment());
292
293 if (result != IOX2_OK) {
294 IOX2_PANIC("This should never happen! Implementation failure while setting the User-Header-Type.");
295 }
296}
297
298template <typename Payload, typename UserHeader, ServiceType S>
299inline void
300ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::override_user_header_type_details(const TypeDetail& value) {
301 // user header type details provided at runtime
302 const auto type_variant =
303 value.variant() == TypeVariant::FixedSize ? iox2_type_variant_e_FIXED_SIZE : iox2_type_variant_e_DYNAMIC;
304
305 const auto result = iox2_service_builder_pub_sub_set_user_header_type_details(
306 &m_handle, type_variant, value.type_name(), std::strlen(value.type_name()), value.size(), value.alignment());
307
308 if (result != IOX2_OK) {
309 IOX2_PANIC("This should never happen! Implementation failure while setting the User-Header-Type.");
310 }
311}
312
313template <typename Payload, typename UserHeader, ServiceType S>
314inline void ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::derive_payload_type_details() {
315 using ValueType = typename PayloadInfo<Payload>::ValueType;
316
317 // payload type details derived from the compile-time Payload
318 const auto payload_type_name = internal::get_type_name<Payload>();
319 const auto type_variant =
320 bb::IsSlice<Payload>::VALUE ? iox2_type_variant_e_DYNAMIC : iox2_type_variant_e_FIXED_SIZE;
321
322 const auto result =
323 iox2_service_builder_pub_sub_set_payload_type_details(&m_handle,
324 type_variant,
325 payload_type_name.unchecked_access().c_str(),
326 payload_type_name.size(),
327 sizeof(ValueType),
328 alignof(ValueType));
329
330 if (result != IOX2_OK) {
331 IOX2_PANIC("This should never happen! Implementation failure while setting the Payload-Type.");
332 }
333}
334
335template <typename Payload, typename UserHeader, ServiceType S>
336inline void
337ServiceBuilderPublishSubscribe<Payload, UserHeader, S>::override_payload_type_details(const TypeDetail& value) {
338 // payload type details provided at runtime
339 const auto type_variant =
340 value.variant() == TypeVariant::FixedSize ? iox2_type_variant_e_FIXED_SIZE : iox2_type_variant_e_DYNAMIC;
341
342 const auto result = iox2_service_builder_pub_sub_set_payload_type_details(
343 &m_handle, type_variant, value.type_name(), std::strlen(value.type_name()), value.size(), value.alignment());
344
345 if (result != IOX2_OK) {
346 IOX2_PANIC("This should never happen! Implementation failure while setting the Payload-Type.");
347 }
348}
349
350
351template <typename Payload, typename UserHeader, ServiceType S>
352template <typename NewHeader>
355 // required here since we just change the template header type but the builder structure stays the same
356 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
357 return std::move(*reinterpret_cast<ServiceBuilderPublishSubscribe<Payload, NewHeader, S>*>(this));
358}
359
360
361template <typename Payload, typename UserHeader, ServiceType S>
362template <typename U, typename>
365 iox2_service_builder_pub_sub_set_flatbuffer_schema_path(&m_handle, value.as_string().unchecked_access().c_str());
366 return std::move(*this);
367}
368
369template <typename Payload, typename UserHeader, ServiceType S>
374
375template <typename Payload, typename UserHeader, ServiceType S>
377 const TypeDetail& value)
378 -> std::enable_if_t<std::is_same<UserHeader, CustomHeaderMarker>::value> {
379 builder.m_user_header_type_details_override = bb::Optional<TypeDetail>(value);
380}
381
382template <typename Payload, typename UserHeader, ServiceType S>
384 const TypeDetail& value)
385 -> std::enable_if_t<std::is_same<Payload, bb::Slice<CustomPayloadMarker>>::value> {
386 builder.m_payload_type_details_override = bb::Optional<TypeDetail>(value);
387}
388
389template <typename Payload, typename UserHeader, ServiceType S>
391 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeOpenOrCreateError> {
392 set_parameters();
393
394 iox2_port_factory_pub_sub_h port_factory_handle {};
395 auto result = iox2_service_builder_pub_sub_open_or_create(m_handle, nullptr, &port_factory_handle);
396
397 if (result == IOX2_OK) {
398 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
399 }
400
401 return bb::err(bb::into<PublishSubscribeOpenOrCreateError>(result));
402}
403
404template <typename Payload, typename UserHeader, ServiceType S>
406 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeOpenError> {
407 set_parameters();
408
409 iox2_port_factory_pub_sub_h port_factory_handle {};
410 auto result = iox2_service_builder_pub_sub_open(m_handle, nullptr, &port_factory_handle);
411
412 if (result == IOX2_OK) {
413 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
414 }
415
416 return bb::err(bb::into<PublishSubscribeOpenError>(result));
417}
418
419template <typename Payload, typename UserHeader, ServiceType S>
421 Expected<PortFactoryPublishSubscribe<S, Payload, UserHeader>, PublishSubscribeCreateError> {
422 set_parameters();
423
424 iox2_port_factory_pub_sub_h port_factory_handle {};
425 auto result = iox2_service_builder_pub_sub_create(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<PublishSubscribeCreateError>(result));
432}
433
434template <typename Payload, typename UserHeader, ServiceType S>
436 const AttributeVerifier&
439 set_parameters();
440
441 iox2_port_factory_pub_sub_h port_factory_handle {};
442 auto result = iox2_service_builder_pub_sub_open_or_create_with_attributes(
443 m_handle, &required_attributes.m_handle, nullptr, &port_factory_handle);
444
445 if (result == IOX2_OK) {
446 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
447 }
448
449 return bb::err(bb::into<PublishSubscribeOpenOrCreateError>(result));
450}
451
452template <typename Payload, typename UserHeader, ServiceType S>
454 const AttributeVerifier&
457 set_parameters();
458
459 iox2_port_factory_pub_sub_h port_factory_handle {};
460 auto result = iox2_service_builder_pub_sub_open_with_attributes(
461 m_handle, &required_attributes.m_handle, nullptr, &port_factory_handle);
462
463 if (result == IOX2_OK) {
464 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
465 }
466
467 return bb::err(bb::into<PublishSubscribeOpenError>(result));
468}
469
470template <typename Payload, typename UserHeader, ServiceType S>
474 set_parameters();
475
476 iox2_port_factory_pub_sub_h port_factory_handle {};
477 auto result = iox2_service_builder_pub_sub_create_with_attributes(
478 m_handle, &attributes.m_handle, nullptr, &port_factory_handle);
479
480 if (result == IOX2_OK) {
481 return PortFactoryPublishSubscribe<S, Payload, UserHeader>(port_factory_handle);
482 }
483
484 return bb::err(bb::into<PublishSubscribeCreateError>(result));
485}
486} // namespace iox2
487
488#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