Skip to content

[#264] address last IOX_TODOs in C++ language binding #696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Apr 23, 2025
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
fb7e64d
[#264] Implement missing functions in AttributeSet
elfenpiff Apr 20, 2025
18699cf
[#264] Implement missing functions in Subscriber
elfenpiff Apr 20, 2025
da8db11
[#264] Add DynamicConfig implementation
elfenpiff Apr 20, 2025
43c733a
[#264] Add DynamicConfig implementation for Events
elfenpiff Apr 20, 2025
8da0d3d
[#264] Add ServiceId getter for event
elfenpiff Apr 20, 2025
1960803
[#264] name available for pub sub
elfenpiff Apr 20, 2025
75d1b5e
[#264] ServiceId available for pubsub port factory
elfenpiff Apr 20, 2025
14a7bbf
[#264] List all nodes connected to a pubsub service
elfenpiff Apr 21, 2025
a8aee37
[#264] List all nodes connected to an event service
elfenpiff Apr 21, 2025
0ae50b9
[#264] Max nodes and event id value can be configured for event services
elfenpiff Apr 21, 2025
4471229
[#264] Address clang-tidy warnings
elfenpiff Apr 21, 2025
c63cd17
[#264] Add attributes to service and test service
elfenpiff Apr 21, 2025
772abbb
[#264] Add service list tests with attributes
elfenpiff Apr 22, 2025
9e399db
[#264] Remove attributes from messaging port factories
elfenpiff Apr 22, 2025
6912586
[#264] Implement Service::details()
elfenpiff Apr 22, 2025
f45d738
[#264] Add owning AttributeSet
elfenpiff Apr 23, 2025
37fdc50
[#264] AttributeSetView can be converted to owned version
elfenpiff Apr 23, 2025
928b22c
[#264] Address static code analysis warnings and add release note
elfenpiff Apr 23, 2025
f978318
[#264] C++ idiomatic naming; increase clang-tidy CI timeout; add dev …
elfenpiff Apr 23, 2025
9abff52
[#264] Fix undefined behavior in attribute set list
elfenpiff Apr 23, 2025
ad96149
[#264] Add Windows bigobj fix
elfenpiff Apr 23, 2025
17bdee9
[#264] Allow empty values for attribute keys in C/C++ binding
elfenpiff Apr 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/release-notes/iceoryx2-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
conflicts when merging.
-->

* Full C/C++ Language bindings for all features
[#264](https://github.com/eclipse-iceoryx/iceoryx2/issues/264)
* Read LogLevel from environment variable
[#396](https://github.com/eclipse-iceoryx/iceoryx2/issues/396)
* Lookup config file in default locations
Expand Down
3 changes: 3 additions & 0 deletions iceoryx2-ffi/cxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ add_library(iceoryx2-cxx-object-lib OBJECT
src/attribute_specifier.cpp
src/attribute_verifier.cpp
src/config.cpp
src/dynamic_config_event.cpp
src/dynamic_config_publish_subscribe.cpp
src/event_id.cpp
src/file_descriptor.cpp
src/header_publish_subscribe.cpp
Expand All @@ -59,6 +61,7 @@ add_library(iceoryx2-cxx-object-lib OBJECT
src/port_factory_notifier.cpp
src/service.cpp
src/service_builder_event.cpp
src/service_id.cpp
src/service_name.cpp
src/static_config.cpp
src/static_config_event.cpp
Expand Down
55 changes: 53 additions & 2 deletions iceoryx2-ffi/cxx/include/iox2/attribute_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <iostream>

namespace iox2 {
class AttributeSet;

/// Represents all service attributes. They can be set when the service is created.
///
/// @attention The parent from which the view was extracted MUST live longer than the
Expand Down Expand Up @@ -49,20 +51,69 @@ class AttributeSetView {
void get_key_values(const Attribute::Key& key,
const iox::function<CallbackProgression(const Attribute::Value&)>& callback) const;

/// Creates a copy of the [`AttributeSetView`] that owns the attributes.
auto to_owned() const -> AttributeSet;

private:
template <ServiceType, typename, typename>
friend class PortFactoryPublishSubscribe;
template <ServiceType>
friend class PortFactoryEvent;
friend class AttributeVerifier;
friend class AttributeSpecifier;
friend class StaticConfig;
friend class AttributeSet;

explicit AttributeSetView(iox2_attribute_set_h_ref handle);
explicit AttributeSetView(iox2_attribute_set_ptr handle);

iox2_attribute_set_h_ref m_handle = nullptr;
iox2_attribute_set_ptr m_handle = nullptr;
};

/// Represents all service attributes. They can be set when the service is created.
class AttributeSet {
public:
AttributeSet(const AttributeSet&) = delete;
AttributeSet(AttributeSet&& rhs) noexcept;
auto operator=(const AttributeSet&) -> AttributeSet& = delete;
auto operator=(AttributeSet&& rhs) noexcept -> AttributeSet&;
~AttributeSet();

/// Returns the number of [`Attribute`]s stored inside the [`AttributeSet`].
auto len() const -> uint64_t;

/// Returns a [`AttributeView`] at a specific index. The number of indices is returned via
/// [`AttributeSet::len()`].
auto at(uint64_t index) const -> AttributeView;

/// Returns the number of values stored under a specific key. If the key does not exist it
/// returns 0.
auto get_key_value_len(const Attribute::Key& key) const -> uint64_t;

/// Returns a value of a key at a specific index. The index enumerates the values of the key
/// if the key has multiple values. The values are always stored at the same position during
/// the lifetime of the service but they can change when the process is recreated by another
/// process when the system restarts.
/// If the key does not exist or it does not have a value at the specified index, it returns
/// [`None`].
auto get_key_value_at(const Attribute::Key& key, uint64_t idx) -> iox::optional<Attribute::Value>;

/// Returns all values to a specific key
void get_key_values(const Attribute::Key& key,
const iox::function<CallbackProgression(const Attribute::Value&)>& callback) const;

private:
friend class AttributeSetView;

explicit AttributeSet(iox2_attribute_set_h handle);
void drop();

iox2_attribute_set_h m_handle = nullptr;
AttributeSetView m_view;
};

} // namespace iox2

auto operator<<(std::ostream& stream, const iox2::AttributeSetView& value) -> std::ostream&;
auto operator<<(std::ostream& stream, const iox2::AttributeSet& value) -> std::ostream&;

#endif
27 changes: 20 additions & 7 deletions iceoryx2-ffi/cxx/include/iox2/dynamic_config_event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,32 @@
#ifndef IOX2_DYNAMIC_CONFIG_EVENT_HPP
#define IOX2_DYNAMIC_CONFIG_EVENT_HPP

#include "iox/assertions_addendum.hpp"
#include "iox2/internal/iceoryx2.hpp"

#include <cstdint>

namespace iox2 {
class DynamicConfigEvent {
public:
auto number_of_listeners() const -> uint64_t {
IOX_TODO();
}
auto number_of_notifiers() const -> uint64_t {
IOX_TODO();
}
DynamicConfigEvent(const DynamicConfigEvent&) = delete;
DynamicConfigEvent(DynamicConfigEvent&&) = delete;
auto operator=(const DynamicConfigEvent&) -> DynamicConfigEvent& = delete;
auto operator=(DynamicConfigEvent&&) -> DynamicConfigEvent& = delete;
~DynamicConfigEvent() = default;

/// Returns how many [`Listener`] ports are currently connected.
auto number_of_listeners() const -> uint64_t;

/// Returns how many [`Notifier`] ports are currently connected.
auto number_of_notifiers() const -> uint64_t;

private:
template <ServiceType>
friend class PortFactoryEvent;

explicit DynamicConfigEvent(iox2_port_factory_event_h handle);

iox2_port_factory_event_h m_handle = nullptr;
};
} // namespace iox2

Expand Down
31 changes: 24 additions & 7 deletions iceoryx2-ffi/cxx/include/iox2/dynamic_config_publish_subscribe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,36 @@
#ifndef IOX2_DYNAMIC_CONFIG_PUBLISH_SUBSCRIBE_HPP
#define IOX2_DYNAMIC_CONFIG_PUBLISH_SUBSCRIBE_HPP

#include "iox/assertions_addendum.hpp"
#include "iox2/internal/iceoryx2.hpp"

#include <cstdint>

namespace iox2 {

/// The dynamic configuration of an
/// [`MessagingPattern::PublishSubscribe`] based service. Contains dynamic
/// parameters like the connected endpoints etc..
class DynamicConfigPublishSubscribe {
public:
auto number_of_publishers() const -> uint64_t {
IOX_TODO();
}
auto number_of_subscribers() const -> uint64_t {
IOX_TODO();
}
DynamicConfigPublishSubscribe(const DynamicConfigPublishSubscribe&) = delete;
DynamicConfigPublishSubscribe(DynamicConfigPublishSubscribe&&) = delete;
auto operator=(const DynamicConfigPublishSubscribe&) -> DynamicConfigPublishSubscribe& = delete;
auto operator=(DynamicConfigPublishSubscribe&&) -> DynamicConfigPublishSubscribe& = delete;
~DynamicConfigPublishSubscribe() = default;

/// Returns how many [`Publisher`] ports are currently connected.
auto number_of_publishers() const -> uint64_t;

/// Returns how many [`Subscriber`] ports are currently connected.
auto number_of_subscribers() const -> uint64_t;

private:
template <ServiceType, typename, typename>
friend class PortFactoryPublishSubscribe;

explicit DynamicConfigPublishSubscribe(iox2_port_factory_pub_sub_h handle);

iox2_port_factory_pub_sub_h m_handle = nullptr;
};
} // namespace iox2

Expand Down
57 changes: 55 additions & 2 deletions iceoryx2-ffi/cxx/include/iox2/internal/callback_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
#ifndef IOX2_INTERNAL_CALLBACK_CONTEXT_HPP
#define IOX2_INTERNAL_CALLBACK_CONTEXT_HPP

#include "iox/optional.hpp"
#include "iox2/internal/iceoryx2.hpp"
#include "iox2/node_details.hpp"
#include "iox2/node_id.hpp"
#include "iox2/node_name.hpp"
#include "iox2/node_state.hpp"
#include "iox2/service_type.hpp"

namespace iox2::internal {
template <typename T>
class CallbackContext {
Expand All @@ -30,14 +38,59 @@ class CallbackContext {
};

template <typename T>
auto ctx(const T& ptr) -> CallbackContext<T> {
inline auto ctx(const T& ptr) -> CallbackContext<T> {
return CallbackContext<T>(ptr);
}

template <typename T>
auto ctx_cast(void* ptr) -> CallbackContext<T>* {
inline auto ctx_cast(void* ptr) -> CallbackContext<T>* {
return static_cast<CallbackContext<T>*>(ptr);
}

template <ServiceType T>
// NOLINTBEGIN(readability-function-size)
auto list_callback(iox2_node_state_e node_state,
iox2_node_id_ptr node_id_ptr,
const char* executable,
iox2_node_name_ptr node_name,
iox2_config_ptr config,
iox2_callback_context context) -> iox2_callback_progression_e {
auto node_details = [&] {
if (node_id_ptr == nullptr || config == nullptr) {
return iox::optional<NodeDetails>();
}

return iox::optional<NodeDetails>(NodeDetails {
iox::FileName::create(iox::string<iox::FileName::capacity()>(iox::TruncateToCapacity, executable))
.expect("The executable file name is always valid."),
NodeNameView { node_name }.to_owned(),
Config {} });
}();

iox2_node_id_h node_id_handle = nullptr;
iox2_node_id_clone_from_ptr(nullptr, node_id_ptr, &node_id_handle);
NodeId node_id { node_id_handle };

auto node_state_object = [&] {
switch (node_state) {
case iox2_node_state_e_ALIVE:
return NodeState<T> { AliveNodeView<T> { node_id, node_details } };
case iox2_node_state_e_DEAD:
return NodeState<T> { DeadNodeView<T> { AliveNodeView<T> { node_id, node_details } } };
case iox2_node_state_e_UNDEFINED:
return NodeState<T> { iox2_node_state_e_UNDEFINED, node_id };
case iox2_node_state_e_INACCESSIBLE:
return NodeState<T> { iox2_node_state_e_INACCESSIBLE, node_id };
}

IOX_UNREACHABLE();
}();

auto* callback = internal::ctx_cast<iox::function<CallbackProgression(NodeState<T>)>>(context);
return iox::into<iox2_callback_progression_e>(callback->value()(node_state_object));
}
// NOLINTEND(readability-function-size)

} // namespace iox2::internal

#endif
12 changes: 6 additions & 6 deletions iceoryx2-ffi/cxx/include/iox2/node_details.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ class NodeDetails {

private:
template <ServiceType>
friend auto list_callback(iox2_node_state_e,
iox2_node_id_ptr,
const char* executable,
iox2_node_name_ptr,
iox2_config_ptr,
iox2_callback_context) -> iox2_callback_progression_e;
friend auto internal::list_callback(iox2_node_state_e,
iox2_node_id_ptr,
const char* executable,
iox2_node_name_ptr,
iox2_config_ptr,
iox2_callback_context) -> iox2_callback_progression_e;

NodeDetails(iox::FileName executable, NodeName name, Config config);

Expand Down
10 changes: 8 additions & 2 deletions iceoryx2-ffi/cxx/include/iox2/node_id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
#include <iostream>

namespace iox2 {
namespace internal {
template <ServiceType>
auto list_callback(
iox2_node_state_e, iox2_node_id_ptr, const char*, iox2_node_name_ptr, iox2_config_ptr, iox2_callback_context)
-> iox2_callback_progression_e;
}

/// The system-wide unique id of a [`Node`]
class NodeId {
public:
Expand Down Expand Up @@ -48,11 +55,10 @@ class NodeId {
template <ServiceType>
friend class DeadNodeView;
template <ServiceType>
friend auto list_callback(
friend auto internal::list_callback(
iox2_node_state_e, iox2_node_id_ptr, const char*, iox2_node_name_ptr, iox2_config_ptr, iox2_callback_context)
-> iox2_callback_progression_e;


explicit NodeId(iox2_node_id_h handle);
void drop();

Expand Down
21 changes: 15 additions & 6 deletions iceoryx2-ffi/cxx/include/iox2/node_name.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
#include "iox2/semantic_string.hpp"

namespace iox2 {
namespace internal {
template <ServiceType>
auto list_callback(iox2_node_state_e,
iox2_node_id_ptr,
const char* executable,
iox2_node_name_ptr,
iox2_config_ptr,
iox2_callback_context) -> iox2_callback_progression_e;
}
class NodeName;

/// Non-owning view of a [`NodeName`].
Expand All @@ -41,12 +50,12 @@ class NodeNameView {
friend class Node;
friend class NodeName;
template <ServiceType>
friend auto list_callback(iox2_node_state_e,
iox2_node_id_ptr,
const char* executable,
iox2_node_name_ptr,
iox2_config_ptr,
iox2_callback_context) -> iox2_callback_progression_e;
friend auto internal::list_callback(iox2_node_state_e,
iox2_node_id_ptr,
const char* executable,
iox2_node_name_ptr,
iox2_config_ptr,
iox2_callback_context) -> iox2_callback_progression_e;

explicit NodeNameView(iox2_node_name_ptr ptr);
iox2_node_name_ptr m_ptr = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion iceoryx2-ffi/cxx/include/iox2/node_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class NodeState {

private:
template <ServiceType>
friend auto list_callback(
friend auto internal::list_callback(
iox2_node_state_e, iox2_node_id_ptr, const char*, iox2_node_name_ptr, iox2_config_ptr, iox2_callback_context)
-> iox2_callback_progression_e;

Expand Down
4 changes: 2 additions & 2 deletions iceoryx2-ffi/cxx/include/iox2/port_factory_event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class PortFactoryEvent {
auto name() const -> ServiceNameView;

/// Returns the [`ServiceId`] of the [`Service`]
auto service_id() const -> const ServiceId&;
auto service_id() const -> ServiceId;

/// Returns the attributes defined in the [`Service`]
auto attributes() const -> AttributeSetView;
Expand All @@ -55,7 +55,7 @@ class PortFactoryEvent {

/// Returns the DynamicConfig of the [`Service`].
/// Contains all dynamic settings, like the current participants etc..
auto dynamic_config() const -> const DynamicConfigEvent&;
auto dynamic_config() const -> DynamicConfigEvent;

/// Iterates over all [`Node`]s of the [`Service`]
/// and calls for every [`Node`] the provided callback. If an error occurs
Expand Down
Loading
Loading