Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F27036430
MessageHandler.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Authored By
Unknown
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
Tue, Oct 27, 7:57 PM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
407853
Default Alt Text
MessageHandler.hpp (5 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline