Skip to content

Commit

Permalink
[eclipse-iceoryx#550] Add C/C++ bindings for auto events
Browse files Browse the repository at this point in the history
  • Loading branch information
elfenpiff committed Dec 17, 2024
1 parent 068ee29 commit 89cce20
Show file tree
Hide file tree
Showing 11 changed files with 405 additions and 7 deletions.
10 changes: 10 additions & 0 deletions iceoryx2-ffi/cxx/include/iox/builder_addendum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@

// NOLINTBEGIN(cppcoreguidelines-macro-usage)
// NOLINTBEGIN(bugprone-macro-parentheses)
#define IOX_BUILDER_SWITCH(name) \
public: \
auto name()&& noexcept -> decltype(auto) { \
m_##name = true; \
return std::move(*this); \
} \
\
private: \
bool m_##name { false };

#define IOX_BUILDER_PARAMETER(type, name, defaultValue) \
public: \
auto name(type const& value)&& noexcept -> decltype(auto) { \
Expand Down
6 changes: 6 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/event_id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ class EventId {
};

auto operator<<(std::ostream& stream, const EventId& value) -> std::ostream&;
auto operator==(const EventId& lhs, const EventId& rhs) -> bool;
auto operator!=(const EventId& lhs, const EventId& rhs) -> bool;
auto operator<(const EventId& lhs, const EventId& rhs) -> bool;
auto operator<=(const EventId& lhs, const EventId& rhs) -> bool;
auto operator>(const EventId& lhs, const EventId& rhs) -> bool;
auto operator>=(const EventId& lhs, const EventId& rhs) -> bool;
} // namespace iox2

#endif
25 changes: 25 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/service_builder_event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "iox/expected.hpp"
#include "iox2/attribute_specifier.hpp"
#include "iox2/attribute_verifier.hpp"
#include "iox2/event_id.hpp"
#include "iox2/internal/iceoryx2.hpp"
#include "iox2/port_factory_event.hpp"
#include "iox2/service_builder_event_error.hpp"
Expand Down Expand Up @@ -48,6 +49,30 @@ class ServiceBuilderEvent {
/// [`Listener`] must be at least supported.
IOX_BUILDER_OPTIONAL(uint64_t, max_listeners);

/// If the [`Service`] is created it defines the event that shall be emitted by every newly
/// created [`Notifier`].
IOX_BUILDER_OPTIONAL(EventId, notifier_created_event);

/// If the [`Service`] is created it disables sending an event when a new notifier was created.
IOX_BUILDER_SWITCH(disable_notifier_created_event);

/// If the [`Service`] is created it defines the event that shall be emitted by every
/// [`Notifier`] before it is dropped. If [`None`] is
/// provided a [`Notifier`] will not emit an event.
IOX_BUILDER_OPTIONAL(EventId, notifier_dropped_event);

/// If the [`Service`] is created it disables sending an event when a notifier was dropped.
IOX_BUILDER_SWITCH(disable_notifier_dropped_event);

/// If the [`Service`] is created it defines the event that shall be emitted when a
/// [`Notifier`] is identified as dead. If [`None`] is
/// provided no event will be emitted.
IOX_BUILDER_OPTIONAL(EventId, notifier_dead_event);

/// If the [`Service`] is created it disables sending an event when a notifier was identified
/// as dead.
IOX_BUILDER_SWITCH(disable_notifier_dead_event);

public:
/// If the [`Service`] exists, it will be opened otherwise a new [`Service`] will be
/// created.
Expand Down
11 changes: 11 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/static_config_event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#ifndef IOX2_STATIC_CONFIG_EVENT_HPP
#define IOX2_STATIC_CONFIG_EVENT_HPP

#include "iox/optional.hpp"
#include "iox2/event_id.hpp"
#include "iox2/iceoryx2.h"
#include "iox2/internal/iceoryx2.hpp"

Expand All @@ -35,6 +37,15 @@ class StaticConfigEvent {
/// Returns the largest [`EventId`] that is supported by the service
auto event_id_max_value() const -> size_t;

/// Returns the emitted [`EventId`] when a new notifier is created.
auto notifier_created_event() const -> iox::optional<EventId>;

/// Returns the emitted [`EventId`] when a notifier is dropped.
auto notifier_dropped_event() const -> iox::optional<EventId>;

/// Returns the emitted [`EventId`] when a notifier is identified as dead.
auto notifier_dead_event() const -> iox::optional<EventId>;

private:
template <ServiceType>
friend class PortFactoryEvent;
Expand Down
25 changes: 24 additions & 1 deletion iceoryx2-ffi/cxx/src/event_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

#include "iox2/event_id.hpp"
#include "iox/assertions_addendum.hpp"

namespace iox2 {
EventId::EventId(const size_t value)
Expand All @@ -30,4 +29,28 @@ auto operator<<(std::ostream& stream, const EventId& value) -> std::ostream& {
stream << "EventId { m_value: " << value.as_value() << " }";
return stream;
}

auto operator==(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() == rhs.as_value();
}

auto operator!=(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() != rhs.as_value();
}

auto operator<(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() < rhs.as_value();
}

auto operator<=(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() <= rhs.as_value();
}

auto operator>(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() > rhs.as_value();
}

auto operator>=(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() >= rhs.as_value();
}
} // namespace iox2
15 changes: 15 additions & 0 deletions iceoryx2-ffi/cxx/src/service_builder_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@ template <ServiceType S>
void ServiceBuilderEvent<S>::set_parameters() {
m_max_notifiers.and_then([&](auto value) { iox2_service_builder_event_set_max_notifiers(&m_handle, value); });
m_max_listeners.and_then([&](auto value) { iox2_service_builder_event_set_max_listeners(&m_handle, value); });
m_notifier_created_event.and_then(
[&](auto value) { iox2_service_builder_event_set_notifier_created_event(&m_handle, value.as_value()); });
m_notifier_dropped_event.and_then(
[&](auto value) { iox2_service_builder_event_set_notifier_dropped_event(&m_handle, value.as_value()); });
m_notifier_dead_event.and_then(
[&](auto value) { iox2_service_builder_event_set_notifier_dead_event(&m_handle, value.as_value()); });
if (m_disable_notifier_created_event) {
iox2_service_builder_event_disable_notifier_created_event(&m_handle);
}
if (m_disable_notifier_dropped_event) {
iox2_service_builder_event_disable_notifier_dropped_event(&m_handle);
}
if (m_disable_notifier_dead_event) {
iox2_service_builder_event_disable_notifier_dead_event(&m_handle);
}
m_max_nodes.and_then([](auto) { IOX_TODO(); });
m_event_id_max_value.and_then([](auto) { IOX_TODO(); });
}
Expand Down
27 changes: 27 additions & 0 deletions iceoryx2-ffi/cxx/src/static_config_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,40 @@ StaticConfigEvent::StaticConfigEvent(iox2_static_config_event_t value)
auto StaticConfigEvent::max_nodes() const -> size_t {
return m_value.max_nodes;
}

auto StaticConfigEvent::max_notifiers() const -> size_t {
return m_value.max_notifiers;
}

auto StaticConfigEvent::max_listeners() const -> size_t {
return m_value.max_listeners;
}

auto StaticConfigEvent::event_id_max_value() const -> size_t {
return m_value.event_id_max_value;
}

auto StaticConfigEvent::notifier_created_event() const -> iox::optional<EventId> {
if (!m_value.has_notifier_created_event) {
return iox::nullopt;
}

return { EventId(m_value.notifier_created_event) };
}

auto StaticConfigEvent::notifier_dropped_event() const -> iox::optional<EventId> {
if (!m_value.has_notifier_dropped_event) {
return iox::nullopt;
}

return { EventId(m_value.notifier_dropped_event) };
}

auto StaticConfigEvent::notifier_dead_event() const -> iox::optional<EventId> {
if (!m_value.has_notifier_dead_event) {
return iox::nullopt;
}

return { EventId(m_value.notifier_dead_event) };
}
} // namespace iox2
52 changes: 51 additions & 1 deletion iceoryx2-ffi/cxx/tests/src/service_event_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ TYPED_TEST(ServiceEventTest, service_settings_are_applied) {
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;
constexpr uint64_t NUMBER_OF_NOTIFIERS = 5;
constexpr uint64_t NUMBER_OF_LISTENERS = 7;
const auto create_event_id = EventId(12);
const auto dropped_event_id = EventId(13);
const auto dead_event_id = EventId(14);

const auto service_name = iox2_testing::generate_service_name();

Expand All @@ -99,13 +102,19 @@ TYPED_TEST(ServiceEventTest, service_settings_are_applied) {
.event()
.max_notifiers(NUMBER_OF_NOTIFIERS)
.max_listeners(NUMBER_OF_LISTENERS)
.notifier_created_event(create_event_id)
.notifier_dropped_event(dropped_event_id)
.notifier_dead_event(dead_event_id)
.create()
.expect("");

auto static_config = sut.static_config();

ASSERT_THAT(static_config.max_notifiers(), Eq(NUMBER_OF_NOTIFIERS));
ASSERT_THAT(static_config.max_listeners(), Eq(NUMBER_OF_LISTENERS));
ASSERT_THAT(static_config.notifier_created_event(), Eq(iox::optional<EventId>(create_event_id)));
ASSERT_THAT(static_config.notifier_dropped_event(), Eq(iox::optional<EventId>(dropped_event_id)));
ASSERT_THAT(static_config.notifier_dead_event(), Eq(iox::optional<EventId>(dead_event_id)));
}

TYPED_TEST(ServiceEventTest, open_fails_with_incompatible_max_notifiers_requirements) {
Expand Down Expand Up @@ -205,6 +214,47 @@ TYPED_TEST(ServiceEventTest, service_name_is_set) {
ASSERT_THAT(service_name.to_string(), Eq(sut_service_name.to_string()));
}

TYPED_TEST(ServiceEventTest, notifier_emits_create_and_drop_events) {
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;
const auto create_event_id = EventId(21);
const auto dropped_event_id = EventId(31);

const auto service_name = iox2_testing::generate_service_name();

auto node = NodeBuilder().create<SERVICE_TYPE>().expect("");
auto service = node.service_builder(service_name)
.event()
.notifier_created_event(create_event_id)
.notifier_dropped_event(dropped_event_id)
.create()
.expect("");

auto listener = service.listener_builder().create().expect("");

{
auto notifier = service.notifier_builder().create();

auto counter = 0;
listener
.try_wait_all([&](auto event_id) {
EXPECT_THAT(event_id, Eq(create_event_id));
counter++;
})
.expect("");
ASSERT_THAT(counter, Eq(1));
}

auto counter = 0;
listener
.try_wait_all([&](auto event_id) {
EXPECT_THAT(event_id, Eq(dropped_event_id));
counter++;
})
.expect("");
ASSERT_THAT(counter, Eq(1));
}


TYPED_TEST(ServiceEventTest, notification_is_received_with_try_wait_one) {
this->notifier.notify().expect("");

Expand Down Expand Up @@ -275,7 +325,7 @@ TYPED_TEST(ServiceEventTest, timed_wait_one_does_not_deadlock) {
}

TYPED_TEST(ServiceEventTest, timed_wait_all_does_not_deadlock) {
this->listener.timed_wait_all([](auto) {}, TIMEOUT).expect("");
this->listener.timed_wait_all([](auto) { }, TIMEOUT).expect("");
}

TYPED_TEST(ServiceEventTest, service_can_be_opened_when_there_is_a_notifier) {
Expand Down
Loading

0 comments on commit 89cce20

Please sign in to comment.