Merge remote-tracking branch 'upstream/mueller/master' into mueller/master

This commit is contained in:
2021-06-08 15:37:13 +02:00
89 changed files with 880 additions and 829 deletions

View File

@ -6,11 +6,23 @@
#endif
#include <cstdlib>
ObjectManager::ObjectManager( void (*setProducer)() ):
produceObjects(setProducer) {
//There's nothing special to do in the constructor.
ObjectManager* ObjectManager::objManagerInstance = nullptr;
ObjectManager* ObjectManager::instance() {
if(objManagerInstance == nullptr) {
objManagerInstance = new ObjectManager();
}
return objManagerInstance;
}
void ObjectManager::setObjectFactoryFunction(produce_function_t objFactoryFunc, void *factoryArgs) {
this->objectFactoryFunction = objFactoryFunc;
this->factoryArgs = factoryArgs;
}
ObjectManager::ObjectManager() {}
ObjectManager::~ObjectManager() {
for (auto const& iter : objectList) {
@ -28,10 +40,13 @@ ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) {
return this->RETURN_OK;
} else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ObjectManager::insert: Object id " << std::hex
<< static_cast<uint32_t>(id) << std::dec
<< " is already in use!" << std::endl;
sif::error << "Terminating program." << std::endl;
sif::error << "ObjectManager::insert: Object ID " << std::hex <<
static_cast<uint32_t>(id) << std::dec << " is already in use!" << std::endl;
sif::error << "Terminating program" << std::endl;
#else
sif::printError("ObjectManager::insert: Object ID 0x%08x is already in use!\n",
static_cast<unsigned int>(id));
sif::printError("Terminating program");
#endif
//This is very severe and difficult to handle in other places.
std::exit(INSERTION_FAILED);
@ -66,12 +81,8 @@ SystemObjectIF* ObjectManager::getSystemObject( object_id_t id ) {
}
}
ObjectManager::ObjectManager() : produceObjects(nullptr) {
}
void ObjectManager::initialize() {
if(produceObjects == nullptr) {
if(objectFactoryFunction == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ObjectManager::initialize: Passed produceObjects "
"functions is nullptr!" << std::endl;
@ -80,7 +91,7 @@ void ObjectManager::initialize() {
#endif
return;
}
this->produceObjects();
objectFactoryFunction(factoryArgs);
ReturnValue_t result = RETURN_FAILED;
uint32_t errorCount = 0;
for (auto const& it : objectList) {

View File

@ -5,6 +5,7 @@
#include "SystemObjectIF.h"
#include <map>
/**
* @brief This class implements a global object manager.
* @details This manager handles a list of available objects with system-wide
@ -19,44 +20,65 @@
* @author Bastian Baetz
*/
class ObjectManager : public ObjectManagerIF {
private:
//comparison?
/**
* @brief This is the map of all initialized objects in the manager.
* @details Objects in the List must inherit the SystemObjectIF.
*/
std::map<object_id_t, SystemObjectIF*> objectList;
protected:
SystemObjectIF* getSystemObject( object_id_t id );
/**
* @brief This attribute is initialized with the factory function
* that creates new objects.
* @details The function is called if an object was requested with
* getSystemObject, but not found in objectList.
* @param The id of the object to be created.
* @return Returns a pointer to the newly created object or NULL.
*/
void (*produceObjects)();
public:
/**
* @brief Apart from setting the producer function, nothing special
* happens in the constructor.
* @param setProducer A pointer to a factory function.
*/
ObjectManager( void (*produce)() );
ObjectManager();
/**
* @brief In the class's destructor, all objects in the list are deleted.
*/
// SHOULDDO: If, for some reason, deleting an ObjectManager instance is
// required, check if this works.
virtual ~ObjectManager( void );
ReturnValue_t insert( object_id_t id, SystemObjectIF* object );
ReturnValue_t remove( object_id_t id );
void initialize();
void printList();
using produce_function_t = void (*) (void* args);
/**
* Returns the single instance of TaskFactory.
* The implementation of #instance is found in its subclasses.
* Thus, we choose link-time variability of the instance.
*/
static ObjectManager* instance();
void setObjectFactoryFunction(produce_function_t prodFunc, void* args);
template <typename T> T* get( object_id_t id );
/**
* @brief In the class's destructor, all objects in the list are deleted.
*/
virtual ~ObjectManager();
ReturnValue_t insert(object_id_t id, SystemObjectIF* object) override;
ReturnValue_t remove(object_id_t id) override;
void initialize() override;
void printList() override;
protected:
SystemObjectIF* getSystemObject(object_id_t id) override;
/**
* @brief This attribute is initialized with the factory function
* that creates new objects.
* @details The function is called if an object was requested with
* getSystemObject, but not found in objectList.
* @param The id of the object to be created.
* @return Returns a pointer to the newly created object or NULL.
*/
produce_function_t objectFactoryFunction = nullptr;
void* factoryArgs = nullptr;
private:
ObjectManager();
/**
* @brief This is the map of all initialized objects in the manager.
* @details Objects in the List must inherit the SystemObjectIF.
*/
std::map<object_id_t, SystemObjectIF*> objectList;
static ObjectManager* objManagerInstance;
};
/**
* @brief This is the forward declaration of the global objectManager instance.
*/
// SHOULDDO: maybe put this in the glob namespace to explicitely mark it global?
//extern ObjectManagerIF *objectManager;
/*Documentation can be found in the class method declaration above.*/
template <typename T>
T* ObjectManager::get( object_id_t id ) {
SystemObjectIF* temp = this->getSystemObject(id);
return dynamic_cast<T*>(temp);
}
#endif /* FSFW_OBJECTMANAGER_OBJECTMANAGER_H_ */

View File

@ -8,11 +8,11 @@
/**
* @brief This class provides an interface to the global object manager.
* @details This manager handles a list of available objects with system-wide
* relevance, such as device handlers, and TM/TC services. They can be
* inserted, removed and retrieved from the list. On getting the
* object, the call checks if the object implements the requested
* interface.
* @details
* This manager handles a list of available objects with system-wide relevance, such as device
* handlers, and TM/TC services. They can be inserted, removed and retrieved from the list.
* On getting the object, the call checks if the object implements the requested interface.
* This interface does not specify a getter function because templates can't be used in interfaces.
* @author Bastian Baetz
* @ingroup system_objects
*/
@ -21,7 +21,8 @@ public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::OBJECT_MANAGER_IF;
static constexpr ReturnValue_t INSERTION_FAILED = MAKE_RETURN_CODE( 1 );
static constexpr ReturnValue_t NOT_FOUND = MAKE_RETURN_CODE( 2 );
static constexpr ReturnValue_t CHILD_INIT_FAILED = MAKE_RETURN_CODE( 3 ); //!< Can be used if the initialization of a SystemObject failed.
//!< Can be used if the initialization of a SystemObject failed.
static constexpr ReturnValue_t CHILD_INIT_FAILED = MAKE_RETURN_CODE( 3 );
static constexpr ReturnValue_t INTERNAL_ERR_REPORTER_UNINIT = MAKE_RETURN_CODE( 4 );
protected:
@ -49,22 +50,11 @@ public:
* @li RETURN_OK in case the object was successfully inserted
*/
virtual ReturnValue_t insert( object_id_t id, SystemObjectIF* object ) = 0;
/**
* @brief With the get call, interfaces of an object can be retrieved in
* a type-safe manner.
* @details With the template-based call, the object list is searched with the
* getSystemObject method and afterwards it is checked, if the object
* implements the requested interface (with a dynamic_cast).
* @param id The object id of the requested object.
* @return The method returns a pointer to an object implementing the
* requested interface, or NULL.
*/
template <typename T> T* get( object_id_t id );
/**
* @brief With this call, an object is removed from the list.
* @param id The object id of the object to be removed.
* @return \li NOT_FOUND in case the object was not found
* \li RETURN_OK in case the object was successfully removed
* @return @li NOT_FOUND in case the object was not found
* @li RETURN_OK in case the object was successfully removed
*/
virtual ReturnValue_t remove( object_id_t id ) = 0;
virtual void initialize() = 0;
@ -75,24 +65,4 @@ public:
virtual void printList() = 0;
};
/**
* @brief This is the forward declaration of the global objectManager instance.
*/
// SHOULDDO: maybe put this in the glob namespace to explicitely mark it global?
extern ObjectManagerIF *objectManager;
/*Documentation can be found in the class method declaration above.*/
template <typename T>
T* ObjectManagerIF::get( object_id_t id ) {
if(objectManager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ObjectManagerIF: Global object manager has not "
"been initialized yet!" << std::endl;
#endif
}
SystemObjectIF* temp = this->getSystemObject(id);
return dynamic_cast<T*>(temp);
}
#endif /* OBJECTMANAGERIF_H_ */

View File

@ -4,18 +4,14 @@
SystemObject::SystemObject(object_id_t setObjectId, bool doRegister) :
objectId(setObjectId), registered(doRegister) {
if (registered) {
if(objectManager != nullptr) {
objectManager->insert(objectId, this);
}
}
if (registered) {
ObjectManager::instance()->insert(objectId, this);
}
}
SystemObject::~SystemObject() {
if (registered) {
if(objectManager != nullptr) {
objectManager->remove(objectId);
}
ObjectManager::instance()->remove(objectId);
}
}