Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F1494528
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
//===-- rosa/core/MessageHandler.hpp ----------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/core/MessageHandler.hpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017
///
/// \brief Facility for combining \c rosa::Invoker instances and applying
/// \c 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 \c rosa::Message instances.
///
/// A \c rosa::MessageHandler stores \c rosa::Invoker instances and tries to
/// apply \c rosa::Message objects to them in the order of definition.The first
/// matching \c rosa::Invoker instance is invoked with the \c rosa::Message
/// object, after which handling of that \c 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 \c rosa::Message with \c rosa::TypeList<uint8_t> invokes the
/// first function, and the second function would never be invoked because any
/// matching \c rosa::Message object had already been handled by the first one.
class
MessageHandler
{
/// Type alias to bring \c rosa::Invoker::invoker_t to the local scope.
using
invoker_t
=
Invoker
::
invoker_t
;
/// Type alias for a \c std::vector storing \c rosa::Invoker instances.
using
invokers_t
=
std
::
vector
<
invoker_t
>
;
/// Stores \c rosa::Invoker instances.
const
invokers_t
Invokers
;
/// Creates a container with \c 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 \c rosa::MessageHandler::invokers_t object storing
/// \c rosa::Invoker instances created from the \p F and \p Fs...
template
<
typename
Fun
,
typename
...
Funs
>
static
inline
invokers_t
createInvokers
(
Fun
&&
F
,
Funs
&&
...
Fs
)
noexcept
;
/// Updates an \c rosa::MessageHandler::invokers_t object with a new
/// \c rosa::Invoker instance and handles further functions recursively.
///
/// \tparam Fun type of the first function
/// \tparam Funs types of further functions
///
/// \param I \c rosa::MessageHandler::invokers_t to update
/// \param Pos index at which to store the new \c rosa::Invoker instance
/// \param F function to wrap and store into \p I at index \p Pos
/// \param Fs further functions to handle later
///
/// \pre \p 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 \c rosa::MessageHandler::wrapFun.
///
/// \param I \c rosa::MessageHandler::invokers_t which is now complete
/// \param Pos size of \p I
///
/// \pre \p Pos is the size of \p 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
/// \c 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 \p this object.
virtual
~
MessageHandler
(
void
);
/// Tells if a \c rosa::Message object can be handled by \p this object.
///
/// \param Msg \c rosa::Message to check
///
/// \return whether \p this object stores a \c rosa::Invoker instance that can
/// handle \p Msg
bool
canHandle
(
const
Message
&
Msg
)
const
noexcept
;
/// Applies a \c rosa::Message object to the first stored \c rosa::Invoker
/// that can handle it, and tells if there was any.
///
/// \note This operator finds the first applicable \c rosa::Invoker and
/// invokes it with the given \c rosa::Message object, while the member
/// function \c rosa::MessageHandler::canHandle only checks if there is any
/// \c rosa::Invoker that can be invoked with a given \c rosa::Message object.
///
/// \param Msg \c rosa::Message to use in invoking a matching \c rosa::Invoker
///
/// \return whether there was a matching \c rosa::Invoker found and invoked
/// with \p 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, Mar 1, 6:47 PM (20 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
280877
Default Alt Text
MessageHandler.hpp (5 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment