diff --git a/examples/basic-system/basic-system.cpp b/examples/basic-system/basic-system.cpp index 1938e47..6adacae 100644 --- a/examples/basic-system/basic-system.cpp +++ b/examples/basic-system/basic-system.cpp @@ -1,69 +1,69 @@ /******************************************************************************* * * File: basic-system.cpp * * Contents: A simple example on the basic System and Unit classes of the RoSA * Core library. * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ #include "rosa/config/version.h" #include "rosa/core/Unit.h" #include "rosa/core/System.hpp" #include "rosa/support/log.h" #include "rosa/support/terminal_colors.h" #include using namespace rosa; using namespace rosa::terminal; // A dummy wrapper for testing System. // NOTE: Since we test System directly here, we need to get access to its // protected members. That we do by imitating to be a decent subclass of // System, while calling protected member functions on an object of a type from // which we actually don't inherit. struct SystemTester : protected System { static constexpr AtomValue UnitKind = atom("unit"); static Unit &createMyUnit(System *S, const std::string &Name = std::string()) { return ((SystemTester *)S) ->createUnit([&Name](const size_t Id, System &S) noexcept { // NOTE: If Name is empty, construct a name with the number of the // Unit being created right now. const std::string N( Name.empty() ? "Unit_" + std::to_string(S.numberOfConstructedUnits()) : Name); return new Unit(UnitKind, Id, N, S); }); } static void destroyMyUnit(System *S, Unit &U) { ((SystemTester *)S)->destroyUnit(U); } }; int main(void) { LOG_INFO_STREAM << library_string() << " -- " << Color::Red - << "simple example" << Color::Default << std::endl; + << "basic-system example" << Color::Default << std::endl; std::unique_ptr S = System::createSystem("Sys"); System *SP = S.get(); Unit &Unit1 = SystemTester::createMyUnit(SP), &Unit2 = SystemTester::createMyUnit(SP, "Second"), &Unit3 = SystemTester::createMyUnit(SP); SystemTester::destroyMyUnit(SP, Unit1); SystemTester::destroyMyUnit(SP, Unit3); LOG_INFO_STREAM << "Dumping Unit2" << std::endl << Unit2 << std::endl; SystemTester::destroyMyUnit(SP, Unit2); return 0; } diff --git a/lib/core/SystemImpl.cpp b/lib/core/SystemImpl.cpp index cca2317..3339938 100644 --- a/lib/core/SystemImpl.cpp +++ b/lib/core/SystemImpl.cpp @@ -1,71 +1,71 @@ /******************************************************************************* * * File: SystemImpl.cpp * - * Contents: Definition of the SystemImpl class + * Contents: Definition of the SystemImpl class. * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ #include "SystemImpl.hpp" #include "rosa/core/Unit.h" #include "rosa/config/config.h" #include "rosa/support/debug.hpp" #include "rosa/support/log.h" namespace rosa { SystemImpl::SystemImpl(const std::string &Name) noexcept : System(Name) {} SystemImpl::~SystemImpl(void) { if (!empty()) { ROSA_CRITICAL("Trying to destroy a non-empty System (" + Name + ")"); } else { markCleaned(); } } void SystemImpl::registerUnit(Unit &U) noexcept { // Obtain exclusive access and instert the Unit. std::lock_guard L(RegisterMutex); auto R = Units.insert(&U); if (!R.second) { ROSA_CRITICAL("Could not register Unit"); } } void SystemImpl::destroyUnit(Unit &U) noexcept { ASSERT(isUnitRegistered(U)); LOG_TRACE("Destroying Unit (" + U.FullName + ")"); // Scope protected container access. { // Obtain exclusive access and remove the Unit. std::lock_guard L(RegisterMutex); auto R = Units.erase(&U); // NOTE: This case is catched by assertion when that is enabled. if (!R) { ROSA_CRITICAL("Trying to remove unregistered Unit"); } } delete &U; } bool SystemImpl::isUnitRegistered(const Unit &U) const noexcept { // NOTE: Casting away constness is safe here. return Units.find(const_cast(&U)) != Units.cend(); } size_t SystemImpl::numberOfLiveUnits(void) const noexcept { return Units.size(); } bool SystemImpl::empty(void) const noexcept { return Units.empty(); } } // End namespace rosa diff --git a/lib/core/SystemImpl.hpp b/lib/core/SystemImpl.hpp index 2fb4ce3..ce2dc81 100644 --- a/lib/core/SystemImpl.hpp +++ b/lib/core/SystemImpl.hpp @@ -1,62 +1,64 @@ /******************************************************************************* * * File: SystemImpl.hpp * * Contents: Declaration of a basic implementation of the System interface. * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ #ifndef ROSA_LIB_CORE_SYSTEMIMPL_HPP // NOLINT #define ROSA_LIB_CORE_SYSTEMIMPL_HPP #include "rosa/core/System.hpp" #include #include namespace rosa { +// A basic implementation of the System interface, which simply stores Units in +// a set. class SystemImpl : public System { public: SystemImpl(const std::string &Name) noexcept; ~SystemImpl(void); private: // Container for keeping reference of registered Units. std::unordered_set Units; // Used to provide mutual exclusion when modifying Units. std::mutex RegisterMutex; protected: // Registers the given Unit instance to the System. // PRE: !isUnitRegistered(U) // POST: isUnitRegistered(U) void registerUnit(Unit &U) noexcept override; // Unregisters and destroys the given Unit. // PRE: isUnitRegistered(U) // POST: !isUnitRegistered(U) && 'U is destroyed' void destroyUnit(Unit &U) noexcept override; // Returns if the given Unit is registered in the System. bool isUnitRegistered(const Unit &U) const noexcept override; public: // Returns the number of live Units, that have been constructed and not // destroyed yet. size_t numberOfLiveUnits(void) const noexcept override; // Returns if the System has no live Units. bool empty(void) const noexcept override; }; } // End namespace rosa #endif // ROSA_LIB_CORE_SYSTEMIMPL_HPP