iceoryx2
C++ Language Bindings
Loading...
Searching...
No Matches
service_builder_blackboard.hpp
Go to the documentation of this file.
1// Copyright (c) 2025 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_BLACKBOARD_BUILDER_HPP
14#define IOX2_SERVICE_BLACKBOARD_BUILDER_HPP
15
19#include "iox2/bb/expected.hpp"
23#include "iox2/service_type.hpp"
24
25#include <cstdint>
26#include <type_traits>
27
28namespace iox2 {
30template <typename KeyType, ServiceType S>
32 public:
33 static_assert(std::is_trivially_copyable<KeyType>::value,
34 "The blackboard supports only trivially copyable key types.");
35 static_assert(std::alignment_of<KeyType>() <= IOX2_MAX_BLACKBOARD_KEY_ALIGNMENT,
36 "The blackboard supports only key types with an alignment <= IOX2_MAX_BLACKBOARD_KEY_ALIGNMENT.");
37 static_assert(sizeof(KeyType) <= IOX2_MAX_BLACKBOARD_KEY_SIZE,
38 "The blackboard supports only key types with a size <= IOX2_MAX_BLACKBOARD_KEY_SIZE.");
39
40
42#ifdef DOXYGEN_MACRO_FIX
43 auto max_readers(const uint64_t value) -> decltype(auto);
44#else
46#endif
47
49#ifdef DOXYGEN_MACRO_FIX
50 auto max_nodes(const uint64_t value) -> decltype(auto);
51#else
53#endif
54
55 public:
57 template <typename ValueType>
58 auto add(KeyType key, ValueType value) -> ServiceBuilderBlackboardCreator&&;
59
61 template <typename ValueType>
63
66
68 auto
71
72 private:
73 template <ServiceType>
74 friend class ServiceBuilder;
75
76 explicit ServiceBuilderBlackboardCreator(iox2_service_builder_h handle);
77
78 void set_parameters();
79
80 iox2_service_builder_blackboard_creator_h m_handle = nullptr;
81};
82
83template <typename KeyType, ServiceType S>
85 public:
87#ifdef DOXYGEN_MACRO_FIX
88 auto max_readers(const uint64_t value) -> decltype(auto);
89#else
91#endif
92
94#ifdef DOXYGEN_MACRO_FIX
95 auto max_nodes(const uint64_t value) -> decltype(auto);
96#else
98#endif
99
100 public:
103
107 const AttributeVerifier&
109
110 private:
111 template <ServiceType>
112 friend class ServiceBuilder;
113
114 explicit ServiceBuilderBlackboardOpener(iox2_service_builder_h handle);
115
116 void set_parameters();
117
118 iox2_service_builder_blackboard_opener_h m_handle = nullptr;
119};
120
121namespace internal {
122template <typename T>
123auto default_key_eq_cmp_func(const void* lhs, const void* rhs) -> bool {
124 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): C API requires to pass void* instead of T*
125 return (*reinterpret_cast<const T*>(lhs)) == (*reinterpret_cast<const T*>(rhs));
126}
127} // namespace internal
128
129template <typename KeyType, ServiceType S>
130inline ServiceBuilderBlackboardCreator<KeyType, S>::ServiceBuilderBlackboardCreator(iox2_service_builder_h handle)
131 : m_handle { iox2_service_builder_blackboard_creator(handle) } {
132 // set key type details so that these are available in add()
133 const auto type_name = internal::get_type_name<KeyType>();
134 const auto key_type_result = iox2_service_builder_blackboard_creator_set_key_type_details(
135 &m_handle, type_name.unchecked_access().c_str(), type_name.size(), sizeof(KeyType), alignof(KeyType));
136 if (key_type_result != IOX2_OK) {
137 IOX2_PANIC("This should never happen! Implementation failure while setting the key type.");
138 }
139}
140
141template <typename KeyType, ServiceType S>
142inline void ServiceBuilderBlackboardCreator<KeyType, S>::set_parameters() {
143 if (m_max_readers.has_value()) {
144 iox2_service_builder_blackboard_creator_set_max_readers(&m_handle, m_max_readers.value());
145 }
146 if (m_max_nodes.has_value()) {
147 iox2_service_builder_blackboard_creator_set_max_nodes(&m_handle, m_max_nodes.value());
148 }
149
150 // key eq comparison function
151 iox2_service_builder_blackboard_creator_set_key_eq_comparison_function(&m_handle,
152 internal::default_key_eq_cmp_func<KeyType>);
153}
154
155template <typename KeyType, ServiceType S>
156template <typename ValueType>
157inline auto ServiceBuilderBlackboardCreator<KeyType, S>::add(KeyType key, ValueType value)
159 static_assert(std::is_trivially_copyable<ValueType>::value,
160 "The blackboard supports only trivially copyable value types.");
161
162 // NOLINTNEXTLINE(cppcoreguidelines-owning-memory): required by C API
163 auto value_ptr = new ValueType(value);
164 const auto type_name = internal::get_type_name<ValueType>();
165
166 iox2_service_builder_blackboard_creator_add(
167 &m_handle,
168 &key,
169 value_ptr,
170 [](void* value) -> auto {
171 auto* value_ptr = static_cast<ValueType*>(value);
172 if (value_ptr != nullptr) {
173 // NOLINTNEXTLINE(cppcoreguidelines-owning-memory): required by C API
174 delete value_ptr;
175 value_ptr = nullptr;
176 }
177 },
178 type_name.unchecked_access().c_str(),
179 type_name.size(),
180 sizeof(ValueType),
181 alignof(ValueType));
182
183 return std::move(*this);
184}
185
186template <typename KeyType, ServiceType S>
187template <typename ValueType>
190 return add(key, ValueType());
191}
192
193template <typename KeyType, ServiceType S>
196 set_parameters();
197
198 iox2_port_factory_blackboard_h port_factory_handle {};
199 auto result = iox2_service_builder_blackboard_create(m_handle, nullptr, &port_factory_handle);
200
201 if (result == IOX2_OK) {
202 return PortFactoryBlackboard<S, KeyType>(port_factory_handle);
203 }
204
205 return bb::err(bb::into<BlackboardCreateError>(result));
206}
207
208template <typename KeyType, ServiceType S>
211 set_parameters();
212
213 iox2_port_factory_blackboard_h port_factory_handle {};
214 auto result = iox2_service_builder_blackboard_create_with_attributes(
215 m_handle, &attributes.m_handle, nullptr, &port_factory_handle);
216
217 if (result == IOX2_OK) {
218 return PortFactoryBlackboard<S, KeyType>(port_factory_handle);
219 }
220
221 return bb::err(bb::into<BlackboardCreateError>(result));
222}
223
224template <typename KeyType, ServiceType S>
226 : m_handle { iox2_service_builder_blackboard_opener(handle) } {
227}
228
229template <typename KeyType, ServiceType S>
230inline void ServiceBuilderBlackboardOpener<KeyType, S>::set_parameters() {
231 if (m_max_readers.has_value()) {
232 iox2_service_builder_blackboard_opener_set_max_readers(&m_handle, m_max_readers.value());
233 }
234 if (m_max_nodes.has_value()) {
235 iox2_service_builder_blackboard_opener_set_max_nodes(&m_handle, m_max_nodes.value());
236 }
237
238 // key type details
239 const auto type_name = internal::get_type_name<KeyType>();
240 const auto key_type_result = iox2_service_builder_blackboard_opener_set_key_type_details(
241 &m_handle, type_name.unchecked_access().c_str(), type_name.size(), sizeof(KeyType), alignof(KeyType));
242 if (key_type_result != IOX2_OK) {
243 IOX2_PANIC("This should never happen! Implementation failure while setting the Key-Type.");
244 }
245}
246
247template <typename KeyType, ServiceType S>
250 set_parameters();
251
252 iox2_port_factory_blackboard_h port_factory_handle {};
253 auto result = iox2_service_builder_blackboard_open(m_handle, nullptr, &port_factory_handle);
254
255 if (result == IOX2_OK) {
256 return PortFactoryBlackboard<S, KeyType>(port_factory_handle);
257 }
258
259 return bb::err(bb::into<BlackboardOpenError>(result));
260}
261
262template <typename KeyType, ServiceType S>
264 const AttributeVerifier&
266 set_parameters();
267
268 iox2_port_factory_blackboard_h port_factory_handle {};
269 auto result = iox2_service_builder_blackboard_open_with_attributes(
270 m_handle, &required_attributes.m_handle, nullptr, &port_factory_handle);
271
272 if (result == IOX2_OK) {
273 return PortFactoryBlackboard<S, KeyType>(port_factory_handle);
274 }
275
276 return bb::err(bb::into<BlackboardOpenError>(result));
277}
278} // namespace iox2
279
280#endif
#define IOX2_PANIC(message)
calls panic handler and does not return
#define IOX2_BUILDER_OPTIONAL(type, name)
Definition builder.hpp:47
Represents the port factory of a [Service] with [MessagingPattern::Blackboard].
Builder to create new [MessagingPattern::Blackboard] based [Service]s.
auto create_with_attributes(const AttributeSpecifier &attributes) &&-> bb::Expected< PortFactoryBlackboard< S, KeyType >, BlackboardCreateError >
Creates a new [Service] with a set of attributes.
auto max_nodes(const uint64_t value) -> decltype(auto)
Defines how many [Node]s shall be able to open it in parallel.
auto add(KeyType key, ValueType value) -> ServiceBuilderBlackboardCreator &&
Adds key-value pairs to the blackboard.
auto create() &&-> bb::Expected< PortFactoryBlackboard< S, KeyType >, BlackboardCreateError >
Creates a new [Service].
auto max_readers(const uint64_t value) -> decltype(auto)
Defines how many [Reader]s shall be supported at most.
auto add_with_default(KeyType key) -> ServiceBuilderBlackboardCreator &&
Adds key-value pairs to the blackboard where value is a default value.
auto max_nodes(const uint64_t value) -> decltype(auto)
Defines how many [Node]s must be at least supported.
auto open() &&-> bb::Expected< PortFactoryBlackboard< S, KeyType >, BlackboardOpenError >
Opens an existing [Service].
auto max_readers(const uint64_t value) -> decltype(auto)
Defines how many [Reader]s must be at least supported.
auto open_with_attributes(const AttributeVerifier &required_attributes) &&-> bb::Expected< PortFactoryBlackboard< S, KeyType >, BlackboardOpenError >
Builder to create or open [Service]s.
constexpr auto err(const E &error) -> Unexpected< E >
Definition expected.hpp:33
iox2::bb::variation::Expected< T, E > Expected
Definition expected.hpp:22
BlackboardOpenError
Errors that can occur when an existing [MessagingPattern::Blackboard] [Service] shall be opened.
BlackboardCreateError
Errors that can occur when a new [MessagingPattern::Blackboard] [Service] shall be created.