fsfw/src/fsfw/objectmanager/ObjectManager.cpp

160 lines
5.0 KiB
C++
Raw Normal View History

2021-07-13 20:22:54 +02:00
#include "fsfw/objectmanager/ObjectManager.h"
2022-02-02 10:29:30 +01:00
2021-07-13 20:22:54 +02:00
#include "fsfw/serviceinterface/ServiceInterface.h"
2021-01-03 14:08:40 +01:00
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2020-06-10 20:51:59 +02:00
#include <iomanip>
2021-01-03 14:08:40 +01:00
#endif
#include <cstdlib>
2021-06-05 19:52:38 +02:00
ObjectManager* ObjectManager::objManagerInstance = nullptr;
ObjectManager* ObjectManager::instance() {
2022-02-02 10:29:30 +01:00
if (objManagerInstance == nullptr) {
objManagerInstance = new ObjectManager();
}
return objManagerInstance;
2021-06-05 19:52:38 +02:00
}
2022-02-02 10:29:30 +01:00
void ObjectManager::setObjectFactoryFunction(produce_function_t objFactoryFunc, void* factoryArgs) {
this->objectFactoryFunction = objFactoryFunc;
this->factoryArgs = factoryArgs;
}
2022-07-25 22:36:53 +02:00
ObjectManager::ObjectManager() = default;
2021-06-05 19:52:38 +02:00
2023-01-12 15:40:52 +01:00
void ObjectManager::clear() {
if (objManagerInstance != nullptr) {
delete objManagerInstance;
objManagerInstance = nullptr;
}
}
ObjectManager::~ObjectManager() {
2023-01-12 15:40:52 +01:00
teardown = true;
for (auto iter = objectList.begin(); iter != objectList.end(); iter = objectList.erase(iter)) {
delete iter->second;
2022-02-02 10:29:30 +01:00
}
}
2022-02-02 10:29:30 +01:00
ReturnValue_t ObjectManager::insert(object_id_t id, SystemObjectIF* object) {
auto returnPair = objectList.emplace(id, object);
if (returnPair.second) {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2022-02-02 10:29:30 +01:00
// sif::debug << "ObjectManager::insert: Object " << std::hex
// << (int)id << std::dec << " inserted." << std::endl;
#endif
2022-08-16 01:08:26 +02:00
return returnvalue::OK;
2022-02-02 10:29:30 +01:00
} else {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2022-02-02 10:29:30 +01:00
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;
2021-06-05 19:52:38 +02:00
#else
2022-02-02 10:29:30 +01:00
sif::printError("ObjectManager::insert: Object ID 0x%08x is already in use!\n",
static_cast<unsigned int>(id));
sif::printError("Terminating program");
#endif
2022-02-02 10:29:30 +01:00
// This is very severe and difficult to handle in other places.
std::exit(INSERTION_FAILED);
}
}
2022-02-02 10:29:30 +01:00
ReturnValue_t ObjectManager::remove(object_id_t id) {
2023-01-12 15:40:52 +01:00
// this function is called during destruction of System Objects
// disabeld for teardown to avoid iterator invalidation and
// double free
if (teardown) {
return returnvalue::OK;
}
2022-07-25 22:36:53 +02:00
if (this->getSystemObject(id) != nullptr) {
2022-02-02 10:29:30 +01:00
this->objectList.erase(id);
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2022-02-02 10:29:30 +01:00
// sif::debug << "ObjectManager::removeObject: Object " << std::hex
// << (int)id << std::dec << " removed." << std::endl;
#endif
2022-08-16 01:08:26 +02:00
return returnvalue::OK;
2022-02-02 10:29:30 +01:00
} else {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2022-02-02 10:29:30 +01:00
sif::error << "ObjectManager::removeObject: Requested object " << std::hex << (int)id
<< std::dec << " not found." << std::endl;
#endif
2022-02-02 10:29:30 +01:00
return NOT_FOUND;
}
}
2022-02-02 10:29:30 +01:00
SystemObjectIF* ObjectManager::getSystemObject(object_id_t id) {
auto listIter = this->objectList.find(id);
if (listIter == this->objectList.end()) {
return nullptr;
} else {
return listIter->second;
}
}
void ObjectManager::initialize() {
2022-02-02 10:29:30 +01:00
if (objectFactoryFunction == nullptr) {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2022-02-02 10:29:30 +01:00
sif::error << "ObjectManager::initialize: Passed produceObjects "
"functions is nullptr!"
<< std::endl;
2021-01-27 20:04:16 +01:00
#else
2022-02-02 10:29:30 +01:00
sif::printError("ObjectManager::initialize: Passed produceObjects functions is nullptr!\n");
#endif
2022-02-02 10:29:30 +01:00
return;
}
objectFactoryFunction(factoryArgs);
2022-08-16 01:08:26 +02:00
ReturnValue_t result = returnvalue::FAILED;
2022-02-02 10:29:30 +01:00
uint32_t errorCount = 0;
for (auto const& it : objectList) {
result = it.second->initialize();
2022-08-16 01:08:26 +02:00
if (result != returnvalue::OK) {
2022-02-22 10:17:56 +01:00
#if FSFW_VERBOSE_LEVEL >= 1
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2022-02-02 10:29:30 +01:00
sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8)
2022-02-22 10:17:56 +01:00
<< std::setfill('0') << it.first << " failed to initialize with code 0x" << result
<< std::dec << std::setfill(' ') << std::endl;
#else
sif::printError(
2023-07-25 16:16:35 +02:00
"ObjectManager::initialize: Object 0x%08x failed to initialize with code 0x%04x\n",
it.first, result);
2022-02-22 10:17:56 +01:00
#endif
#endif
2022-02-02 10:29:30 +01:00
errorCount++;
}
}
if (errorCount > 0) {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2022-02-02 10:29:30 +01:00
sif::error << "ObjectManager::ObjectManager: Counted " << errorCount
<< " failed initializations." << std::endl;
#endif
2022-02-02 10:29:30 +01:00
}
// Init was successful. Now check successful interconnections.
errorCount = 0;
for (auto const& it : objectList) {
result = it.second->checkObjectConnections();
2022-08-16 01:08:26 +02:00
if (result != returnvalue::OK) {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2022-02-02 10:29:30 +01:00
sif::error << "ObjectManager::ObjectManager: Object 0x" << std::hex << (int)it.first
<< " connection check failed with code 0x" << result << std::dec << std::endl;
#endif
2022-02-02 10:29:30 +01:00
errorCount++;
}
}
if (errorCount > 0) {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2022-02-02 10:29:30 +01:00
sif::error << "ObjectManager::ObjectManager: Counted " << errorCount
<< " failed connection checks." << std::endl;
#endif
2022-02-02 10:29:30 +01:00
}
}
void ObjectManager::printList() {
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2022-02-02 10:29:30 +01:00
sif::debug << "ObjectManager: Object List contains:" << std::endl;
for (auto const& it : objectList) {
sif::debug << std::hex << it.first << " | " << it.second << std::endl;
}
#endif
}