diff --git a/examples/agent-functionalities/agent-functionalities.cpp b/examples/agent-functionalities/agent-functionalities.cpp index 47dd576..8f111db 100644 --- a/examples/agent-functionalities/agent-functionalities.cpp +++ b/examples/agent-functionalities/agent-functionalities.cpp @@ -1,211 +1,211 @@ //===-- examples/agent-functionalities/agent-functionalities.cpp *-- C++-*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file examples/agent-functionalities/agent-functionalities.cpp /// /// \author David Juhasz (david.juhasz@tuwien.ac.at) /// /// \date 2017 /// /// \brief A simple example on defining \c rosa::Agent instances using /// \c rosa::agent::Functionality object as components. /// //===----------------------------------------------------------------------===// #include "rosa/agent/Abstraction.hpp" #include "rosa/agent/Confidence.hpp" #include "rosa/agent/FunctionAbstractions.hpp" #include "rosa/agent/RangeConfidence.hpp" #include "rosa/config/version.h" #include "rosa/core/Agent.hpp" #include "rosa/core/MessagingSystem.hpp" #include "rosa/support/log.h" #include "rosa/support/terminal_colors.h" #include using namespace rosa; using namespace rosa::agent; using namespace rosa::terminal; /// A dummy wrapper for testing \c rosa::MessagingSystem. /// /// \note Since we test \c rosa::MessagingSystem directly here, we need to get /// access to its protected members. That we do by imitating to be a decent /// subclass of \c rosa::MessagingSystem, while calling protected member /// functions on an object of a type from which we actually don't inherit. struct SystemTester : protected MessagingSystem { template static AgentHandle createMyAgent(MessagingSystem *S, const std::string &Name, Funs &&... Fs) { return ((SystemTester *)S)->createAgent(Name, std::move(Fs)...); } static void destroyMyAgent(MessagingSystem *S, const AgentHandle &H) { ((SystemTester *)S)->destroyUnit(unwrapAgent(H)); } }; /// A special \c rosa::Agent with its own state. class MyAgent : public Agent { public: using Tick = AtomConstant; private: enum class Categories { Bad, Normal, Good }; static const std::map CategoryNames; StaticLengthHistory H; Confidence C; RangeAbstraction A; PartialFunction L; RangeConfidence RCL; RangeConfidence RCS; public: void handler(Tick, uint8_t V) noexcept { // Record \p V to the \c rosa::agent::History, then print state info. H << V; ASSERT(H.entry() == V); // Sanity check. LOG_INFO_STREAM << "\nNext value: " << PRINTABLE(V) << ", confidence: " << C(H) << ", category: " << CategoryNames.at(A(H.entry())) << ", partial: " << int(L(H.entry())) << ", range-confidence-linear: "; - std::map res_lin = RCL(H.entry()); - for (auto i : res_lin) { - LOG_INFO_STREAM << " " << CategoryNames.at(i.first) << " " << i.second + std::map ResLin = RCL(H.entry()); + for (auto Con : ResLin) { + LOG_INFO_STREAM << " " << CategoryNames.at(Con.first) << " " << Con.second << ","; } LOG_INFO_STREAM << " range-confidence-sine: "; - std::map res_sine = RCS(H.entry()); - for (auto i : res_sine) { - LOG_INFO_STREAM << " " << CategoryNames.at(i.first) << " " << i.second + std::map ResSine = RCS(H.entry()); + for (auto Con : ResSine) { + LOG_INFO_STREAM << " " << CategoryNames.at(Con.first) << " " << Con.second << ","; } LOG_INFO_STREAM << '\n'; } MyAgent(const AtomValue Kind, const rosa::id_t Id, const std::string &Name, MessagingSystem &S) : Agent(Kind, Id, Name, S, THISMEMBER(handler)), H(), C(5, 20, 1), A({{{(uint8_t)10, (uint8_t)14}, Categories::Normal}, {{(uint8_t)15, (uint8_t)17}, Categories::Good}, {{(uint8_t)18, (uint8_t)19}, Categories::Normal}}, Categories::Bad), L({{{0, 2}, std::make_shared>(0, 1)}, {{2, 4}, std::make_shared>(2, 0)}, {{4, 6}, std::make_shared>(6, -1)}}, 0), RCL({{Categories::Bad, PartialFunction( { {{0, 3}, std::make_shared>(0, 1.0 / 3)}, {{3, 6}, std::make_shared>(1, 0)}, {{6, 9}, std::make_shared>( 3.0, -1.0 / 3)}, }, 0)}, {Categories::Normal, PartialFunction( { {{6, 9}, std::make_shared>(-2, 1.0 / 3)}, {{9, 12}, std::make_shared>(1, 0)}, {{12, 15}, std::make_shared>( 5, -1.0 / 3)}, }, 0)}, {Categories::Good, PartialFunction( { {{12, 15}, std::make_shared>(-4, 1.0 / 3)}, {{15, 18}, std::make_shared>(1, 0)}, {{18, 21}, std::make_shared>( 7, -1.0 / 3)}, }, 0)}}), RCS({{Categories::Bad, PartialFunction( { {{0, 3}, std::make_shared>( M_PI / 3, 0.5, -M_PI / 2, 0.5)}, {{3, 6}, std::make_shared>(1, 0)}, {{6, 9}, std::make_shared>( M_PI / 3, 0.5, -M_PI / 2 + 3, 0.5)}, }, 0)}, {Categories::Normal, PartialFunction( { {{6, 9}, std::make_shared>( M_PI / 3, 0.5, -M_PI / 2, 0.5)}, {{9, 12}, std::make_shared>(1, 0)}, {{12, 15}, std::make_shared>( M_PI / 3, 0.5, -M_PI / 2 + 3, 0.5)}, }, 0)}, {Categories::Good, PartialFunction( { {{12, 15}, std::make_shared>( M_PI / 3, 0.5, -M_PI / 2, 0.5)}, {{15, 18}, std::make_shared>(1, 0)}, {{18, 21}, std::make_shared>( M_PI / 3, 0.5, -M_PI / 2 + 3, 0.5)}, }, 0)}}, true) {} }; const std::map MyAgent::CategoryNames{ {Categories::Bad, "Bad"}, {Categories::Normal, "Normal"}, {Categories::Good, "Good"}}; int main(void) { LOG_INFO_STREAM << library_string() << " -- " << Color::Red << "agent-functionalities example" << Color::Default << '\n'; std::unique_ptr S = MessagingSystem::createSystem("Sys"); MessagingSystem *SP = S.get(); AgentHandle A = SystemTester::createMyAgent(SP, "MyAgent"); std::vector Vs{0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 13, 15, 14, 15, 16, 19, 20, 21}; for (auto I = Vs.begin(); I != Vs.end(); ++I) { A.send(MyAgent::Tick::Value, *I); } SystemTester::destroyMyAgent(SP, A); return 0; } diff --git a/include/rosa/agent/RangeConfidence.hpp b/include/rosa/agent/RangeConfidence.hpp index 0d8732e..60a53c1 100644 --- a/include/rosa/agent/RangeConfidence.hpp +++ b/include/rosa/agent/RangeConfidence.hpp @@ -1,109 +1,108 @@ //===-- rosa/agent/RangeConfidence.hpp --------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/agent/RangeConfidence.hpp /// /// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *RangeConfidence* *functionality*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_RANGECONFIDENCE_HPP #define ROSA_AGENT_RANGECONFIDENCE_HPP -#include "rosa/agent/Functionality.h" #include "rosa/agent/Abstraction.hpp" #include "rosa/agent/FunctionAbstractions.hpp" +#include "rosa/agent/Functionality.h" #include "rosa/support/debug.hpp" #include -#include #include #include +#include namespace rosa { namespace agent { /// Evaluates a map of ID's to Abstractions at a given value and returns the /// results as a map from ID's to results of the corresponding Abstraction /// /// \note This implementation is supposed to be used to abstract ranges of /// arithmetic types into maps whose values are of another arithmetic type, /// which is statically enforced. /// /// \tparam D type to abstract from /// \tparam I type the type of the ID's /// \tparam R type of the range template class RangeConfidence : protected Abstraction>, - private std::map>{ + private std::map> { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), - "abstracting not to arithmetic"); + "abstracting not to arithmetic"); private: /// Wether to include default results in the result-map or not bool IgnoreDefaults; public: /// Creates an instance by Initializing the underlying \c Abstraction and /// \c std::map. /// /// \param Abstractions the Abstractions to be evaluated /// \param IgnoreDefaults wether to include default results in the result-map /// or not (defaults to false). RangeConfidence(const std::map> &Abstractions, - bool IgnoreDefaults = false) - : Abstraction>({}), - std::map>(Abstractions), - IgnoreDefaults(IgnoreDefaults){ - } + bool IgnoreDefaults = false) + : Abstraction>({}), std::map>( + Abstractions), + IgnoreDefaults(IgnoreDefaults) {} /// Destroys \p this object. ~RangeConfidence(void) = default; /// Checks wether all Abstractions evaluate to default at the given position /// /// \param V the value at which to check if the functions falls back to it's /// default value. /// /// \return true, if all Abstractions evaluate to default bool isDefaultAt(const D &V) const noexcept override { - for (auto const& p : ((std::map>)*this)){ - if(!p.second.isDefaultAt(V)) - return false; - } + for (auto const &P : ((std::map>)*this)) { + if (!P.second.isDefaultAt(V)) + return false; + } return true; } /// All Abstractions stored in the underlying \c std::map are evaluated for /// the given value. Their results are stored in another map, with /// corresponding keys. /// If IgnoreDefaults is set, Abstractions that default for that value are not /// evaluated and inserted into the resulting \c std::map /// /// \param V value to abstract /// /// \return a \c std::map containing the results of the stored Abstractions, /// indexable by the key's the Abstractions are associated with std::map operator()(const D &V) const noexcept override { - std::map ret; - for (auto const& p : ((std::map>)*this)){ - if(!IgnoreDefaults || !p.second.isDefaultAt(V)) - ret.insert(std::pair(p.first, p.second(V))); + std::map Ret; + for (auto const &P : ((std::map>)*this)) { + if (!IgnoreDefaults || !P.second.isDefaultAt(V)) + Ret.insert(std::pair(P.first, P.second(V))); } - return ret; + return Ret; } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_RANGECONFIDENCE_HPP diff --git a/include/rosa/core/SystemBase.hpp b/include/rosa/core/SystemBase.hpp index a5ca0d2..4b6720e 100644 --- a/include/rosa/core/SystemBase.hpp +++ b/include/rosa/core/SystemBase.hpp @@ -1,138 +1,138 @@ //===-- rosa/core/SystemBase.hpp -----------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/core/SystemBase.hpp /// /// \author David Juhasz (david.juhasz@tuwien.ac.at) /// /// \date 2017 /// /// \brief Base implementation of the \c rosa::System interface. /// //===----------------------------------------------------------------------===// #ifndef ROSA_CORE_SYSTEMBASE_HPP #define ROSA_CORE_SYSTEMBASE_HPP #include "rosa/core/System.hpp" #include namespace rosa { /// Base implementation of the \c rosa::System interface. /// /// This implementation provides only equality checking and *name* for /// \c rosa::System, identifiers for \c rosa::Unit instances, and marking the /// \c rosa::System cleaned for destruction. /// /// \note Actual implementations of \c rosa::System and derived interfaces are /// supposed to inherit from this implementation. class SystemBase : public System { protected: /// Creates an instance. /// /// \note Protected constructor restrict instantiation for subclasses. /// /// \param Name name of the new instance SystemBase(const std::string &Name) noexcept; public: /// Destroys \p this object. /// /// \pre \p this object is marked cleaned:\code /// isSystemCleaned() /// \endcode ~SystemBase(void); /// Tells whether \p this object is the same as \p Other. /// /// Two \c rosa::System instances are considered equal if they share a common /// \c rosa::SystemBase::Name member field. That should do among various /// subclasses. /// /// \param Other another \c rosa::System instance to compare to /// /// \return whether \p this object and \p Other is the same bool operator==(const System &Other) const noexcept override; protected: /// The textual name of \p this object implementing \c rosa::System. const std::string Name; private: /// Number of \c rosa::Unit instances constructed by \p this object. /// /// \note Should never be decremented! std::atomic UnitCount; /// Indicates that \p this object has been cleaned and is ready for /// destruction. /// /// The field is initialized as \c false and can be set by /// \c rosa::SystemBase::markCleaned. /// /// \note Subclasses must set the flag upon destructing their instances, which /// indicates to the destructor of the base-class that all the managed /// resources has been properly released. std::atomic SystemIsCleaned; public: /// Tells the name of \p this object /// /// \note The returned reference remains valid as long as \p this object is /// not destroyed. /// /// \return reference to \c rosa::SystemBase::Name const std::string &name(void) const noexcept override; protected: /// Tells the next unique identifier to be used for a newly created /// \c rosa::Unit. /// /// The functions takes the current value of the internal counter /// \c rosa::SystemBase::UnitCount and then increments it. /// /// \note This is the only function modifying /// \c rosa::SystemBase::UnitCount. /// /// \return \c rosa::id_t which is unique within the context of \p this /// object. id_t nextId(void) noexcept override; /// Tells if \p this object has been marked cleaned and is ready for /// destruction. /// /// \return if \p this object is marked clean. bool isSystemCleaned(void) const noexcept override; /// Marks \p this object cleaned by setting /// \c rosa::SystemBase::SystemIsCleaned. /// /// \note Can be called only once when the System does not have any live /// \c rosa::Unit instances. /// /// \pre \p this object has not yet been marked as cleaned and it has no /// \c rosa::Unit instances registered:\code /// !isSystemCleaned() && empty() /// \endcode /// /// \post \p this object is marked cleaned:\code /// isSystemCleaned() /// \endcode void markCleaned(void) noexcept override; /// Tells the number of \c rosa::Unit instances constructed in the context of /// \p this object so far, including those being already destroyed. /// /// \return current value of \c rosa::SystemBase::UnitCount that is the number /// of \c rosa::Unit instances created so far size_t numberOfConstructedUnits(void) const noexcept override; }; } // End namespace rosa -#endif // ROSA_LIB_CORE_SYSTEMBASE_HPP +#endif // ROSA_CORE_SYSTEMBASE_HPP diff --git a/include/rosa/deluxe/DeluxeSystem.hpp b/include/rosa/deluxe/DeluxeSystem.hpp index 4388a4e..1be3bbd 100755 --- a/include/rosa/deluxe/DeluxeSystem.hpp +++ b/include/rosa/deluxe/DeluxeSystem.hpp @@ -1,211 +1,210 @@ //===-- rosa/deluxe/DeluxeSystem.hpp ----------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/deluxe/DeluxeSystem.hpp /// /// \author David Juhasz (david.juhasz@tuwien.ac.at) /// /// \date 2017-2019 /// /// \brief Specialization of \c rosa::MessagingSystem for the *deluxe /// interface*. /// /// \see \c rosa::deluxe::DeluxeContext /// //===----------------------------------------------------------------------===// #ifndef ROSA_DELUXE_DELUXESYSTEM_HPP #define ROSA_DELUXE_DELUXESYSTEM_HPP #include "rosa/core/MessagingSystem.hpp" #include "rosa/deluxe/DeluxeAgent.hpp" #include "rosa/deluxe/DeluxeSensor.hpp" namespace rosa { namespace deluxe { /// Implements and extends the \c rosa::MessagingSystem interface to be /// used by \c rosa::deluxe::DeluxeContext. /// /// The class is a specialization of \c rosa::MessagingSystem, where objects /// of two specialized subtypes of \c rosa::Agent, \c rosa::deluxe::DeluxeSensor /// and \c rosa::deluxe::DeluxeAgent, constitute a system. The class extends the /// \c rosa::MessagingSystem interface with features required to implement the /// *deluxe interface*. /// /// \see rosa::deluxe::DeluxeContext class DeluxeSystem : public MessagingSystem { friend class DeluxeContext; public: /// Returns an object implementing the \c rosa::deluxe::DeluxeSystem /// interface. /// /// \param Name name of the new instance /// /// \return \c std::unique_ptr for the new instance of /// \c rosa::DeluxeSystem static std::unique_ptr createSystem(const std::string &Name) noexcept; protected: /// Creates a new instance. /// /// \note Protected constructor restricts instantiation for subclasses. DeluxeSystem(void) noexcept = default; public: /// Creates a \c rosa::deluxe::DeluxeSensor instance owned by \p this object /// and returns a \p rosa::AgentHandle for it. /// /// \tparam T type of data the new \c rosa::deluxe::DeluxeSensor operates on /// /// \param Name name of the new \c rosa::deluxe::DeluxeSensor /// \param F function to generate the next value with during normal operation /// /// \return \c rosa::AgentHandle for new \c rosa::deluxe::DeluxeSensor template AgentHandle createSensor(const std::string &Name, DeluxeSensor::D &&F) noexcept; /// Creates a \c rosa::deluxe::DeluxeAgent instance owned by \p this object /// and returns a \c rosa::AgentHandle for it. /// /// \tparam T type of data the new \c rosa::deluxe::DeluxeAgent outputs /// \tparam As types of inputs the new \c rosa::deluxe::DeluxeAgent takes /// /// \param Name name of the new \c rosa::deluxe::DeluxeAgent /// \param F function for the new \c rosa::deluxe::DeluxeAgent to process /// input values and generate output with /// /// \return \c rosa::AgentHandle for new \c rosa::deluxe::DeluxeAgent template AgentHandle createAgent(const std::string &Name, DeluxeAgent::D &&F) noexcept; protected: /// Tells whether a \c rosa::AgentHandle refers to a /// \c rosa::deluxe::DeluxeSensor owned by \p this object. /// /// \param H \c rosa::AgentHandle to check /// /// \return whether \p H refers to a \c rosa::deluxe::DeluxeSensor owned by /// \p this object virtual bool isDeluxeSensor(const AgentHandle &H) const noexcept = 0; /// Extracts a const qualified \c rosa::deluxe::DeluxeSensor reference from a /// const qualified \c rosa::AgentHandle if possible. /// /// The function returns a \c rosa::Optional object containing a const /// qualified reference to a \c rosa::deluxe::DeluxeSensor object extracted /// from a const qualified \c rosa::AgentHandle instance if the referred /// object is of type \c rosa::deluxeDeluxeSensor and owned by \p this object. /// The returned \c rosa::Optional object is empty otherwise. /// /// \see rosa::deluxe::DeluxeSystem::isDeluxeSensor /// /// \param H \c rosa::AgentHandle to extract a \c rosa::deluxe::DeluxeSensor /// from /// /// \return const qualified reference to \c rosa::deluxe::DeluxeSensor if /// \p H refers to an object which is of that type and is owned by \p this /// object Optional getDeluxeSensor(const AgentHandle &H) const noexcept; /// Extracts a \c rosa::deluxe::DeluxeSensor reference from a /// \c rosa::AgentHandle if possible. /// /// The function returns a \c rosa::Optional object containing a reference to /// a \c rosa::deluxe::DeluxeSensor object extracted from a /// \c rosa::AgentHandle instance if the referred object is of type /// \c rosa::deluxeDeluxeSensor and owned by \p this object. The returned /// \c rosa::Optional object is empty otherwise. /// /// \see rosa::deluxe::DeluxeSystem::isDeluxeSensor /// /// \param H \c rosa::AgentHandle to extract a \c rosa::deluxe::DeluxeSensor /// from /// /// \return reference to \c rosa::deluxe::DeluxeSensor if \p H refers to an /// object which is of that type and is owned by \p this object Optional getDeluxeSensor(AgentHandle &H) const noexcept; /// Tells whether a \c rosa::AgentHandle refers to a /// \c rosa::deluxe::DeluxeAgent owned by \p this object. /// /// \param H \c rosa::AgentHandle to check /// /// \return whether \p H refers to a \c rosa::deluxe::DeluxeAgent owned by /// \p this object virtual bool isDeluxeAgent(const AgentHandle &H) const noexcept = 0; /// Extracts a const qualified \c rosa::deluxe::DeluxeAgent reference from a /// const qualified \c rosa::AgentHandle if possible. /// /// The function returns a \c rosa::Optional object containing a const /// qualified reference to a \c rosa::deluxe::DeluxeAgent object extracted /// from a const qualified \c rosa::AgentHandle instance if the referred /// object is of type \c rosa::deluxeDeluxeAgent and owned by \p this object. /// The returned \c rosa::Optional object is empty otherwise. /// /// \see rosa::deluxe::DeluxeSystem::isDeluxeAgent /// /// \param H \c rosa::AgentHandle to extract a \c rosa::deluxe::DeluxeAgent /// from /// /// \return const qualified reference to \c rosa::deluxe::DeluxeAgent if \p H /// refers to an object which is of that type and is owned by \p this object Optional getDeluxeAgent(const AgentHandle &H) const noexcept; /// Extracts a \c rosa::deluxe::DeluxeAgent reference from a /// \c rosa::AgentHandle if possible. /// /// The function returns a \c rosa::Optional object containing a reference to /// a \c rosa::deluxe::DeluxeAgent object extracted from a /// \c rosa::AgentHandle instance if the referred object is of type /// \c rosa::deluxeDeluxeAgent and owned by \p this object. The returned /// \c rosa::Optional object is empty otherwise. /// /// \see rosa::deluxe::DeluxeSystem::isDeluxeAgent /// /// \param H \c rosa::AgentHandle to extract a \c rosa::deluxe::DeluxeAgent /// from /// /// \return reference to \c rosa::deluxe::DeluxeAgent if \p H refers to an /// object which is of that type and is owned by \p this object Optional getDeluxeAgent(AgentHandle &H) const noexcept; }; template AgentHandle DeluxeSystem::createSensor(const std::string &Name, DeluxeSensor::D &&F) noexcept { Agent &DS = createUnit( [&](const id_t Id, MessagingSystem &S) { return new DeluxeSensor(atoms::SensorKind, Id, Name, S, std::move(F)); }); return {DS}; } template -AgentHandle -DeluxeSystem::createAgent(const std::string &Name, - DeluxeAgent::D &&F) noexcept { - +AgentHandle DeluxeSystem::createAgent(const std::string &Name, + DeluxeAgent::D &&F) noexcept { + Agent &DA = createUnit( [&](const id_t Id, DeluxeSystem &S) { return new DeluxeAgent(atoms::AgentKind, Id, Name, S, std::move(F)); }); return {DA}; } } // End namespace deluxe } // End namespace rosa -#endif // ROSA_LIB_DELUXE_DELUXESYSTEM_HPP +#endif // ROSA_DELUXE_DELUXESYSTEM_HPP diff --git a/lib/core/MessagingSystemImpl.hpp b/lib/core/MessagingSystemImpl.hpp index 485711a..89a366b 100644 --- a/lib/core/MessagingSystemImpl.hpp +++ b/lib/core/MessagingSystemImpl.hpp @@ -1,109 +1,110 @@ //===-- core/MessagingSystemImpl.hpp ----------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file core/MessagingSystemImpl.hpp /// /// \author David Juhasz (david.juhasz@tuwien.ac.at) /// /// \date 2017 /// /// \brief Declaration of a basic implementation of the \c rosa::MessagingSystem /// interface. /// //===----------------------------------------------------------------------===// #ifndef ROSA_LIB_CORE_MESSAGINGSYSTEMIMPL_HPP #define ROSA_LIB_CORE_MESSAGINGSYSTEMIMPL_HPP #include "SystemImpl.hpp" #include "rosa/core/MessagingSystem.hpp" namespace rosa { /// Implements \c rosa::MessagingSystem by extending \c rosa::SystemImpl with /// adding a simple implementation of sending messages: directly invoking /// \c rosa::Agent instances with given \c rosa::Message objects. /// /// \note Keep in mind that sending a \c rosa::Message object with this /// implementation translates into a direct function call. class MessagingSystemImpl : public MessagingSystem, public SystemImpl { /// Alies for the base-class \c rosa::SystemImpl. using Base = SystemImpl; public: /// Creates an instance. /// /// \param Name name of the new instance MessagingSystemImpl(const std::string &Name) noexcept; - /// \defgroup MessagingSystemImplCallForwarding Call forwardings of rosa::MessagingSystemImpl + /// \defgroup MessagingSystemImplCallForwarding Call forwardings of + /// rosa::MessagingSystemImpl /// /// \c rosa::MessagingSystemImpl call forwardings /// /// \note Simply forwarding calls to implementations provided by /// \c rosa::MessagingSystem::Base for the \c rosa::System interface. /// /// \todo How could we use the inherited implementations in a simpler way? ///@{ bool operator==(const System &Other) const noexcept override { return Base::operator==(Other); } protected: id_t nextId(void) noexcept override { return Base::nextId(); } bool isSystemCleaned(void) const noexcept override { return Base::isSystemCleaned(); } void markCleaned(void) noexcept override { Base::markCleaned(); } void registerUnit(Unit &U) noexcept override { Base::registerUnit(U); } void destroyUnit(Unit &U) noexcept override { Base::destroyUnit(U); } bool isUnitRegistered(const Unit &U) const noexcept override { return Base::isUnitRegistered(U); } public: const std::string &name(void) const noexcept override { return Base::name(); } size_t numberOfConstructedUnits(void) const noexcept override { return Base::numberOfConstructedUnits(); } size_t numberOfLiveUnits(void) const noexcept override { return Base::numberOfLiveUnits(); } bool empty(void) const noexcept override { return Base::empty(); } ///@} /// Sends a \c rosa::message_t instance to the \c rosa::Agent instance /// referred by a \c rosa::AgentHandle -- by directly invoking the /// \c rosa::Agent instance with the \c rosa::Message object. /// /// \note If the given \c rosa::Message object cannot be handled by the /// referred \c rosa::Agent instance, the \c rosa::Message object is simply /// ignored. /// /// \param H refers to the \c rosa::Agent instance to send to /// \param M message to send /// /// \pre The referred \c rosa::Agent instance is owned by \p this object and /// also registered: \code /// &unwrapSystem(H) == this && isUnitRegistered(unwrapAgent(H)) /// \endcode void send(const AgentHandle &H, message_t &&M) noexcept override; }; } // End namespace rosa #endif // ROSA_LIB_CORE_MESSAGINGSYSTEMIMPL_HPP