Skip to content

Commit

Permalink
Allow posting lambdas and update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
rmed committed Jun 29, 2024
1 parent d03d651 commit dc2ca19
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
5 changes: 4 additions & 1 deletion docs/base-package.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ These components can be chained as many times as needed, as long as there is one

Note that all components deriving from a single parent will be executed **in the same thread**.

Method calls can be **posted to the event loop** via the `kouta::base::Component::post()` method. This is the core of the event-based architecture, as it allows to defer method execution in a single thread in an efficient manner.
Method calls can be **posted to the event loop** via the `kouta::base::Component::post()` method. This is the core of the event-based architecture, as it allows to defer method execution in a single thread in an efficient manner. In addition, it is also possible to **post calls to lambdas and free functions**.

A simple component could be:

Expand Down Expand Up @@ -42,6 +42,9 @@ public:
// Deferred method call
comp.post(&MyComponent::print_message, 42);
comp.post(&MyComponent::print_message, 546);
comp.post([]() {
std::cout << "This is deferred" << std::endl;
});
```

## Root
Expand Down
21 changes: 18 additions & 3 deletions include/kouta/base/component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@ namespace kouta::base
/// @brief Post a function call to the event loop for deferred execution.
///
/// @details
/// This allows other components, even those residing in another thread/event loop, to post a functor to this
/// specific component, for example a lambda function.
/// This allows other components, even those residing in another thread/event loop, to post a function to this
/// specific component.
///
/// @warning Arguments are **copied** before being passed to the event loop.
///
/// @tparam TFuncArgs Types of the arguments that the function accepts.
/// @tparam TArgs Types of the arguments provided to the invocation.
///
/// @param[in] functor Functor to invoke invoked. Its signature must match `void(TArgs...)`
/// @param[in] functor Functor to invoke. Its signature must match `void(TArgs...)`
/// @param[in] args Arguments to invoke the functor with.
template<class... TFuncArgs, class... TArgs>
void post(const std::function<void(TFuncArgs...)>& functor, TArgs... args)
Expand All @@ -90,6 +90,21 @@ namespace kouta::base
});
}

/// @brief Post a functor call to the event loop for deferred execution.
///
/// @details
/// This allows other components, even those residing in another thread/event loop, to post a functor to this
/// specific component, for example a lambda.
///
/// @tparam TFunctor Functor type.
///
/// @param[in] functor Functor to invoke.s
template<class TFunctor>
void post(TFunctor&& functor)
{
boost::asio::post(context().get_executor(), functor);
}

private:
Component* m_parent;
};
Expand Down
6 changes: 5 additions & 1 deletion tests/base/test-base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,11 @@ namespace kouta::tests::base

root.post(&RootMock::handler_a, std::uint16_t{42});
root.post(&RootMock::handler_b, -512, "This is a test");
root.post(&RootMock::handler_c, std::vector<std::uint8_t>{12, 34});
root.post(
[&root]()
{
root.handler_c(std::vector<std::uint8_t>{12, 34});
});
}

/// @brief Test the behaviour of the event loop when running.
Expand Down

0 comments on commit dc2ca19

Please sign in to comment.