iceoryx2
C++ Language 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/iceoryx2.h"
20#include "iox2/iceoryx2_cxx_deployment.hpp"
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
68 template <typename T = Payload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
69 auto send_copy(const Payload& payload) const -> bb::Expected<size_t, SendError>;
70
74 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
75 auto send_slice_copy(bb::ImmutableSlice<ValueType>& payload) const -> bb::Expected<size_t, SendError>;
76
77#if IOX2_FEATURE_FLATBUFFERS
79 template <typename T = Payload, typename = std::enable_if_t<has_flatbuffer_marker<T>(), void>>
81#endif // IOX2_FEATURE_FLATBUFFERS
82
87 template <typename T = Payload,
88 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
90
96 template <typename T = Payload,
97 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
99
106 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
107 auto loan_slice(uint64_t number_of_elements) -> bb::Expected<SampleMut<S, T, UserHeader>, LoanError>;
108
113 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
115
123
124 private:
125 template <ServiceType, typename, typename>
127
128 explicit Publisher(iox2_publisher_h handle);
129 void drop();
130
131 iox2_publisher_h m_handle = nullptr;
132};
133
134template <ServiceType S, typename Payload, typename UserHeader>
135inline Publisher<S, Payload, UserHeader>::Publisher(iox2_publisher_h handle)
136 : m_handle { handle } {
137}
138
139template <ServiceType S, typename Payload, typename UserHeader>
140inline void Publisher<S, Payload, UserHeader>::drop() {
141 if (m_handle != nullptr) {
142 iox2_publisher_drop(m_handle);
143 m_handle = nullptr;
144 }
145}
146
147template <ServiceType S, typename Payload, typename UserHeader>
149 *this = std::move(rhs);
150}
151
152template <ServiceType S, typename Payload, typename UserHeader>
154 if (this != &rhs) {
155 drop();
156 m_handle = rhs.m_handle;
157 rhs.m_handle = nullptr;
158 }
159
160 return *this;
161}
162
163template <ServiceType S, typename Payload, typename UserHeader>
167
168template <ServiceType S, typename Payload, typename UserHeader>
170 return iox2::bb::into<BackpressureStrategy>(static_cast<int>(iox2_publisher_backpressure_strategy(&m_handle)));
171}
172
173
174template <ServiceType S, typename Payload, typename UserHeader>
175template <typename T, typename>
177 return iox2_publisher_initial_max_slice_len(&m_handle);
178}
179
180template <ServiceType S, typename Payload, typename UserHeader>
182 iox2_unique_publisher_id_h id_handle = nullptr;
183
184 iox2_publisher_id(&m_handle, nullptr, &id_handle);
185 return UniquePublisherId { id_handle };
186}
187
188template <ServiceType S, typename Payload, typename UserHeader>
190 const auto* port_name_ptr = iox2_publisher_name(&m_handle);
191 return PortNameView::from_native_ptr(port_name_ptr);
192}
193
194template <ServiceType S, typename Payload, typename UserHeader>
195template <typename T, typename>
196inline auto Publisher<S, Payload, UserHeader>::send_copy(const Payload& payload) const
198 static_assert(std::is_trivially_copyable<Payload>::value,
199 "The publisher supports only trivially copyable payload types.");
200
201 size_t number_of_recipients = 0;
202 auto result =
203 iox2_publisher_send_copy(&m_handle, static_cast<const void*>(&payload), sizeof(Payload), &number_of_recipients);
204
205 if (result == IOX2_OK) {
206 return number_of_recipients;
207 }
208
209 return bb::err(iox2::bb::into<SendError>(result));
210}
211
212template <ServiceType S, typename Payload, typename UserHeader>
213template <typename T, typename>
216 size_t number_of_recipients = 0;
217 auto result = iox2_publisher_send_slice_copy(&m_handle,
218 payload.data(),
219 sizeof(typename Payload::ValueType),
220 payload.number_of_elements(),
221 &number_of_recipients);
222
223 if (result == IOX2_OK) {
224 return number_of_recipients;
225 }
226
227 return bb::err(iox2::bb::into<SendError>(result));
228}
229
230#if IOX2_FEATURE_FLATBUFFERS
231
232template <ServiceType S, typename Payload, typename UserHeader>
233template <typename T, typename>
237
238 auto result = iox2_publisher_loan_slice_uninit(&m_handle, &sample.m_sample.m_sample, &sample.m_sample.m_handle, 1);
239
240 if (result != IOX2_OK) {
241 return bb::err(iox2::bb::into<LoanError>(result));
242 }
243
244 iox2_resizable_memory_publish_subscribe_h resizable_memory_handle {};
245 iox2_sample_mut_create_resizable_memory_builder(&sample.m_sample.m_handle, nullptr, &resizable_memory_handle);
246
247 // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) The FlatBufferBuilder takes the ownership and the external interface requires a raw pointer.
248 sample.m_memory = new internal::ResizableMemoryPublishSubscribe<S>(resizable_memory_handle);
249
250 auto initial_size = sample.m_memory->len();
251 sample.m_flatbuffer_builder = flatbuffers::FlatBufferBuilder(initial_size, sample.m_memory, true);
252
253 return std::move(sample);
254}
255
256#endif // IOX2_FEATURE_FLATBUFFERS
257
258template <ServiceType S, typename Payload, typename UserHeader>
259template <typename T, typename>
263
264 auto result = iox2_publisher_loan_slice_uninit(&m_handle, &sample.m_sample.m_sample, &sample.m_sample.m_handle, 1);
266
267 if (result == IOX2_OK) {
268 return std::move(sample);
269 }
270
271 return bb::err(iox2::bb::into<LoanError>(result));
272}
273
274template <ServiceType S, typename Payload, typename UserHeader>
275template <typename T, typename>
277 auto sample = loan_uninit();
278
279 if (!sample.has_value()) {
280 return bb::err(sample.error());
281 }
282
283 new (&sample->payload_mut()) Payload();
284
285 return assume_init(std::move(*sample));
286}
287
288template <ServiceType S, typename Payload, typename UserHeader>
289template <typename T, typename>
290inline auto Publisher<S, Payload, UserHeader>::loan_slice(const uint64_t number_of_elements)
292 auto sample_uninit = loan_slice_uninit(number_of_elements);
293
294 if (!sample_uninit.has_value()) {
295 return bb::err(sample_uninit.error());
296 }
297 auto sample_init = std::move(sample_uninit.value());
298
299 for (auto& item : sample_init.payload_mut()) {
300 new (&item) ValueType();
301 }
302
303 return assume_init(std::move(sample_init));
304}
305
306template <ServiceType S, typename Payload, typename UserHeader>
307template <typename T, typename>
308inline auto Publisher<S, Payload, UserHeader>::loan_slice_uninit(const uint64_t number_of_elements)
311
312 auto result = iox2_publisher_loan_slice_uninit(
313 &m_handle, &sample.m_sample.m_sample, &sample.m_sample.m_handle, number_of_elements);
315
316 if (result == IOX2_OK) {
317 return std::move(sample);
318 }
319
320 return bb::err(iox2::bb::into<LoanError>(result));
321}
322
323template <ServiceType S, typename Payload, typename UserHeader>
325 auto result = iox2_publisher_update_connections(&m_handle);
326 if (result != IOX2_OK) {
327 return bb::err(iox2::bb::into<ConnectionFailure>(result));
328 }
329
330 return {};
331}
332} // namespace iox2
333
334#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_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 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 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 >
auto payload_mut() -> ValueType &
Returns a reference to the payload of the sample.
The system-wide unique id of a [Publisher].
A class representing a slice of contiguous elements of type T.
Definition slice.hpp:31
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