Page MenuHomePhorge

MessageHandler.hpp
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

MessageHandler.hpp

/*******************************************************************************
*
* File: MessageHandler.hpp
*
* Contents: Definition of MessageHandler interface.
*
* Copyright 2017
*
* Author: David Juhasz (david.juhasz@tuwien.ac.at)
*
******************************************************************************/
#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 Message instances. A MessageHandler stores Invokers and tries to
// apply Messages to them in the order of definition. The first matching
// Invoker is invoked with the Message, after which handling of Message is
// completed.
//
// For example, consider the following snippet:
//
// MessageHandler {
// Invoker::F<uint8_t>([](uint8_t) { /* ... */ }),
// Invoker::F<uint8_t>([](uint8_t) { /* Never invoked */ })
// };
//
// Applying a Message with TypeList<uint8_t> invokes the first function, and
// the second function would never be invoked because any matching Message had
// already been handled by the first one.
class MessageHandler {
// Using invoker_t from Invoker.
using invoker_t = Invoker::invoker_t;
// Type alias for a vector storing Invokers.
using invokers_t = std::vector<invoker_t>;
// Stores the Invokers of this MessageHandler.
const invokers_t Invokers;
// Creates a container with Invokers from the given functions.
template <typename Fun, typename... Funs>
static inline invokers_t createInvokers(Fun &&F, Funs &&... Fs) noexcept;
// Wraps F into an Invoker and stores it into I at position Pos.
// PRE: Pos < I.size()
template <typename Fun, typename... Funs>
static inline void wrapFun(invokers_t &I, const size_t Pos, Fun &&F,
Funs &&... Fs) noexcept;
// Terminal case for function wrapper.
// PRE: Pos == I.size();
static inline void wrapFun(invokers_t &I, const size_t Pos) noexcept;
public:
// Ctor, stores the given functions into the new MessageHandler instance.
template<typename Fun, typename... Funs>
MessageHandler(Fun &&F, Funs &&... Fs) noexcept;
virtual ~MessageHandler(void);
// Tells if there is any Invoker that can handle Msg.
bool canHandle(const Message &Msg) const noexcept;
// Applies Msg to the first Invoker which can handle Msg, and tells if there
// was any.
// NOTE: This operator finds the first applicable Invoker and invokes it with
// Msg, while the member function canHandle only checks if there is any
// Invoker that can be 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

Mime Type
text/x-c++
Expires
Sun, Apr 12, 11:46 AM (10 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
295784
Default Alt Text
MessageHandler.hpp (3 KB)

Event Timeline