diff --git a/include/rosa/core/System.h b/include/rosa/core/System.h index ffed832..6594af4 100644 --- a/include/rosa/core/System.h +++ b/include/rosa/core/System.h @@ -1,115 +1,115 @@ /******************************************************************************* * * File: System.h * * Contents: Declaration of System base-class. * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ #ifndef ROSA_CORE_SYSTEM_H #define ROSA_CORE_SYSTEM_H #include #include #include namespace rosa { // Forward declarations. class Unit; // Base-class for actual agent-systems, the class provides facitlities to keep // track of Units of the system. // NOTE: This class and any subclasses are supposed to provide thread-safe // interfaces. class System { public: // Signature of creator functions for Units. using UnitCreator = Unit *(*)(const size_t, const std::string&, System&); // Returns an object implementing the interface defined by the class. - static std::unique_ptr createSystem(const std::string &Name); + static std::unique_ptr createSystem(const std::string &Name) noexcept; protected: // Protected ctor, only subclasses can instantiate. System(const std::string &Name) noexcept; // No copy and move. System(const System&) = delete; System(System&&) = delete; System &operator=(const System&) = delete; System &operator=(System&&) = delete; public: // Dtor. Only a cleared System can be destroyed. // PRE: SystemCleaned virtual ~System(void); protected: // Sets SystemCleaned flag. Can be called only once and the System must not // have any live Units. // PRE: !SystemCleaned && empty() // POST: SystemCleaned void markCleaned(void) noexcept; // Creates a Unit instance with the given UnitCreator, using the given Name // if any, then registers the new Unit instance by calling the virtual // member function registerUnit. // NOTE: This function handles the member field CountUnits. // PRE: !SystemCleaned Unit &createUnit(UnitCreator C, const std::string &Name = std::string()) noexcept; // Registers the given Unit instance to the System. // PRE: !isUnitRegistered(U) // POST: isUnitRegistered(U) virtual void registerUnit(Unit &U) noexcept = 0; // Unregisters and destroys the given Unit. // PRE: isUnitRegistered(U) // POST: !isUnitRegistered(U) && 'U is destroyed' virtual void destroyUnit(Unit &U) noexcept = 0; // Returns if the given Unit is registered in the System. virtual bool isUnitRegistered(const Unit &U) const noexcept = 0; public: // The textual name of the System. const std::string Name; private: // Number of Units constructed in the system. // NOTE: Should never be decremented! std::atomic CountUnits; // Indicates that the System has been cleaned and is ready for destruction. // The field is initialized as 'false' and can be set by the member function // markCleaned. // Subclasses must set the flag upon destroying the System instance, which // indicates to the destructor of the base-class that all the managed // resources has been properly released. std::atomic SystemCleaned; public: // Returns the number of Units constructed in the System so far, // including those being already destroyed. size_t numberOfConstructedUnits(void) const noexcept; // Returns the number of live Units, that have been constructed and not // destroyed yet. virtual size_t numberOfLiveUnits(void) const noexcept = 0; // Returns if the System has no live Units. virtual bool empty(void) const noexcept = 0; }; } // End namespace rosa #endif // ROSA_CORE_SYSTEM_H diff --git a/include/rosa/core/Unit.h b/include/rosa/core/Unit.h index 7c5fb8f..9d2f71f 100644 --- a/include/rosa/core/Unit.h +++ b/include/rosa/core/Unit.h @@ -1,76 +1,76 @@ /******************************************************************************* * * File: Unit.h * * Contents: Declaration of Unit base-class. * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ #ifndef ROSA_CORE_UNIT_H #define ROSA_CORE_UNIT_H #include #include namespace rosa { // Forward declarations. class System; // Base class for every entity in the system that has to be identified and // traced. // NOTE: Life-cycle of Unit instances is supposed to be managed by a System, do // not create and destroy a Unit directly. class Unit { public: // System-assigned unique identifier of the Unit instance, // based on the static member field CountUnits. const size_t Id; // Textual identifier of the Unit instance. Defaults to a text referring to // the Id value of the Unit, unless otherwise defined via a constructor // argument. The Name of a Unit is not necessarily unique in the system. const std::string Name; protected: // The owning System. System &S; public: // Full qualified name of the Unit instance. const std::string FullName; public: // Ctor. Unit(const size_t Id, const std::string &Name, System &S) noexcept; // No copy and move. Unit(const Unit &) = delete; Unit(Unit &&) = delete; Unit &operator=(const Unit &) = delete; Unit &operator=(Unit &&) = delete; // Dtor. - virtual ~Unit(void) noexcept; + virtual ~Unit(void); // Returns a reference to the owning System. // NOTE: Subclasses may override the function to return a reference of a // special System subtype. virtual System &system() const noexcept; // Dumping the object into a string for tracing purposes, // subclasses are supposed to override this function. virtual std::string dump(void) const noexcept; }; // Helper function dumping the given Unit instance to the given output stream. std::ostream &operator<<(std::ostream &os, const Unit &U); } // End namespace rosa #endif // ROSA_CORE_UNIT_H diff --git a/lib/core/System.cpp b/lib/core/System.cpp index 1d086d0..4d97e23 100644 --- a/lib/core/System.cpp +++ b/lib/core/System.cpp @@ -1,68 +1,68 @@ /******************************************************************************* * * File: System.cpp * * Contents: Implementation of System base-class. * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ #include "SystemImpl.h" #include "rosa/config/config.h" #include "rosa/core/Unit.h" #include "rosa/core/System.h" #include "rosa/support/debug.hpp" #include "rosa/support/log.h" namespace rosa { -std::unique_ptr System::createSystem(const std::string &Name) { +std::unique_ptr System::createSystem(const std::string &Name) noexcept { return std::unique_ptr(new SystemImpl(Name)); } System::System(const std::string &Name) noexcept : Name(Name), CountUnits(0), SystemCleaned(false) { LOG_TRACE("Creating System (" + Name + ")"); } System::~System(void) { LOG_TRACE("Destroying System (" + Name + ")"); if (!SystemCleaned) { ROSA_CRITICAL("Trying to destroy a uncleaned System (" + Name + ")"); } } void System::markCleaned(void) noexcept { if (SystemCleaned) { ROSA_CRITICAL("System (" + Name + ") has been already mark cleaned"); } else if (!empty()) { ROSA_CRITICAL("Trying to mark a non-empty System (" + Name + ")"); } else { SystemCleaned = true; LOG_TRACE("System (" + Name + ") is marked clean"); } } Unit &System::createUnit(UnitCreator C, const std::string &Name) noexcept { if (SystemCleaned) { ROSA_CRITICAL("Trying to create a Unit in an already cleaned System (" + Name + ")"); } const uint64_t Id = ++CountUnits; const std::string N = Name.empty() ? "Unit_" + std::to_string(Id) : Name; Unit *U = C(Id, N, *this); registerUnit(*U); LOG_TRACE("Unit created and registered (" + U->FullName + ")"); return *U; } size_t System::numberOfConstructedUnits(void) const noexcept { return CountUnits; } } // End namespace rosa diff --git a/lib/core/Unit.cpp b/lib/core/Unit.cpp index bda3e1e..d0a6039 100644 --- a/lib/core/Unit.cpp +++ b/lib/core/Unit.cpp @@ -1,49 +1,49 @@ /******************************************************************************* * * File: Unit.cpp * * Contents: Implementation of Unit base-class. * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ #include "rosa/core/Unit.h" #include "rosa/core/System.h" #include "rosa/support/debug.hpp" #include "rosa/support/log.h" namespace rosa { // Ctor. Initializing member fields. Unit::Unit(const size_t Id, const std::string &Name, System &S) noexcept : Id(Id), Name(Name), S(S), FullName(Name + "@" + S.Name) { LOG_TRACE("Constructing Unit (" + FullName + ")"); } // Dtor. -Unit::~Unit(void) noexcept { LOG_TRACE("Destroying Unit (" + FullName + ")"); } +Unit::~Unit(void) { LOG_TRACE("Destroying Unit (" + FullName + ")"); } System &Unit::system(void) const noexcept { return S; } // Default dump function, emitting the Name of the Unit. std::string Unit::dump(void) const noexcept { LOG_TRACE("Dumping Unit (" + FullName + ")"); return "[Unit] " + FullName; } std::ostream &operator<<(std::ostream &os, const Unit &U) { os << U.dump(); return os; } } // End namespace rosa