Page MenuHomePhorge

System.hpp
No OneTemporary

Size
7 KB
Referenced Files
None
Subscribers
None

System.hpp

//===-- rosa/core/System.hpp ------------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/core/System.hpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Declaration of *System* interface.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_CORE_SYSTEM_HPP
#define ROSA_CORE_SYSTEM_HPP
#include "rosa/config/config.h"
#include "rosa/core/forward_declarations.h"
#include "rosa/support/debug.hpp"
#include "rosa/support/log.h"
#include <functional>
#include <memory>
#include <string>
namespace rosa {
/// Base interface for actual agent-systems.
///
/// The class provides facilities to keep track of \c rosa::Unit instances owned
/// by a \c rosa::System.
///
/// \note Any subclass is supposed to provide thread-safe implementation.
///
/// \note The class declares only an interface to avoid trouble with multiple
/// inheritance in various subclasses as in derived interfaces and derived
/// implementations.
///
/// \note Actual implementations are supposed to derive from \c rosa::SystemBase
/// implenenting a base feature-set.
class System {
public:
/// Signature of creator functions for \c rosa::Unit instances.
///
/// \note The function is to be \c noexcept.
///
/// \tparam T type derived from \c rosa::Unit
/// \tparam S type derived from \c rosa::System
template <typename T, typename S>
using UnitCreator = std::function<T *(const id_t, S &)>;
/// Returns an object implementing the \c rosa::System interface.
///
/// \param Name name of the new instance
///
/// \return \c std::unique_ptr for a new instance of \c rosa::System
static std::unique_ptr<System> createSystem(const std::string &Name) noexcept;
protected:
/// Creates an instance.
///
/// \note Protected constructor restricts instantiation for subclasses.
System(void) noexcept = default;
/// No copying and moving of \c rosa::System.
///@{
System(const System &) = delete;
System(System &&) = delete;
System &operator=(const System &) = delete;
System &operator=(System &&) = delete;
///@}
public:
/// Destroys \p this object.
///
/// \note Any implementation makes sure that a \c rosa::System can be
/// destroyed only if it is marked *cleaned*
/// \see \c rosa::System::isSystemCleaned
virtual ~System(void) = default;
/// Tells whether \p this object is the same as \p Other.
///
/// \note Whenever checking equality of two objects, use the one with the
/// more specialized static type on the left-hand side of the operator. The
/// static type of the object on the right-hand side is better to be
/// \c rosa::System, ambiguous conversion might happen otherwise.
///
/// \param Other another \c rosa::System instance to compare to
///
/// \return whether \p this object and \p Other is the same
virtual bool operator==(const System &Other) const noexcept = 0;
/// Tells whether \p this object is not the same as \p Other.
///
/// \note Whenever checking inequality of two objects, use the one with the
/// more specialized static type on the left-hand side of the operator. The
/// static type of the object on the right-hand side is better to be
/// \c rosa::System, ambiguous conversion might happen otherwise.
///
/// \param Other another \c rosa::System instance to compare to
///
/// \return whether \p this object and \p Other is not the same
bool operator!=(const System &Other) const noexcept {
return !operator==(Other);
}
protected:
/// Tells the next unique identifier to be used for a newly created
/// \c rosa::Unit.
///
/// \return \c rosa::id_t which is unique within the context of \p this
/// object.
///
/// \note Never returs the same value twice.
virtual id_t nextId(void) noexcept = 0;
/// Tells if \p this object has been marked cleaned and is ready for
/// destruction.
///
/// \return if \p this object is marked clean.
virtual bool isSystemCleaned(void) const noexcept = 0;
/// Marks \p this object cleaned.
///
/// \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
virtual void markCleaned(void) noexcept = 0;
/// Registers a \c rosa::Unit instance to \p this object.
///
/// \param U \c rosa::Unit to register
///
/// \pre \p this object has not yet been marked as cleaned and \p U is not
/// registered yet:\code
/// !isSystemCleaned() && !isUnitRegistered(U)
/// \endcode
///
/// \post \p U is registered:\code
/// isUnitRegistered(U)
/// \endcode
virtual void registerUnit(Unit &U) noexcept = 0;
/// Unregisters and destroys a registered \c rosa::Unit instance.
///
/// \param U \c rosa::Unit to destroy
///
/// \pre \p U is registered:\code
/// isUnitRegistered(U)
/// \endcode
///
/// \post \p U is not registered and also destroyed.
virtual void destroyUnit(Unit &U) noexcept = 0;
/// Tells if a \c rosa::Unit is registered in \p this object.
///
/// \param U \c rosa::Unit to check
///
/// \return whether \p U is registered in \p this object
virtual bool isUnitRegistered(const Unit &U) const noexcept = 0;
/// Creates a \c rosa::Unit instance with the given
/// \c rosa::System::UnitCreator and registers the new instance.
///
/// \tparam T type of the actual \c rosa::Unit to instantiate
/// \tparam S type of the actual \c rosa::System instantiating
///
/// \param C function creating an instance of type \p T
///
/// \note \p S must be the actual subclass that wants to instantiate
/// \c rosa::Unit. That cannot be statically enforced, it is the
/// reponsibility of the caller to provide the proper \c rosa::System
/// subclass.
///
/// \pre Statically, \p T is a subclass of \c rosa::Unit and \p S is a
/// subclass of \c rosa::System:
/// \code
/// std::is_base_of<Unit, T>::value && std::is_base_of<System, S>::value
/// \endcode
/// Dynamically, \p this object has not yet been marked cleaned:\code
/// !isSystemCleaned()
/// \endcode
template <typename T, typename S> T &createUnit(UnitCreator<T, S> C) noexcept;
public:
/// Tells the name of \p this object
///
/// \note The returned reference remains valid as long as \p this object is
/// not destroyed.
///
/// \return name of \p this object
virtual const std::string &name(void) const noexcept = 0;
/// Tells the number of \c rosa::Unit instances constructed in the context of
/// \p this object so far, including those being already destroyed.
///
/// \return number of \c rosa::Unit instances created so far
virtual size_t numberOfConstructedUnits(void) const noexcept = 0;
/// Tells the number of live \c rosa::Unit instances in the context \p this
/// object, those being constructed and not destroyed yet.
///
/// \return number of \c rosa::Unit instances alive
virtual size_t numberOfLiveUnits(void) const noexcept = 0;
/// Tells if \p this object has no live \c rosa::Unit instances.
///
/// \return whether \p this object has any live \c rosa::Unit instances
virtual bool empty(void) const noexcept = 0;
};
template <typename T, typename S>
T &System::createUnit(UnitCreator<T, S> C) noexcept {
STATIC_ASSERT((std::is_base_of<Unit, T>::value), "not a Unit");
STATIC_ASSERT((std::is_base_of<System, S>::value), "not a System");
if (isSystemCleaned()) {
ROSA_CRITICAL("Trying to create a Unit in a cleaned System '" + name() +
"'");
}
const id_t Id = nextId();
T *U = C(Id, static_cast<S &>(*this));
registerUnit(*U);
LOG_TRACE("Unit created and registered '" + U->FullName + "'");
return *U;
}
} // End namespace rosa
#endif // ROSA_CORE_SYSTEM_HPP

File Metadata

Mime Type
text/x-c++
Expires
Sun, Jun 8, 8:16 PM (1 d, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
150100
Default Alt Text
System.hpp (7 KB)

Event Timeline