Page MenuHomePhorge

MessagingSystem.hpp
No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None

MessagingSystem.hpp

/***************************************************************************//**
*
* \file rosa/core/MessagingSystem.hpp
*
* \author David Juhasz (david.juhasz@tuwien.ac.at)
*
* \date 2017
*
* \brief Declaration of an interface extending `rosa::System` with messaging.
*
******************************************************************************/
#ifndef ROSA_CORE_MESSAGINGSYSTEM_HPP
#define ROSA_CORE_MESSAGINGSYSTEM_HPP
#include "rosa/core/AgentHandle.hpp"
#include "rosa/core/System.hpp"
#include "rosa/support/atom.hpp"
namespace rosa {
/// Extends the `rosa::System` interface with features to create `rosa::Agent`
/// instancess and register `rosa::Message` objects for them.
class MessagingSystem : public System {
friend class AgentHandle; ///< `rosa::AgentHandle` is our friend.
public:
/// Returns an object implementing the `rosa::MessagingSystem` interface.
///
/// \param Name name of the new instance
///
/// \return `std::unique_ptr` for the new instance of
/// `rosa::MessagingSystem`
static std::unique_ptr<MessagingSystem>
createSystem(const std::string &Name) noexcept;
private:
/// Kind for categorizing `rosa::Unit` instances as *agents*.
static constexpr AtomValue AgentKind = atom("agent");
protected:
/// Creates a new instance.
///
/// \note Protected constructor restricts instantiation for subclasses.
MessagingSystem(void) noexcept = default;
protected:
/// Creates a `rosa::Agent` instance owned by `this` object and returns a
/// `rosa::AgentHandle` for it.
///
/// \tparam T type of the actual `rosa::Agent` to instantiate
/// \tparam Funs types of the functions to instantiate `rosa::Agent` with
///
/// \note `rosa::Agent` requires at least one function for its constructor,
/// but derived classes may do not need that. That's the reason of allowing
/// zero `Funs` for this template function.
///
/// \param Name name of the new `rosa::Unit` instance
/// \param Fs functions to instantiate `rosa::Unit` with
///
/// \pre Statically, `T` is a subclass of `rosa::Agent`:\code
/// std::is_base_of<Agent, T>::value
/// \endcode
template <typename T, typename... Funs>
AgentHandle createAgent(const std::string &Name, Funs &&... Fs);
/// Gives the references `rosa::Agent` instance for a `rosa::AgentHandle`.
///
/// \note Intended for derived classes to be able to inspect
/// `rosa::AgentHandle` instances.
///
/// \param H `rosa::AgentHandle` to take the referenced `rosa::Agent` from
///
/// \return reference to the `rosa::Agent` instance from `H`
static inline Agent &unwrapAgent(const AgentHandle &H) noexcept {
return H.A;
}
/// Gives the owning `rosa::MessagingSystem` of a `rosa::Agent` instance
/// for a `rosa::AgentHandle`.
///
/// \note Intended for for derived classes to be able to inspect
/// `rosa::AgentHandle` instances.
///
/// \param H `rosa::AgentHandle` to take the owning
/// `rosa::MessagingSystem` from
///
/// \return reference to the `rosa::MessagingSystem` owning the
/// `rosa::agent` instance from `H`
static inline MessagingSystem &unwrapSystem(const AgentHandle &H) noexcept {
return H.S;
}
public:
/// Sends a `rosa::message_t` instance to the `rosa::Agent`instance referred
/// by a `rosa::AgentHandle`.
///
/// \note If the given `rosa::Message` object cannot be handled by the
/// referred `rosa::Agent` instance, the `rosa::Message` object is simply
/// ignored.
///
/// \param H refers to the `rosa::Agent` instance to send to
/// \param M message to send
///
/// \pre The referred `rosa::Agent` instance is owned by `this` object and
/// also registered: \code
/// &unwrapSystem(H) == this && isUnitRegistered(unwrapAgent(H))
/// \endcode
virtual void send(const AgentHandle &H, message_t &&M) noexcept = 0;
/// Sends a message -- created from given constant lvalue references --
/// to the `rosa::Agent`instance referred by a `rosa::AgentHandle`.
///
/// \note If the given `rosa::Message` object cannot be handled by the
/// referred `rosa::Agent` instance, the `rosa::Message` object is simply
/// ignored.
///
/// \note The message must consists of at least one value.
///
/// \tparam Type type of the first mandatory value
/// \tparam Types types of any further values
///
/// \param H refers to the `rosa::Agent` instance to send to
/// \param T the first value to include in the message
/// \param Ts optional further values to include in the message
///
/// \pre The referred `rosa::Agent` instance is owned by `this` object and
/// also registered: \code
/// &unwrapSystem(H) == this && isUnitRegistered(unwrapAgent(H))
/// \endcode
template <typename Type, typename... Types>
void send(const AgentHandle &H, const Type &T, const Types &... Ts) noexcept;
/// Sends a message -- created from given rvalue references --
/// to the `rosa::Agent`instance referred by a `rosa::AgentHandle`.
///
/// \note If the given `rosa::Message` object cannot be handled by the
/// referred `rosa::Agent` instance, the `rosa::Message` object is simply
/// ignored.
///
/// \note The message must consists of at least one value.
///
/// \tparam Type type of the first mandatory value
/// \tparam Types types of any further values
///
/// \param H refers to the `rosa::Agent` instance to send to
/// \param T the first value to include in the message
/// \param Ts optional further values to include in the message
///
/// \pre The referred `rosa::Agent` instance is owned by `this` object and
/// also registered: \code
/// &unwrapSystem(H) == this && isUnitRegistered(unwrapAgent(H))
/// \endcode
template <typename Type, typename... Types>
void send(const AgentHandle &H, Type &&T, Types &&... Ts) noexcept;
};
template <typename T, typename... Funs>
AgentHandle MessagingSystem::createAgent(const std::string &Name,
Funs &&... Fs) {
STATIC_ASSERT((std::is_base_of<Agent, T>::value), "not an Agent");
Agent &A = createUnit<T, MessagingSystem>([&](const id_t Id,
MessagingSystem &S) noexcept {
return new T(AgentKind, Id, Name, S, std::move(Fs)...);
});
return {A};
}
template <typename Type, typename... Types>
void MessagingSystem::send(const AgentHandle &H, const Type &T,
const Types &... Ts) noexcept {
send(H, Message::create<Type, Types...>(T, Ts...));
}
template <typename Type, typename... Types>
void MessagingSystem::send(const AgentHandle &H, Type &&T,
Types &&... Ts) noexcept {
send(H, Message::create<Type, Types...>(std::move(T), std::move(Ts)...));
}
} // End namespace rosa
#endif // ROSA_CORE_MESSAGINGSYSTEM_HPP

File Metadata

Mime Type
text/x-c++
Expires
Sun, May 31, 5:15 PM (20 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
328083
Default Alt Text
MessagingSystem.hpp (6 KB)

Event Timeline