iceoryx2
C++ Bindings
Loading...
Searching...
No Matches
publisher.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_PUBLISHER_HPP
14#define IOX2_PUBLISHER_HPP
15
16#include "iox2/bb/expected.hpp"
17#include "iox2/bb/slice.hpp"
19#include "iox2/deployment/iceoryx2_cxx_feature_flags.hpp"
20#include "iox2/iceoryx2.h"
22#include "iox2/marker.hpp"
23#include "iox2/port_name.hpp"
24#include "iox2/sample_mut.hpp"
26#include "iox2/service_type.hpp"
28
29#include <cstdint>
30#include <type_traits>
31
32#if IOX2_FEATURE_FLATBUFFERS
34#include <flatbuffers/flatbuffer_builder.h>
35#endif
36
37namespace iox2 {
39template <ServiceType S, typename Payload, typename UserHeader>
40class Publisher {
41 using ValueType = typename PayloadInfo<Payload>::ValueType;
42
43 public:
44 Publisher(Publisher&& rhs) noexcept;
45 auto operator=(Publisher&& rhs) noexcept -> Publisher&;
46 ~Publisher();
47
48 Publisher(const Publisher&) = delete;
49 auto operator=(const Publisher&) -> Publisher& = delete;
50
52 auto id() const -> UniquePublisherId;
53
55 auto name() const -> PortNameView;
56
60
62 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
63 auto initial_max_slice_len() const -> uint64_t;
64
66 auto max_loaned_samples() const -> uint64_t;
67
70 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
72
76 template <typename T = Payload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
77 auto send_copy(const Payload& payload) const -> bb::Expected<size_t, SendError>;
78
82 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
83 auto send_slice_copy(bb::ImmutableSlice<ValueType>& payload) const -> bb::Expected<size_t, SendError>;
84
85#if IOX2_FEATURE_FLATBUFFERS
87 template <typename T = Payload, typename = std::enable_if_t<has_flatbuffer_marker<T>(), void>>
89#endif // IOX2_FEATURE_FLATBUFFERS
90
95 template <typename T = Payload,
96 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
98
104 template <typename T = Payload,
105 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
107
114 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
115 auto loan_slice(uint64_t number_of_elements) -> bb::Expected<SampleMut<S, T, UserHeader>, LoanError>;
116
121 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
123
131
132 private:
133 template <ServiceType, typename, typename>
135
136 explicit Publisher(iox2_publisher_h handle);
137 void drop();
138
139 iox2_publisher_h m_handle = nullptr;
140};
141
142template <ServiceType S, typename Payload, typename UserHeader>
143inline Publisher<S, Payload, UserHeader>::Publisher(iox2_publisher_h handle)
144 : m_handle { handle } {
145}
146
147template <ServiceType S, typename Payload, typename UserHeader>
148inline void Publisher<S, Payload, UserHeader>::drop() {
149 if (m_handle != nullptr) {
150 iox2_publisher_drop(m_handle);
151 m_handle = nullptr;
152 }
153}
154
155template <ServiceType S, typename Payload, typename UserHeader>
157 *this = std::move(rhs);
158}
159
160template <ServiceType S, typename Payload, typename UserHeader>
162 if (this != &rhs) {
163 drop();
164 m_handle = rhs.m_handle;
165 rhs.m_handle = nullptr;
166 }
167
168 return *this;
169}
170
171template <ServiceType S, typename Payload, typename UserHeader>
175
176template <ServiceType S, typename Payload, typename UserHeader>
178 return iox2::bb::into<BackpressureStrategy>(static_cast<int>(iox2_publisher_backpressure_strategy(&m_handle)));
179}
180
181
182template <ServiceType S, typename Payload, typename UserHeader>
183template <typename T, typename>
185 return iox2_publisher_initial_max_slice_len(&m_handle);
186}
187
188template <ServiceType S, typename Payload, typename UserHeader>
190 return iox2_publisher_max_loaned_samples(&m_handle);
191}
192
193template <ServiceType S, typename Payload, typename UserHeader>
194template <typename T, typename>
196 return iox2::bb::into<AllocationStrategy>(static_cast<int>(iox2_publisher_allocation_strategy(&m_handle)));
197}
198
199template <ServiceType S, typename Payload, typename UserHeader>
201 iox2_unique_publisher_id_h id_handle = nullptr;
202
203 iox2_publisher_id(&m_handle, nullptr, &id_handle);
204 return UniquePublisherId { id_handle };
205}
206
207template <ServiceType S, typename Payload, typename UserHeader>
209 const auto* port_name_ptr = iox2_publisher_name(&m_handle);
210 return PortNameView::from_native_ptr(port_name_ptr);
211}
212
213template <ServiceType S, typename Payload, typename UserHeader>
214template <typename T, typename>
215inline auto Publisher<S, Payload, UserHeader>::send_copy(const Payload& payload) const
217 static_assert(std::is_trivially_copyable<Payload>::value,
218 "The publisher supports only trivially copyable payload types.");
219
220 size_t number_of_recipients = 0;
221 auto result =
222 iox2_publisher_send_copy(&m_handle, static_cast<const void*>(&payload), sizeof(Payload), &number_of_recipients);
223
224 if (result == IOX2_OK) {
225 return number_of_recipients;
226 }
227
228 return bb::err(iox2::bb::into<SendError>(result));
229}
230
231template <ServiceType S, typename Payload, typename UserHeader>
232template <typename T, typename>
235 size_t number_of_recipients = 0;
236 auto result = iox2_publisher_send_slice_copy(&m_handle,
237 payload.data(),
238 sizeof(typename Payload::ValueType),
239 payload.number_of_elements(),
240 &number_of_recipients);
241
242 if (result == IOX2_OK) {
243 return number_of_recipients;
244 }
245
246 return bb::err(iox2::bb::into<SendError>(result));
247}
248
249#if IOX2_FEATURE_FLATBUFFERS
250
251template <ServiceType S, typename Payload, typename UserHeader>
252template <typename T, typename>
256
257 auto result = iox2_publisher_loan_slice_uninit(&m_handle, &sample.m_sample.m_sample, &sample.m_sample.m_handle, 1);
258
259 if (result != IOX2_OK) {
260 return bb::err(iox2::bb::into<LoanError>(result));
261 }
262
263 iox2_resizable_memory_publish_subscribe_h resizable_memory_handle {};
264 iox2_sample_mut_create_resizable_memory(&sample.m_sample.m_handle, nullptr, &resizable_memory_handle);
265
266 // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) The FlatBufferBuilder takes the ownership and the external interface requires a raw pointer.
267 sample.m_memory = new internal::ResizableMemoryPublishSubscribe<S>(resizable_memory_handle);
268
269 auto initial_size = sample.m_memory->len();
270 sample.m_flatbuffer_builder = flatbuffers::FlatBufferBuilder(initial_size, sample.m_memory, true);
271
272 return std::move(sample);
273}
274
275#endif // IOX2_FEATURE_FLATBUFFERS
276
277template <ServiceType S, typename Payload, typename UserHeader>
278template <typename T, typename>
282
283 auto result = iox2_publisher_loan_slice_uninit(&m_handle, &sample.m_sample.m_sample, &sample.m_sample.m_handle, 1);
285
286 if (result == IOX2_OK) {
287 return std::move(sample);
288 }
289
290 return bb::err(iox2::bb::into<LoanError>(result));
291}
292
293template <ServiceType S, typename Payload, typename UserHeader>
294template <typename T, typename>
296 auto sample = loan_uninit();
297
298 if (!sample.has_value()) {
299 return bb::err(sample.error());
300 }
301
302 new (&sample->payload_mut()) Payload();
303
304 return assume_init(std::move(*sample));
305}
306
307template <ServiceType S, typename Payload, typename UserHeader>
308template <typename T, typename>
309inline auto Publisher<S, Payload, UserHeader>::loan_slice(const uint64_t number_of_elements)
311 auto sample_uninit = loan_slice_uninit(number_of_elements);
312
313 if (!sample_uninit.has_value()) {
314 return bb::err(sample_uninit.error());
315 }
316 auto sample_init = std::move(sample_uninit.value());
317
318 for (auto& item : sample_init.payload_mut()) {
319 new (&item) ValueType();
320 }
321
322 return assume_init(std::move(sample_init));
323}
324
325template <ServiceType S, typename Payload, typename UserHeader>
326template <typename T, typename>
327inline auto Publisher<S, Payload, UserHeader>::loan_slice_uninit(const uint64_t number_of_elements)
330
331 auto result = iox2_publisher_loan_slice_uninit(
332 &m_handle, &sample.m_sample.m_sample, &sample.m_sample.m_handle, number_of_elements);
334
335 if (result == IOX2_OK) {
336 return std::move(sample);
337 }
338
339 return bb::err(iox2::bb::into<LoanError>(result));
340}
341
342template <ServiceType S, typename Payload, typename UserHeader>
344 auto result = iox2_publisher_update_connections(&m_handle);
345 if (result != IOX2_OK) {
346 return bb::err(iox2::bb::into<ConnectionFailure>(result));
347 }
348
349 return {};
350}
351} // namespace iox2
352
353#endif
Non-owning view of a [PortName].
Definition port_name.hpp:25
static auto from_native_ptr(iox2_port_name_ptr m_ptr) -> PortNameView
Creates a [PortNameView] from a native [iox2_port_name_ptr].
Sending endpoint of a publish-subscriber based communication.
Definition publisher.hpp:40
auto loan() -> bb::Expected< SampleMut< S, Payload, UserHeader >, LoanError >
auto operator=(Publisher &&rhs) noexcept -> Publisher &
auto id() const -> UniquePublisherId
Returns the [UniquePublisherId] of the [Publisher].
auto loan_uninit() -> bb::Expected< SampleMutUninit< S, Payload, UserHeader >, LoanError >
auto loan_flatbuffer() -> bb::Expected< SampleMutUninit< S, Payload, UserHeader >, LoanError >
Acquires a [SampleMutUninit] with an integrated flatbuffer builder.
auto loan_slice_uninit(uint64_t number_of_elements) -> bb::Expected< SampleMutUninit< S, T, UserHeader >, LoanError >
auto initial_max_slice_len() const -> uint64_t
Returns the maximum number of elements that can be loaned in a slice.
auto send_copy(const Payload &payload) const -> bb::Expected< size_t, SendError >
auto allocation_strategy() const -> AllocationStrategy
auto name() const -> PortNameView
Returns the [PortNameView] of the [Publisher].
Publisher(Publisher &&rhs) noexcept
auto update_connections() -> bb::Expected< void, ConnectionFailure >
Publisher(const Publisher &)=delete
auto max_loaned_samples() const -> uint64_t
Returns the maximum number of [SampleMut] that can be loaned in parallel.
auto backpressure_strategy() const -> BackpressureStrategy
auto operator=(const Publisher &) -> Publisher &=delete
auto loan_slice(uint64_t number_of_elements) -> bb::Expected< SampleMut< S, T, UserHeader >, LoanError >
auto send_slice_copy(bb::ImmutableSlice< ValueType > &payload) const -> bb::Expected< size_t, SendError >
The system-wide unique id of a [Publisher].
A class representing a slice of contiguous elements of type T.
Definition slice.hpp:31
Internal helper class to handle dynamic memory allocations used in e.g. flatbuffers.
constexpr auto err(const E &error) -> Unexpected< E >
Definition expected.hpp:33
iox2::bb::variation::Expected< T, E > Expected
Definition expected.hpp:22
SendError
Failure that can be emitted when data is sent.
auto assume_init(RequestMutUninit< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader > &&self) -> RequestMut< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader >
auto loan_uninit(EntryHandleMut< S, KeyType, ValueType > &&self) -> EntryValueUninit< S, KeyType, ValueType >
static void placement_default(S &payload)
Definition helper.hpp:22