Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F19814867
MessageHandler.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
5 KB
Referenced Files
None
Subscribers
None
MessageHandler.hpp
View Options
/***************************************************************************//**
*
* \file rosa/core/MessageHandler.hpp
*
* \author David Juhasz (david.juhasz@tuwien.ac.at)
*
* \date 2017
*
* \brief Facility for combining `rosa::Invoker` instances and applying
* `rosa::Message` intances to them.
*
******************************************************************************/
#ifndef ROSA_CORE_MESSAGEHANDLER_HPP
#define ROSA_CORE_MESSAGEHANDLER_HPP
#include
"rosa/core/Invoker.hpp"
#include
"rosa/support/log.h"
#include
<vector>
namespace
rosa
{
/// Handles `rosa::Message` instances.
///
/// A `rosa::MessageHandler` stores `rosa::Invoker` instances and tries to
/// apply `rosa::Message` objects to them in the order of definition.The first
/// matching `rosa::Invoker` instance is invoked with the `rosa::Message`
/// object, after which handling of that `rosa::Message` object is completed.
///
/// For example, consider the following snippet: \code
/// rosa::MessageHandler {
/// rosa::Invoker::F<uint8_t>([](uint8_t) { /* ... */ }),
/// rosa::Invoker::F<uint8_t>([](uint8_t) { /* Never invoked */ })
/// };
/// \endcode
/// Applying a `rosa::Message` with `rosa::TypeList<uint8_t>` invokes the first
/// function, and the second function would never be invoked because any
/// matching `rosa::Message` object had already been handled by the first one.
class
MessageHandler
{
/// Type alias to bring `rosa::Invoker::invoker_t` to the local scope.
using
invoker_t
=
Invoker
::
invoker_t
;
/// Type alias for a `std::vector` storing `rosa::Invoker` instances.
using
invokers_t
=
std
::
vector
<
invoker_t
>
;
/// Stores `rosa::Invoker` instances.
const
invokers_t
Invokers
;
/// Creates a container with `rosa::Invoker` instances from functions.
///
/// \tparam Fun type of the mandatory first function
/// \tparam Funs types of further functions
///
/// \param F the mandatory first function
/// \param Fs optional further functions
///
/// \return `invokers_t` object storing `rosa::Invoker` instances created
/// from the `F` and `Fs...`
template
<
typename
Fun
,
typename
...
Funs
>
static
inline
invokers_t
createInvokers
(
Fun
&&
F
,
Funs
&&
...
Fs
)
noexcept
;
/// Updates an `invokers_t` object with a new `rosa::Invoker` instance and
/// handles further functions recursively.
///
/// \tparam Fun type of the first function
/// \tparam Funs types of further functions
///
/// \param I `invokers_t` to update
/// \param Pos index at which to store the new `rosa::Invoker` instance
/// \param F function to wrap and store into `I` at index `Pos`
/// \param Fs further functions to handle later
///
/// \pre `Pos` is a valid index:\code
/// Pos < I.size()
/// \endcode
template
<
typename
Fun
,
typename
...
Funs
>
static
inline
void
wrapFun
(
invokers_t
&
I
,
const
size_t
Pos
,
Fun
&&
F
,
Funs
&&
...
Fs
)
noexcept
;
/// Terminal case for the template `rosa::MessageHandler::wrapFun`.
///
/// \param I `invokers_t` which is now complete
/// \param Pos size of `I`
///
/// \pre `Pos` is the size of `I`:\code
/// Pos == I.size();
/// \endcode
static
inline
void
wrapFun
(
invokers_t
&
I
,
const
size_t
Pos
)
noexcept
;
public
:
/// Creates an instance.
///
/// The constructor stores the given functions into the new
/// `rosa::MessageHandler` instance.
///
/// \tparam Fun type of the mandatory first function
/// \tparam Funs types of further functions
///
/// \param F the first function to store
/// \param Fs optional further functions to store
template
<
typename
Fun
,
typename
...
Funs
>
MessageHandler
(
Fun
&&
F
,
Funs
&&
...
Fs
)
noexcept
;
/// Destroys `this` object.
virtual
~
MessageHandler
(
void
);
/// Tells if a `rosa::Message` object can be handled by `this` object.
///
/// \param Msg `rosa::Message`to check
///
/// \return whether `this` object stores a `rosa::Invoker` instance that can
/// handle `Msg`
bool
canHandle
(
const
Message
&
Msg
)
const
noexcept
;
/// Applies a `rosa::Message` object to the first stored `rosa::Invoker` that
/// can handle it, and tells if there was any.
///
/// \note This operator finds the first applicable `rosa::Invoker` and invokes
/// it with the given `rosa::Message` object, while the member function
/// `rosa::MessageHandler::canHandle` only checks if there is any
/// `rosa::Invoker` that can be invoked with `rosa::Message` object.
///
/// \param Msg `rosa::Message` to use in invoking a matching `rosa::Invoker`
///
/// \return whether there was a matching `rosa::Invoker` found and invoked
/// with `Msg`.
bool
operator
()(
const
Message
&
Msg
)
const
noexcept
;
};
template
<
typename
Fun
,
typename
...
Funs
>
MessageHandler
::
MessageHandler
(
Fun
&&
F
,
Funs
&&
...
Fs
)
noexcept
:
Invokers
(
createInvokers
(
std
::
move
(
F
),
std
::
move
(
Fs
)...))
{
LOG_TRACE
(
"MessageHandler is created"
);
}
template
<
typename
Fun
,
typename
...
Funs
>
MessageHandler
::
invokers_t
MessageHandler
::
createInvokers
(
Fun
&&
F
,
Funs
&&
...
Fs
)
noexcept
{
// Create a container with the required size and get all the functions
// wrapped.
invokers_t
I
(
1
+
sizeof
...(
Funs
));
wrapFun
(
I
,
0
,
std
::
move
(
F
),
std
::
move
(
Fs
)...);
return
I
;
}
template
<
typename
Fun
,
typename
...
Funs
>
void
MessageHandler
::
wrapFun
(
invokers_t
&
I
,
const
size_t
Pos
,
Fun
&&
F
,
Funs
&&
...
Fs
)
noexcept
{
ASSERT
(
Pos
<
I
.
size
());
// Sanity check.
// Wrap the current function and continue with the rest.
I
[
Pos
]
=
Invoker
::
wrap
(
std
::
move
(
F
));
wrapFun
(
I
,
Pos
+
1
,
std
::
move
(
Fs
)...);
}
void
MessageHandler
::
wrapFun
(
invokers_t
&
I
,
const
size_t
Pos
)
noexcept
{
ASSERT
(
Pos
==
I
.
size
());
// Sanity check.
// Nothing to do here.
}
}
// End namespace rosa
#endif
// ROSA_CORE_MESSAGEHANDLER_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, Jul 12, 2:08 PM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
328488
Default Alt Text
MessageHandler.hpp (5 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment