Page MenuHomePhorge

System.hpp
No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None

System.hpp

/***************************************************************************//**
*
* \file rosa/core/System.hpp
*
* \author David Juhasz (david.juhasz@tuwien.ac.at)
*
* \date 2017
*
* \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 `rosa::Unit` instances owned
/// by `this` `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 `rosa::SystemBase`
/// implenenting a base feature-set.
class System {
public:
/// Signature of creator functions for `rosa::Unit` instances.
///
/// \tparam T type derived from `rosa::Unit`
/// \tparam S type derived from `rosa::System`
template <typename T, typename S>
using UnitCreator = std::function<T *(const id_t, S &)noexcept>;
/// Returns an object implementing the `rosa::System` interface.
///
/// \param Name name of the new instance
///
/// \return `std::unique_ptr` for a new instance of `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 `rosa::System`.
///@{
System(const System&) = delete;
System(System&&) = delete;
System &operator=(const System&) = delete;
System &operator=(System&&) = delete;
///@}
public:
/// Destroys `this` object.
///
/// \note Any implementation makes sure that a `rosa::System` can be
/// destroyed only if it is marked *cleaned*
/// \see rosa::System::isSystemCleaned
virtual ~System(void) = default;
protected:
/// Tells the next unique identifier to be used for a newly created
/// `rosa::Unit`.
///
/// \return `id_t` which is unique within the context of `this` object.
///
/// \note Never returs the same value twice.
virtual id_t nextId(void) noexcept = 0;
/// Tells if `this` object has been marked cleaned and is ready for
/// destruction.
///
/// \return if `this` object is marked clean.
virtual bool isSystemCleaned(void) const noexcept = 0;
/// Marks `this` object cleaned.
///
/// \note Can be called only once when the System does not have any live
/// `rosa::Unit` instances.
///
/// \pre `this` object has not yet been marked as cleaned and it has no
/// `rosa::Unit` instances registered:\code
/// !isSystemCleaned() && empty()
/// \endcode
///
/// \post `this` object is marked cleaned:\code
/// isSystemCleaned()
/// \encode
virtual void markCleaned(void) noexcept = 0;
/// Registers a `rosa::Unit` instance to `this` object.
///
/// \param U `rosa::Unit` to register
///
/// \pre `this` object has not yet been marked as cleaned and `U` is not
/// registered yet:\code
/// !isSystemCleaned() && !isUnitRegistered(U)
/// \endcode
///
/// \post `U` is registered:\code
/// isUnitRegistered(U)
/// \endcode
virtual void registerUnit(Unit &U) noexcept = 0;
/// Unregisters and destroys a registered `rosa::Unit` instance.
///
/// \param U `rosa::Unit` to destroy
///
/// \pre `U` is registered:\code
/// isUnitRegistered(U)
/// \endcode
///
/// \post `U` is not registered:\code
/// !isUnitRegistered(U)
/// \endcode Moreover, `U` is destroyed.
virtual void destroyUnit(Unit &U) noexcept = 0;
/// Tells if a `rosa::Unit` is registered in `this` object.
///
/// \param U `rosa::Unit` to check
///
/// \return whether `U` is registered in `this` object
virtual bool isUnitRegistered(const Unit &U) const noexcept = 0;
/// Creates a `rosa::Unit` instance with the given `rosa::System::UnitCreator`
/// and registers the new instance.
///
/// \tparam T type of the actual `rosa::Unit` to instantiate
/// \tparam S type of the actual `rosa::System` instantiating
///
/// \param C function creating an instance of type `T`
///
/// \note `S` must be the actual subclass that wants to instantiate
/// `rosa::Unit`. That cannot be statically enforced, it is the
/// reponsibility of the caller to provide the proper `rosa::System` subclass.
///
/// \pre Statically, `T` is a subclass of `rosa::Unit` and `S` is a subclass
/// of `rosa::System`:\code
/// std::is_base_of<Unit, T>::value && std::is_base_of<System, S>::value
/// \endcode Dynamically, `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 `this` object
///
/// \note The returned reference remains valid as long as `this` object is not
/// destroyed.
///
/// \return name of `this` object
virtual const std::string &name(void) const noexcept = 0;
/// Tells the number of `rosa::Unit` instances constructed in the context of
/// `this`object so far, including those being already destroyed.
///
/// \return number of `rosa::Unit`instances created so far
virtual size_t numberOfConstructedUnits(void) const noexcept = 0;
/// Tells the number of live `rosa::Unit` instances in the context `this`
/// object, those being constructed and not destroyed yet.
///
/// \return number of `rosa::Unit` instances alive
virtual size_t numberOfLiveUnits(void) const noexcept = 0;
/// Tells if `this` object has no live `rosa::Unit` instances.
///
/// \return whether `this` object has any live `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
Thu, Jan 15, 7:58 PM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
261176
Default Alt Text
System.hpp (6 KB)

Event Timeline