Merge branch 'development' into mueller/rtems-only
This commit is contained in:
commit
46e4816faf
@ -3,151 +3,119 @@
|
|||||||
|
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
ActionHelper::ActionHelper(HasActionsIF* setOwner,
|
ActionHelper::ActionHelper(HasActionsIF* setOwner,
|
||||||
MessageQueueIF* useThisQueue) :
|
MessageQueueIF* useThisQueue) :
|
||||||
owner(setOwner), queueToUse(useThisQueue) {
|
owner(setOwner), queueToUse(useThisQueue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionHelper::~ActionHelper() {
|
ActionHelper::~ActionHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
|
ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
|
||||||
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
|
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
|
||||||
ActionId_t currentAction = ActionMessage::getActionId(command);
|
ActionId_t currentAction = ActionMessage::getActionId(command);
|
||||||
prepareExecution(command->getSender(), currentAction,
|
prepareExecution(command->getSender(), currentAction,
|
||||||
ActionMessage::getStoreId(command));
|
ActionMessage::getStoreId(command));
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
return CommandMessage::UNKNOWN_COMMAND;
|
return CommandMessage::UNKNOWN_COMMAND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
|
ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
|
||||||
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
if (ipcStore == nullptr) {
|
if (ipcStore == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
if(queueToUse_ != nullptr) {
|
if(queueToUse_ != nullptr) {
|
||||||
setQueueToUse(queueToUse_);
|
setQueueToUse(queueToUse_);
|
||||||
}
|
}
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo,
|
void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo,
|
||||||
ActionId_t commandId, ReturnValue_t result) {
|
ActionId_t commandId, ReturnValue_t result) {
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
|
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
|
||||||
queueToUse->sendMessage(reportTo, &reply);
|
queueToUse->sendMessage(reportTo, &reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId,
|
void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId,
|
||||||
ReturnValue_t result) {
|
ReturnValue_t result) {
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
ActionMessage::setCompletionReply(&reply, commandId, result);
|
ActionMessage::setCompletionReply(&reply, commandId, result);
|
||||||
queueToUse->sendMessage(reportTo, &reply);
|
queueToUse->sendMessage(reportTo, &reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
|
void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
|
||||||
queueToUse = queue;
|
queueToUse = queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy,
|
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy,
|
||||||
ActionId_t actionId, store_address_t dataAddress) {
|
ActionId_t actionId, store_address_t dataAddress) {
|
||||||
const uint8_t* dataPtr = NULL;
|
const uint8_t* dataPtr = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||||
queueToUse->sendMessage(commandedBy, &reply);
|
queueToUse->sendMessage(commandedBy, &reply);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||||
ipcStore->deleteData(dataAddress);
|
ipcStore->deleteData(dataAddress);
|
||||||
if(result == HasActionsIF::EXECUTION_FINISHED) {
|
if(result == HasActionsIF::EXECUTION_FINISHED) {
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
ActionMessage::setCompletionReply(&reply, actionId, result);
|
ActionMessage::setCompletionReply(&reply, actionId, result);
|
||||||
queueToUse->sendMessage(commandedBy, &reply);
|
queueToUse->sendMessage(commandedBy, &reply);
|
||||||
}
|
}
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||||
queueToUse->sendMessage(commandedBy, &reply);
|
queueToUse->sendMessage(commandedBy, &reply);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
||||||
ActionId_t replyId, SerializeIF* data, bool hideSender) {
|
ActionId_t replyId, SerializeIF* data, bool hideSender) {
|
||||||
CommandMessage reply;
|
|
||||||
store_address_t storeAddress;
|
|
||||||
uint8_t *dataPtr;
|
|
||||||
size_t maxSize = data->getSerializedSize();
|
|
||||||
if (maxSize == 0) {
|
|
||||||
//No error, there's simply nothing to report.
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
size_t size = 0;
|
|
||||||
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize,
|
|
||||||
&dataPtr);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = data->serialize(&dataPtr, &size, maxSize,
|
|
||||||
SerializeIF::Endianness::BIG);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
ipcStore->deleteData(storeAddress);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// We don't need to report the objectId, as we receive REQUESTED data
|
|
||||||
// before the completion success message.
|
|
||||||
// True aperiodic replies need to be reported with
|
|
||||||
// another dedicated message.
|
|
||||||
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
|
||||||
|
|
||||||
// If the sender needs to be hidden, for example to handle packet
|
|
||||||
// as unrequested reply, this will be done here.
|
|
||||||
if (hideSender) {
|
|
||||||
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = queueToUse->sendMessage(reportTo, &reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK){
|
|
||||||
ipcStore->deleteData(storeAddress);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionHelper::resetHelper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
|
||||||
ActionId_t replyId, const uint8_t *data, size_t dataSize,
|
|
||||||
bool hideSender) {
|
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
store_address_t storeAddress;
|
store_address_t storeAddress;
|
||||||
ReturnValue_t result = ipcStore->addData(&storeAddress, data, dataSize);
|
uint8_t *dataPtr;
|
||||||
|
size_t maxSize = data->getSerializedSize();
|
||||||
|
if (maxSize == 0) {
|
||||||
|
/* No error, there's simply nothing to report. */
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
size_t size = 0;
|
||||||
|
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize,
|
||||||
|
&dataPtr);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "ActionHelper::reportData: Getting free element from IPC store failed!" <<
|
||||||
|
std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("ActionHelper::reportData: Getting free element from IPC "
|
||||||
|
"store failed!\n");
|
||||||
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
result = data->serialize(&dataPtr, &size, maxSize,
|
||||||
|
SerializeIF::Endianness::BIG);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
ipcStore->deleteData(storeAddress);
|
ipcStore->deleteData(storeAddress);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't need to report the objectId, as we receive REQUESTED data
|
/* We don't need to report the objectId, as we receive REQUESTED data before the completion
|
||||||
// before the completion success message.
|
success message. True aperiodic replies need to be reported with another dedicated message. */
|
||||||
// True aperiodic replies need to be reported with
|
|
||||||
// another dedicated message.
|
|
||||||
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
||||||
|
|
||||||
// If the sender needs to be hidden, for example to handle packet
|
/* If the sender needs to be hidden, for example to handle packet
|
||||||
// as unrequested reply, this will be done here.
|
as unrequested reply, this will be done here. */
|
||||||
if (hideSender) {
|
if (hideSender) {
|
||||||
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
|
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
|
||||||
}
|
}
|
||||||
@ -160,3 +128,45 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActionHelper::resetHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
||||||
|
ActionId_t replyId, const uint8_t *data, size_t dataSize,
|
||||||
|
bool hideSender) {
|
||||||
|
CommandMessage reply;
|
||||||
|
store_address_t storeAddress;
|
||||||
|
ReturnValue_t result = ipcStore->addData(&storeAddress, data, dataSize);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "ActionHelper::reportData: Adding data to IPC store failed!" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("ActionHelper::reportData: Adding data to IPC store failed!\n");
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
ipcStore->deleteData(storeAddress);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We don't need to report the objectId, as we receive REQUESTED data before the completion
|
||||||
|
success message. True aperiodic replies need to be reported with another dedicated message. */
|
||||||
|
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
||||||
|
|
||||||
|
/* If the sender needs to be hidden, for example to handle packet
|
||||||
|
as unrequested reply, this will be done here. */
|
||||||
|
if (hideSender) {
|
||||||
|
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = queueToUse->sendMessage(reportTo, &reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
ipcStore->deleteData(storeAddress);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -18,68 +18,68 @@ class HasActionsIF;
|
|||||||
|
|
||||||
class ActionHelper {
|
class ActionHelper {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor of the action helper
|
* Constructor of the action helper
|
||||||
* @param setOwner Pointer to the owner of the interface
|
* @param setOwner Pointer to the owner of the interface
|
||||||
* @param useThisQueue messageQueue to be used, can be set during
|
* @param useThisQueue messageQueue to be used, can be set during
|
||||||
* initialize function as well.
|
* initialize function as well.
|
||||||
*/
|
*/
|
||||||
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||||
|
|
||||||
virtual ~ActionHelper();
|
virtual ~ActionHelper();
|
||||||
/**
|
/**
|
||||||
* Function to be called from the owner with a new command message
|
* Function to be called from the owner with a new command message
|
||||||
*
|
*
|
||||||
* If the message is a valid action message the helper will use the
|
* If the message is a valid action message the helper will use the
|
||||||
* executeAction function from HasActionsIF.
|
* executeAction function from HasActionsIF.
|
||||||
* If the message is invalid or the callback fails a message reply will be
|
* If the message is invalid or the callback fails a message reply will be
|
||||||
* send to the sender of the message automatically.
|
* send to the sender of the message automatically.
|
||||||
*
|
*
|
||||||
* @param command Pointer to a command message received by the owner
|
* @param command Pointer to a command message received by the owner
|
||||||
* @return HasReturnvaluesIF::RETURN_OK if the message is a action message,
|
* @return HasReturnvaluesIF::RETURN_OK if the message is a action message,
|
||||||
* CommandMessage::UNKNOW_COMMAND if this message ID is unkown
|
* CommandMessage::UNKNOW_COMMAND if this message ID is unkown
|
||||||
*/
|
*/
|
||||||
ReturnValue_t handleActionMessage(CommandMessage* command);
|
ReturnValue_t handleActionMessage(CommandMessage* command);
|
||||||
/**
|
/**
|
||||||
* Helper initialize function. Must be called before use of any other
|
* Helper initialize function. Must be called before use of any other
|
||||||
* helper function
|
* helper function
|
||||||
* @param queueToUse_ Pointer to the messageQueue to be used, optional
|
* @param queueToUse_ Pointer to the messageQueue to be used, optional
|
||||||
* if queue was set in constructor
|
* if queue was set in constructor
|
||||||
* @return Returns RETURN_OK if successful
|
* @return Returns RETURN_OK if successful
|
||||||
*/
|
*/
|
||||||
ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr);
|
ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr);
|
||||||
/**
|
/**
|
||||||
* Function to be called from the owner to send a step message.
|
* Function to be called from the owner to send a step message.
|
||||||
* Success or failure will be determined by the result value.
|
* Success or failure will be determined by the result value.
|
||||||
*
|
*
|
||||||
* @param step Number of steps already done
|
* @param step Number of steps already done
|
||||||
* @param reportTo The messageQueueId to report the step message to
|
* @param reportTo The messageQueueId to report the step message to
|
||||||
* @param commandId ID of the executed command
|
* @param commandId ID of the executed command
|
||||||
* @param result Result of the execution
|
* @param result Result of the execution
|
||||||
*/
|
*/
|
||||||
void step(uint8_t step, MessageQueueId_t reportTo,
|
void step(uint8_t step, MessageQueueId_t reportTo,
|
||||||
ActionId_t commandId,
|
ActionId_t commandId,
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||||
/**
|
/**
|
||||||
* Function to be called by the owner to send a action completion message
|
* Function to be called by the owner to send a action completion message
|
||||||
*
|
*
|
||||||
* @param reportTo MessageQueueId_t to report the action completion message to
|
* @param reportTo MessageQueueId_t to report the action completion message to
|
||||||
* @param commandId ID of the executed command
|
* @param commandId ID of the executed command
|
||||||
* @param result Result of the execution
|
* @param result Result of the execution
|
||||||
*/
|
*/
|
||||||
void finish(MessageQueueId_t reportTo, ActionId_t commandId,
|
void finish(MessageQueueId_t reportTo, ActionId_t commandId,
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||||
/**
|
/**
|
||||||
* Function to be called by the owner if an action does report data.
|
* Function to be called by the owner if an action does report data.
|
||||||
* Takes a SerializeIF* pointer and serializes it into the IPC store.
|
* Takes a SerializeIF* pointer and serializes it into the IPC store.
|
||||||
* @param reportTo MessageQueueId_t to report the action completion
|
* @param reportTo MessageQueueId_t to report the action completion
|
||||||
* message to
|
* message to
|
||||||
* @param replyId ID of the executed command
|
* @param replyId ID of the executed command
|
||||||
* @param data Pointer to the data
|
* @param data Pointer to the data
|
||||||
* @return Returns RETURN_OK if successful, otherwise failure code
|
* @return Returns RETURN_OK if successful, otherwise failure code
|
||||||
*/
|
*/
|
||||||
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
|
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
|
||||||
SerializeIF* data, bool hideSender = false);
|
SerializeIF* data, bool hideSender = false);
|
||||||
/**
|
/**
|
||||||
* Function to be called by the owner if an action does report data.
|
* Function to be called by the owner if an action does report data.
|
||||||
* Takes the raw data and writes it into the IPC store.
|
* Takes the raw data and writes it into the IPC store.
|
||||||
@ -91,35 +91,36 @@ public:
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
|
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
|
||||||
const uint8_t* data, size_t dataSize, bool hideSender = false);
|
const uint8_t* data, size_t dataSize, bool hideSender = false);
|
||||||
/**
|
/**
|
||||||
* Function to setup the MessageQueueIF* of the helper. Can be used to
|
* Function to setup the MessageQueueIF* of the helper. Can be used to
|
||||||
* set the MessageQueueIF* if message queue is unavailable at construction
|
* set the MessageQueueIF* if message queue is unavailable at construction
|
||||||
* and initialize but must be setup before first call of other functions.
|
* and initialize but must be setup before first call of other functions.
|
||||||
* @param queue Queue to be used by the helper
|
* @param queue Queue to be used by the helper
|
||||||
*/
|
*/
|
||||||
void setQueueToUse(MessageQueueIF *queue);
|
void setQueueToUse(MessageQueueIF *queue);
|
||||||
protected:
|
protected:
|
||||||
//!< Increase of value of this per step
|
//! Increase of value of this per step
|
||||||
static const uint8_t STEP_OFFSET = 1;
|
static const uint8_t STEP_OFFSET = 1;
|
||||||
HasActionsIF* owner;//!< Pointer to the owner
|
//! Pointer to the owner
|
||||||
//! Queue to be used as response sender, has to be set in ctor or with
|
HasActionsIF* owner;
|
||||||
//! setQueueToUse
|
//! Queue to be used as response sender, has to be set in ctor or with
|
||||||
MessageQueueIF* queueToUse;
|
//! setQueueToUse
|
||||||
//! Pointer to an IPC Store, initialized during construction or
|
MessageQueueIF* queueToUse;
|
||||||
StorageManagerIF* ipcStore = nullptr;
|
//! Pointer to an IPC Store, initialized during construction or
|
||||||
|
StorageManagerIF* ipcStore = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal function called by handleActionMessage
|
* Internal function called by handleActionMessage
|
||||||
* @param commandedBy MessageQueueID of Commander
|
* @param commandedBy MessageQueueID of Commander
|
||||||
* @param actionId ID of action to be done
|
* @param actionId ID of action to be done
|
||||||
* @param dataAddress Address of additional data in IPC Store
|
* @param dataAddress Address of additional data in IPC Store
|
||||||
*/
|
*/
|
||||||
virtual void prepareExecution(MessageQueueId_t commandedBy,
|
virtual void prepareExecution(MessageQueueId_t commandedBy,
|
||||||
ActionId_t actionId, store_address_t dataAddress);
|
ActionId_t actionId, store_address_t dataAddress);
|
||||||
/**
|
/**
|
||||||
* @brief Default implementation is empty.
|
* @brief Default implementation is empty.
|
||||||
*/
|
*/
|
||||||
virtual void resetHelper();
|
virtual void resetHelper();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_ACTION_ACTIONHELPER_H_ */
|
#endif /* FSFW_ACTION_ACTIONHELPER_H_ */
|
||||||
|
@ -11,71 +11,71 @@ ActionMessage::~ActionMessage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ActionMessage::setCommand(CommandMessage* message, ActionId_t fid,
|
void ActionMessage::setCommand(CommandMessage* message, ActionId_t fid,
|
||||||
store_address_t parameters) {
|
store_address_t parameters) {
|
||||||
message->setCommand(EXECUTE_ACTION);
|
message->setCommand(EXECUTE_ACTION);
|
||||||
message->setParameter(fid);
|
message->setParameter(fid);
|
||||||
message->setParameter2(parameters.raw);
|
message->setParameter2(parameters.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionId_t ActionMessage::getActionId(const CommandMessage* message) {
|
ActionId_t ActionMessage::getActionId(const CommandMessage* message) {
|
||||||
return ActionId_t(message->getParameter());
|
return ActionId_t(message->getParameter());
|
||||||
}
|
}
|
||||||
|
|
||||||
store_address_t ActionMessage::getStoreId(const CommandMessage* message) {
|
store_address_t ActionMessage::getStoreId(const CommandMessage* message) {
|
||||||
store_address_t temp;
|
store_address_t temp;
|
||||||
temp.raw = message->getParameter2();
|
temp.raw = message->getParameter2();
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionMessage::setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step,
|
void ActionMessage::setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step,
|
||||||
ReturnValue_t result) {
|
ReturnValue_t result) {
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
message->setCommand(STEP_SUCCESS);
|
message->setCommand(STEP_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
message->setCommand(STEP_FAILED);
|
message->setCommand(STEP_FAILED);
|
||||||
}
|
}
|
||||||
message->setParameter(fid);
|
message->setParameter(fid);
|
||||||
message->setParameter2((step << 16) + result);
|
message->setParameter2((step << 16) + result);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ActionMessage::getStep(const CommandMessage* message) {
|
uint8_t ActionMessage::getStep(const CommandMessage* message) {
|
||||||
return uint8_t((message->getParameter2() >> 16) & 0xFF);
|
return uint8_t((message->getParameter2() >> 16) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ActionMessage::getReturnCode(const CommandMessage* message) {
|
ReturnValue_t ActionMessage::getReturnCode(const CommandMessage* message) {
|
||||||
return message->getParameter2() & 0xFFFF;
|
return message->getParameter2() & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionMessage::setDataReply(CommandMessage* message, ActionId_t actionId,
|
void ActionMessage::setDataReply(CommandMessage* message, ActionId_t actionId,
|
||||||
store_address_t data) {
|
store_address_t data) {
|
||||||
message->setCommand(DATA_REPLY);
|
message->setCommand(DATA_REPLY);
|
||||||
message->setParameter(actionId);
|
message->setParameter(actionId);
|
||||||
message->setParameter2(data.raw);
|
message->setParameter2(data.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionMessage::setCompletionReply(CommandMessage* message,
|
void ActionMessage::setCompletionReply(CommandMessage* message,
|
||||||
ActionId_t fid, ReturnValue_t result) {
|
ActionId_t fid, ReturnValue_t result) {
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK or result == HasActionsIF::EXECUTION_FINISHED) {
|
if (result == HasReturnvaluesIF::RETURN_OK or result == HasActionsIF::EXECUTION_FINISHED) {
|
||||||
message->setCommand(COMPLETION_SUCCESS);
|
message->setCommand(COMPLETION_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
message->setCommand(COMPLETION_FAILED);
|
message->setCommand(COMPLETION_FAILED);
|
||||||
}
|
}
|
||||||
message->setParameter(fid);
|
message->setParameter(fid);
|
||||||
message->setParameter2(result);
|
message->setParameter2(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionMessage::clear(CommandMessage* message) {
|
void ActionMessage::clear(CommandMessage* message) {
|
||||||
switch(message->getCommand()) {
|
switch(message->getCommand()) {
|
||||||
case EXECUTE_ACTION:
|
case EXECUTE_ACTION:
|
||||||
case DATA_REPLY: {
|
case DATA_REPLY: {
|
||||||
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
|
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
|
||||||
objects::IPC_STORE);
|
objects::IPC_STORE);
|
||||||
if (ipcStore != NULL) {
|
if (ipcStore != NULL) {
|
||||||
ipcStore->deleteData(getStoreId(message));
|
ipcStore->deleteData(getStoreId(message));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,29 +15,29 @@ using ActionId_t = uint32_t;
|
|||||||
*/
|
*/
|
||||||
class ActionMessage {
|
class ActionMessage {
|
||||||
private:
|
private:
|
||||||
ActionMessage();
|
ActionMessage();
|
||||||
public:
|
public:
|
||||||
static const uint8_t MESSAGE_ID = messagetypes::ACTION;
|
static const uint8_t MESSAGE_ID = messagetypes::ACTION;
|
||||||
static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1);
|
static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1);
|
||||||
static const Command_t STEP_SUCCESS = MAKE_COMMAND_ID(2);
|
static const Command_t STEP_SUCCESS = MAKE_COMMAND_ID(2);
|
||||||
static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3);
|
static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3);
|
||||||
static const Command_t DATA_REPLY = MAKE_COMMAND_ID(4);
|
static const Command_t DATA_REPLY = MAKE_COMMAND_ID(4);
|
||||||
static const Command_t COMPLETION_SUCCESS = MAKE_COMMAND_ID(5);
|
static const Command_t COMPLETION_SUCCESS = MAKE_COMMAND_ID(5);
|
||||||
static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6);
|
static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6);
|
||||||
virtual ~ActionMessage();
|
virtual ~ActionMessage();
|
||||||
static void setCommand(CommandMessage* message, ActionId_t fid,
|
static void setCommand(CommandMessage* message, ActionId_t fid,
|
||||||
store_address_t parameters);
|
store_address_t parameters);
|
||||||
static ActionId_t getActionId(const CommandMessage* message );
|
static ActionId_t getActionId(const CommandMessage* message );
|
||||||
static store_address_t getStoreId(const CommandMessage* message );
|
static store_address_t getStoreId(const CommandMessage* message );
|
||||||
static void setStepReply(CommandMessage* message, ActionId_t fid,
|
static void setStepReply(CommandMessage* message, ActionId_t fid,
|
||||||
uint8_t step, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
uint8_t step, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||||
static uint8_t getStep(const CommandMessage* message );
|
static uint8_t getStep(const CommandMessage* message );
|
||||||
static ReturnValue_t getReturnCode(const CommandMessage* message );
|
static ReturnValue_t getReturnCode(const CommandMessage* message );
|
||||||
static void setDataReply(CommandMessage* message, ActionId_t actionId,
|
static void setDataReply(CommandMessage* message, ActionId_t actionId,
|
||||||
store_address_t data);
|
store_address_t data);
|
||||||
static void setCompletionReply(CommandMessage* message, ActionId_t fid,
|
static void setCompletionReply(CommandMessage* message, ActionId_t fid,
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||||
static void clear(CommandMessage* message);
|
static void clear(CommandMessage* message);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_ACTION_ACTIONMESSAGE_H_ */
|
#endif /* FSFW_ACTION_ACTIONMESSAGE_H_ */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
target_sources(${LIB_FSFW_NAME}
|
target_sources(${LIB_FSFW_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
ActionHelper.cpp
|
ActionHelper.cpp
|
||||||
ActionMessage.cpp
|
ActionMessage.cpp
|
||||||
CommandActionHelper.cpp
|
CommandActionHelper.cpp
|
||||||
SimpleActionHelper.cpp
|
SimpleActionHelper.cpp
|
||||||
)
|
)
|
@ -5,123 +5,123 @@
|
|||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
|
|
||||||
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner) :
|
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner) :
|
||||||
owner(setOwner), queueToUse(NULL), ipcStore(
|
owner(setOwner), queueToUse(NULL), ipcStore(
|
||||||
NULL), commandCount(0), lastTarget(0) {
|
NULL), commandCount(0), lastTarget(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandActionHelper::~CommandActionHelper() {
|
CommandActionHelper::~CommandActionHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
|
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
|
||||||
ActionId_t actionId, SerializeIF *data) {
|
ActionId_t actionId, SerializeIF *data) {
|
||||||
HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
|
HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
|
||||||
if (receiver == NULL) {
|
if (receiver == NULL) {
|
||||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||||
}
|
}
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
uint8_t *storePointer;
|
uint8_t *storePointer;
|
||||||
size_t maxSize = data->getSerializedSize();
|
size_t maxSize = data->getSerializedSize();
|
||||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize,
|
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize,
|
||||||
&storePointer);
|
&storePointer);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
result = data->serialize(&storePointer, &size, maxSize,
|
result = data->serialize(&storePointer, &size, maxSize,
|
||||||
SerializeIF::Endianness::BIG);
|
SerializeIF::Endianness::BIG);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
|
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
|
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
|
||||||
ActionId_t actionId, const uint8_t *data, uint32_t size) {
|
ActionId_t actionId, const uint8_t *data, uint32_t size) {
|
||||||
// if (commandCount != 0) {
|
// if (commandCount != 0) {
|
||||||
// return CommandsFunctionsIF::ALREADY_COMMANDING;
|
// return CommandsFunctionsIF::ALREADY_COMMANDING;
|
||||||
// }
|
// }
|
||||||
HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
|
HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
|
||||||
if (receiver == NULL) {
|
if (receiver == NULL) {
|
||||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||||
}
|
}
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
ReturnValue_t result = ipcStore->addData(&storeId, data, size);
|
ReturnValue_t result = ipcStore->addData(&storeId, data, size);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
|
return sendCommand(receiver->getCommandQueue(), actionId, storeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId,
|
ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId,
|
||||||
ActionId_t actionId, store_address_t storeId) {
|
ActionId_t actionId, store_address_t storeId) {
|
||||||
CommandMessage command;
|
CommandMessage command;
|
||||||
ActionMessage::setCommand(&command, actionId, storeId);
|
ActionMessage::setCommand(&command, actionId, storeId);
|
||||||
ReturnValue_t result = queueToUse->sendMessage(queueId, &command);
|
ReturnValue_t result = queueToUse->sendMessage(queueId, &command);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
ipcStore->deleteData(storeId);
|
ipcStore->deleteData(storeId);
|
||||||
}
|
}
|
||||||
lastTarget = queueId;
|
lastTarget = queueId;
|
||||||
commandCount++;
|
commandCount++;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CommandActionHelper::initialize() {
|
ReturnValue_t CommandActionHelper::initialize() {
|
||||||
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
if (ipcStore == NULL) {
|
if (ipcStore == NULL) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
queueToUse = owner->getCommandQueuePtr();
|
queueToUse = owner->getCommandQueuePtr();
|
||||||
if (queueToUse == NULL) {
|
if (queueToUse == NULL) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) {
|
ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) {
|
||||||
if (reply->getSender() != lastTarget) {
|
if (reply->getSender() != lastTarget) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
switch (reply->getCommand()) {
|
switch (reply->getCommand()) {
|
||||||
case ActionMessage::COMPLETION_SUCCESS:
|
case ActionMessage::COMPLETION_SUCCESS:
|
||||||
commandCount--;
|
commandCount--;
|
||||||
owner->completionSuccessfulReceived(ActionMessage::getActionId(reply));
|
owner->completionSuccessfulReceived(ActionMessage::getActionId(reply));
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
case ActionMessage::COMPLETION_FAILED:
|
case ActionMessage::COMPLETION_FAILED:
|
||||||
commandCount--;
|
commandCount--;
|
||||||
owner->completionFailedReceived(ActionMessage::getActionId(reply),
|
owner->completionFailedReceived(ActionMessage::getActionId(reply),
|
||||||
ActionMessage::getReturnCode(reply));
|
ActionMessage::getReturnCode(reply));
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
case ActionMessage::STEP_SUCCESS:
|
case ActionMessage::STEP_SUCCESS:
|
||||||
owner->stepSuccessfulReceived(ActionMessage::getActionId(reply),
|
owner->stepSuccessfulReceived(ActionMessage::getActionId(reply),
|
||||||
ActionMessage::getStep(reply));
|
ActionMessage::getStep(reply));
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
case ActionMessage::STEP_FAILED:
|
case ActionMessage::STEP_FAILED:
|
||||||
commandCount--;
|
commandCount--;
|
||||||
owner->stepFailedReceived(ActionMessage::getActionId(reply),
|
owner->stepFailedReceived(ActionMessage::getActionId(reply),
|
||||||
ActionMessage::getStep(reply),
|
ActionMessage::getStep(reply),
|
||||||
ActionMessage::getReturnCode(reply));
|
ActionMessage::getReturnCode(reply));
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
case ActionMessage::DATA_REPLY:
|
case ActionMessage::DATA_REPLY:
|
||||||
extractDataForOwner(ActionMessage::getActionId(reply),
|
extractDataForOwner(ActionMessage::getActionId(reply),
|
||||||
ActionMessage::getStoreId(reply));
|
ActionMessage::getStoreId(reply));
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
default:
|
default:
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t CommandActionHelper::getCommandCount() const {
|
uint8_t CommandActionHelper::getCommandCount() const {
|
||||||
return commandCount;
|
return commandCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
|
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
|
||||||
const uint8_t * data = NULL;
|
const uint8_t * data = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
owner->dataReceived(actionId, data, size);
|
owner->dataReceived(actionId, data, size);
|
||||||
ipcStore->deleteData(storeId);
|
ipcStore->deleteData(storeId);
|
||||||
}
|
}
|
||||||
|
@ -11,26 +11,26 @@
|
|||||||
class CommandsActionsIF;
|
class CommandsActionsIF;
|
||||||
|
|
||||||
class CommandActionHelper {
|
class CommandActionHelper {
|
||||||
friend class CommandsActionsIF;
|
friend class CommandsActionsIF;
|
||||||
public:
|
public:
|
||||||
CommandActionHelper(CommandsActionsIF* owner);
|
CommandActionHelper(CommandsActionsIF* owner);
|
||||||
virtual ~CommandActionHelper();
|
virtual ~CommandActionHelper();
|
||||||
ReturnValue_t commandAction(object_id_t commandTo,
|
ReturnValue_t commandAction(object_id_t commandTo,
|
||||||
ActionId_t actionId, const uint8_t* data, uint32_t size);
|
ActionId_t actionId, const uint8_t* data, uint32_t size);
|
||||||
ReturnValue_t commandAction(object_id_t commandTo,
|
ReturnValue_t commandAction(object_id_t commandTo,
|
||||||
ActionId_t actionId, SerializeIF* data);
|
ActionId_t actionId, SerializeIF* data);
|
||||||
ReturnValue_t initialize();
|
ReturnValue_t initialize();
|
||||||
ReturnValue_t handleReply(CommandMessage* reply);
|
ReturnValue_t handleReply(CommandMessage* reply);
|
||||||
uint8_t getCommandCount() const;
|
uint8_t getCommandCount() const;
|
||||||
private:
|
private:
|
||||||
CommandsActionsIF* owner;
|
CommandsActionsIF* owner;
|
||||||
MessageQueueIF* queueToUse;
|
MessageQueueIF* queueToUse;
|
||||||
StorageManagerIF* ipcStore;
|
StorageManagerIF* ipcStore;
|
||||||
uint8_t commandCount;
|
uint8_t commandCount;
|
||||||
MessageQueueId_t lastTarget;
|
MessageQueueId_t lastTarget;
|
||||||
void extractDataForOwner(ActionId_t actionId, store_address_t storeId);
|
void extractDataForOwner(ActionId_t actionId, store_address_t storeId);
|
||||||
ReturnValue_t sendCommand(MessageQueueId_t queueId, ActionId_t actionId,
|
ReturnValue_t sendCommand(MessageQueueId_t queueId, ActionId_t actionId,
|
||||||
store_address_t storeId);
|
store_address_t storeId);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* COMMANDACTIONHELPER_H_ */
|
#endif /* COMMANDACTIONHELPER_H_ */
|
||||||
|
@ -15,22 +15,22 @@
|
|||||||
* - replyReceived(id, step, cause) (if cause == OK, it's a success).
|
* - replyReceived(id, step, cause) (if cause == OK, it's a success).
|
||||||
*/
|
*/
|
||||||
class CommandsActionsIF {
|
class CommandsActionsIF {
|
||||||
friend class CommandActionHelper;
|
friend class CommandActionHelper;
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF;
|
||||||
static const ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
|
static const ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
|
||||||
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
|
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
|
||||||
virtual ~CommandsActionsIF() {}
|
virtual ~CommandsActionsIF() {}
|
||||||
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
||||||
protected:
|
protected:
|
||||||
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) = 0;
|
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) = 0;
|
||||||
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step,
|
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step,
|
||||||
ReturnValue_t returnCode) = 0;
|
ReturnValue_t returnCode) = 0;
|
||||||
virtual void dataReceived(ActionId_t actionId, const uint8_t* data,
|
virtual void dataReceived(ActionId_t actionId, const uint8_t* data,
|
||||||
uint32_t size) = 0;
|
uint32_t size) = 0;
|
||||||
virtual void completionSuccessfulReceived(ActionId_t actionId) = 0;
|
virtual void completionSuccessfulReceived(ActionId_t actionId) = 0;
|
||||||
virtual void completionFailedReceived(ActionId_t actionId,
|
virtual void completionFailedReceived(ActionId_t actionId,
|
||||||
ReturnValue_t returnCode) = 0;
|
ReturnValue_t returnCode) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,28 +35,28 @@
|
|||||||
*/
|
*/
|
||||||
class HasActionsIF {
|
class HasActionsIF {
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_ACTIONS_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_ACTIONS_IF;
|
||||||
static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1);
|
static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1);
|
||||||
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
|
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
|
||||||
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
|
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
|
||||||
static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4);
|
static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4);
|
||||||
virtual ~HasActionsIF() { }
|
virtual ~HasActionsIF() { }
|
||||||
/**
|
/**
|
||||||
* Function to get the MessageQueueId_t of the implementing object
|
* Function to get the MessageQueueId_t of the implementing object
|
||||||
* @return MessageQueueId_t of the object
|
* @return MessageQueueId_t of the object
|
||||||
*/
|
*/
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
/**
|
/**
|
||||||
* Execute or initialize the execution of a certain function.
|
* Execute or initialize the execution of a certain function.
|
||||||
* The ActionHelpers will execute this function and behave differently
|
* The ActionHelpers will execute this function and behave differently
|
||||||
* depending on the returnvalue.
|
* depending on the returnvalue.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* -@c EXECUTION_FINISHED Finish reply will be generated
|
* -@c EXECUTION_FINISHED Finish reply will be generated
|
||||||
* -@c Not RETURN_OK Step failure reply will be generated
|
* -@c Not RETURN_OK Step failure reply will be generated
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t executeAction(ActionId_t actionId,
|
virtual ReturnValue_t executeAction(ActionId_t actionId,
|
||||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
|
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,74 +2,74 @@
|
|||||||
#include "SimpleActionHelper.h"
|
#include "SimpleActionHelper.h"
|
||||||
|
|
||||||
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner,
|
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner,
|
||||||
MessageQueueIF* useThisQueue) :
|
MessageQueueIF* useThisQueue) :
|
||||||
ActionHelper(setOwner, useThisQueue), isExecuting(false) {
|
ActionHelper(setOwner, useThisQueue), isExecuting(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleActionHelper::~SimpleActionHelper() {
|
SimpleActionHelper::~SimpleActionHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleActionHelper::step(ReturnValue_t result) {
|
void SimpleActionHelper::step(ReturnValue_t result) {
|
||||||
// STEP_OFFESET is subtracted to compensate for adding offset in base
|
// STEP_OFFESET is subtracted to compensate for adding offset in base
|
||||||
// method, which is not necessary here.
|
// method, which is not necessary here.
|
||||||
ActionHelper::step(stepCount - STEP_OFFSET, lastCommander, lastAction,
|
ActionHelper::step(stepCount - STEP_OFFSET, lastCommander, lastAction,
|
||||||
result);
|
result);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
resetHelper();
|
resetHelper();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleActionHelper::finish(ReturnValue_t result) {
|
void SimpleActionHelper::finish(ReturnValue_t result) {
|
||||||
ActionHelper::finish(lastCommander, lastAction, result);
|
ActionHelper::finish(lastCommander, lastAction, result);
|
||||||
resetHelper();
|
resetHelper();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SimpleActionHelper::reportData(SerializeIF* data) {
|
ReturnValue_t SimpleActionHelper::reportData(SerializeIF* data) {
|
||||||
return ActionHelper::reportData(lastCommander, lastAction, data);
|
return ActionHelper::reportData(lastCommander, lastAction, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleActionHelper::resetHelper() {
|
void SimpleActionHelper::resetHelper() {
|
||||||
stepCount = 0;
|
stepCount = 0;
|
||||||
isExecuting = false;
|
isExecuting = false;
|
||||||
lastAction = 0;
|
lastAction = 0;
|
||||||
lastCommander = 0;
|
lastCommander = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy,
|
void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy,
|
||||||
ActionId_t actionId, store_address_t dataAddress) {
|
ActionId_t actionId, store_address_t dataAddress) {
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
if (isExecuting) {
|
if (isExecuting) {
|
||||||
ipcStore->deleteData(dataAddress);
|
ipcStore->deleteData(dataAddress);
|
||||||
ActionMessage::setStepReply(&reply, actionId, 0,
|
ActionMessage::setStepReply(&reply, actionId, 0,
|
||||||
HasActionsIF::IS_BUSY);
|
HasActionsIF::IS_BUSY);
|
||||||
queueToUse->sendMessage(commandedBy, &reply);
|
queueToUse->sendMessage(commandedBy, &reply);
|
||||||
}
|
}
|
||||||
const uint8_t* dataPtr = NULL;
|
const uint8_t* dataPtr = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||||
queueToUse->sendMessage(commandedBy, &reply);
|
queueToUse->sendMessage(commandedBy, &reply);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastCommander = commandedBy;
|
lastCommander = commandedBy;
|
||||||
lastAction = actionId;
|
lastAction = actionId;
|
||||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||||
ipcStore->deleteData(dataAddress);
|
ipcStore->deleteData(dataAddress);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case HasReturnvaluesIF::RETURN_OK:
|
case HasReturnvaluesIF::RETURN_OK:
|
||||||
isExecuting = true;
|
isExecuting = true;
|
||||||
stepCount++;
|
stepCount++;
|
||||||
break;
|
break;
|
||||||
case HasActionsIF::EXECUTION_FINISHED:
|
case HasActionsIF::EXECUTION_FINISHED:
|
||||||
ActionMessage::setCompletionReply(&reply, actionId,
|
ActionMessage::setCompletionReply(&reply, actionId,
|
||||||
HasReturnvaluesIF::RETURN_OK);
|
HasReturnvaluesIF::RETURN_OK);
|
||||||
queueToUse->sendMessage(commandedBy, &reply);
|
queueToUse->sendMessage(commandedBy, &reply);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||||
queueToUse->sendMessage(commandedBy, &reply);
|
queueToUse->sendMessage(commandedBy, &reply);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,27 +4,27 @@
|
|||||||
#include "ActionHelper.h"
|
#include "ActionHelper.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is an action helper which is only able to service one action
|
* @brief This is an action helper which is only able to service one action
|
||||||
* at a time but remembers last commander and last action which
|
* at a time but remembers last commander and last action which
|
||||||
* simplifies usage
|
* simplifies usage
|
||||||
*/
|
*/
|
||||||
class SimpleActionHelper: public ActionHelper {
|
class SimpleActionHelper: public ActionHelper {
|
||||||
public:
|
public:
|
||||||
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||||
virtual ~SimpleActionHelper();
|
virtual ~SimpleActionHelper();
|
||||||
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||||
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||||
ReturnValue_t reportData(SerializeIF* data);
|
ReturnValue_t reportData(SerializeIF* data);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||||
store_address_t dataAddress);
|
store_address_t dataAddress);
|
||||||
virtual void resetHelper();
|
virtual void resetHelper();
|
||||||
private:
|
private:
|
||||||
bool isExecuting;
|
bool isExecuting;
|
||||||
MessageQueueId_t lastCommander = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t lastCommander = MessageQueueIF::NO_QUEUE;
|
||||||
ActionId_t lastAction = 0;
|
ActionId_t lastAction = 0;
|
||||||
uint8_t stepCount = 0;
|
uint8_t stepCount = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SIMPLEACTIONHELPER_H_ */
|
#endif /* SIMPLEACTIONHELPER_H_ */
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "../serialize/SerializeIF.h"
|
#include "../serialize/SerializeIF.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A List that stores its values in an array.
|
* @brief A List that stores its values in an array.
|
||||||
* @details
|
* @details
|
||||||
* The underlying storage is an array that can be allocated by the class
|
* The underlying storage is an array that can be allocated by the class
|
||||||
* itself or supplied via ctor.
|
* itself or supplied via ctor.
|
||||||
@ -15,237 +15,237 @@
|
|||||||
*/
|
*/
|
||||||
template<typename T, typename count_t = uint8_t>
|
template<typename T, typename count_t = uint8_t>
|
||||||
class ArrayList {
|
class ArrayList {
|
||||||
template<typename U, typename count> friend class SerialArrayListAdapter;
|
template<typename U, typename count> friend class SerialArrayListAdapter;
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
||||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the allocating constructor.
|
* This is the allocating constructor.
|
||||||
* It allocates an array of the specified size.
|
* It allocates an array of the specified size.
|
||||||
* @param maxSize
|
* @param maxSize
|
||||||
*/
|
*/
|
||||||
ArrayList(count_t maxSize) :
|
ArrayList(count_t maxSize) :
|
||||||
size(0), maxSize_(maxSize), allocated(true) {
|
size(0), maxSize_(maxSize), allocated(true) {
|
||||||
entries = new T[maxSize];
|
entries = new T[maxSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the non-allocating constructor
|
* This is the non-allocating constructor
|
||||||
*
|
*
|
||||||
* It expects a pointer to an array of a certain size and initializes
|
* It expects a pointer to an array of a certain size and initializes
|
||||||
* itself to it.
|
* itself to it.
|
||||||
*
|
*
|
||||||
* @param storage the array to use as backend
|
* @param storage the array to use as backend
|
||||||
* @param maxSize size of storage
|
* @param maxSize size of storage
|
||||||
* @param size size of data already present in storage
|
* @param size size of data already present in storage
|
||||||
*/
|
*/
|
||||||
ArrayList(T *storage, count_t maxSize, count_t size = 0) :
|
ArrayList(T *storage, count_t maxSize, count_t size = 0) :
|
||||||
size(size), entries(storage), maxSize_(maxSize), allocated(false) {
|
size(size), entries(storage), maxSize_(maxSize), allocated(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copying is forbiden by declaring copy ctor and copy assignment deleted
|
* Copying is forbiden by declaring copy ctor and copy assignment deleted
|
||||||
* It is too ambigous in this case.
|
* It is too ambigous in this case.
|
||||||
* (Allocate a new backend? Use the same? What to do in an modifying call?)
|
* (Allocate a new backend? Use the same? What to do in an modifying call?)
|
||||||
*/
|
*/
|
||||||
ArrayList(const ArrayList& other) = delete;
|
ArrayList(const ArrayList& other) = delete;
|
||||||
const ArrayList& operator=(const ArrayList& other) = delete;
|
const ArrayList& operator=(const ArrayList& other) = delete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of Elements stored in this List
|
* Number of Elements stored in this List
|
||||||
*/
|
*/
|
||||||
count_t size;
|
count_t size;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor, if the allocating constructor was used, it deletes the array.
|
* Destructor, if the allocating constructor was used, it deletes the array.
|
||||||
*/
|
*/
|
||||||
virtual ~ArrayList() {
|
virtual ~ArrayList() {
|
||||||
if (allocated) {
|
if (allocated) {
|
||||||
delete[] entries;
|
delete[] entries;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An Iterator to go trough an ArrayList
|
* An Iterator to go trough an ArrayList
|
||||||
*
|
*
|
||||||
* It stores a pointer to an element and increments the
|
* It stores a pointer to an element and increments the
|
||||||
* pointer when incremented itself.
|
* pointer when incremented itself.
|
||||||
*/
|
*/
|
||||||
class Iterator {
|
class Iterator {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Empty ctor, points to NULL
|
* Empty ctor, points to NULL
|
||||||
*/
|
*/
|
||||||
Iterator(): value(0) {}
|
Iterator(): value(0) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the Iterator to point to an element
|
* Initializes the Iterator to point to an element
|
||||||
*
|
*
|
||||||
* @param initialize
|
* @param initialize
|
||||||
*/
|
*/
|
||||||
Iterator(T *initialize) {
|
Iterator(T *initialize) {
|
||||||
value = initialize;
|
value = initialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current element the iterator points to
|
* The current element the iterator points to
|
||||||
*/
|
*/
|
||||||
T *value;
|
T *value;
|
||||||
|
|
||||||
Iterator& operator++() {
|
Iterator& operator++() {
|
||||||
value++;
|
value++;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator operator++(int) {
|
Iterator operator++(int) {
|
||||||
Iterator tmp(*this);
|
Iterator tmp(*this);
|
||||||
operator++();
|
operator++();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator& operator--() {
|
Iterator& operator--() {
|
||||||
value--;
|
value--;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator operator--(int) {
|
Iterator operator--(int) {
|
||||||
Iterator tmp(*this);
|
Iterator tmp(*this);
|
||||||
operator--();
|
operator--();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
T& operator*() {
|
T& operator*() {
|
||||||
return *value;
|
return *value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& operator*() const {
|
const T& operator*() const {
|
||||||
return *value;
|
return *value;
|
||||||
}
|
}
|
||||||
|
|
||||||
T *operator->() {
|
T *operator->() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T *operator->() const {
|
const T *operator->() const {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
friend bool operator==(const ArrayList::Iterator& lhs,
|
friend bool operator==(const ArrayList::Iterator& lhs,
|
||||||
const ArrayList::Iterator& rhs) {
|
const ArrayList::Iterator& rhs) {
|
||||||
return (lhs.value == rhs.value);
|
return (lhs.value == rhs.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator!=(const ArrayList::Iterator& lhs,
|
friend bool operator!=(const ArrayList::Iterator& lhs,
|
||||||
const ArrayList::Iterator& rhs) {
|
const ArrayList::Iterator& rhs) {
|
||||||
return not (lhs.value == rhs.value);
|
return not (lhs.value == rhs.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterator pointing to the first stored elmement
|
* Iterator pointing to the first stored elmement
|
||||||
*
|
*
|
||||||
* @return Iterator to the first element
|
* @return Iterator to the first element
|
||||||
*/
|
*/
|
||||||
Iterator begin() const {
|
Iterator begin() const {
|
||||||
return Iterator(&entries[0]);
|
return Iterator(&entries[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns an Iterator pointing to the element after the last stored entry
|
* returns an Iterator pointing to the element after the last stored entry
|
||||||
*
|
*
|
||||||
* @return Iterator to the element after the last entry
|
* @return Iterator to the element after the last entry
|
||||||
*/
|
*/
|
||||||
Iterator end() const {
|
Iterator end() const {
|
||||||
return Iterator(&entries[size]);
|
return Iterator(&entries[size]);
|
||||||
}
|
}
|
||||||
|
|
||||||
T & operator[](count_t i) const {
|
T & operator[](count_t i) const {
|
||||||
return entries[i];
|
return entries[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The first element
|
* The first element
|
||||||
*
|
*
|
||||||
* @return pointer to the first stored element
|
* @return pointer to the first stored element
|
||||||
*/
|
*/
|
||||||
T *front() {
|
T *front() {
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last element
|
* The last element
|
||||||
*
|
*
|
||||||
* does not return a valid pointer if called on an empty list.
|
* does not return a valid pointer if called on an empty list.
|
||||||
*
|
*
|
||||||
* @return pointer to the last stored element
|
* @return pointer to the last stored element
|
||||||
*/
|
*/
|
||||||
T *back() {
|
T *back() {
|
||||||
return &entries[size - 1];
|
return &entries[size - 1];
|
||||||
//Alternative solution
|
//Alternative solution
|
||||||
//return const_cast<T*>(static_cast<const T*>(*this).back());
|
//return const_cast<T*>(static_cast<const T*>(*this).back());
|
||||||
}
|
}
|
||||||
|
|
||||||
const T* back() const{
|
const T* back() const{
|
||||||
return &entries[size-1];
|
return &entries[size-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum number of elements this List can contain
|
* The maximum number of elements this List can contain
|
||||||
*
|
*
|
||||||
* @return maximum number of elements
|
* @return maximum number of elements
|
||||||
*/
|
*/
|
||||||
size_t maxSize() const {
|
size_t maxSize() const {
|
||||||
return this->maxSize_;
|
return this->maxSize_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a new element into the list.
|
* Insert a new element into the list.
|
||||||
*
|
*
|
||||||
* The new element is inserted after the last stored element.
|
* The new element is inserted after the last stored element.
|
||||||
*
|
*
|
||||||
* @param entry
|
* @param entry
|
||||||
* @return
|
* @return
|
||||||
* -@c FULL if the List is full
|
* -@c FULL if the List is full
|
||||||
* -@c RETURN_OK else
|
* -@c RETURN_OK else
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insert(T entry) {
|
ReturnValue_t insert(T entry) {
|
||||||
if (size >= maxSize_) {
|
if (size >= maxSize_) {
|
||||||
return FULL;
|
return FULL;
|
||||||
}
|
}
|
||||||
entries[size] = entry;
|
entries[size] = entry;
|
||||||
++size;
|
++size;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clear the List
|
* clear the List
|
||||||
*
|
*
|
||||||
* This does not actually clear all entries, it only sets the size to 0.
|
* This does not actually clear all entries, it only sets the size to 0.
|
||||||
*/
|
*/
|
||||||
void clear() {
|
void clear() {
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
count_t remaining() {
|
count_t remaining() {
|
||||||
return (maxSize_ - size);
|
return (maxSize_ - size);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* pointer to the array in which the entries are stored
|
* pointer to the array in which the entries are stored
|
||||||
*/
|
*/
|
||||||
T *entries;
|
T *entries;
|
||||||
/**
|
/**
|
||||||
* remembering the maximum size
|
* remembering the maximum size
|
||||||
*/
|
*/
|
||||||
size_t maxSize_;
|
size_t maxSize_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* true if the array was allocated and needs to be deleted in the destructor.
|
* true if the array was allocated and needs to be deleted in the destructor.
|
||||||
*/
|
*/
|
||||||
bool allocated;
|
bool allocated;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,65 +7,65 @@
|
|||||||
template<typename Tp>
|
template<typename Tp>
|
||||||
class BinaryNode {
|
class BinaryNode {
|
||||||
public:
|
public:
|
||||||
BinaryNode(Tp* setValue) :
|
BinaryNode(Tp* setValue) :
|
||||||
value(setValue), left(NULL), right(NULL), parent(NULL) {
|
value(setValue), left(NULL), right(NULL), parent(NULL) {
|
||||||
}
|
}
|
||||||
Tp *value;
|
Tp *value;
|
||||||
BinaryNode* left;
|
BinaryNode* left;
|
||||||
BinaryNode* right;
|
BinaryNode* right;
|
||||||
BinaryNode* parent;
|
BinaryNode* parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Tp>
|
template<typename Tp>
|
||||||
class ExplicitNodeIterator {
|
class ExplicitNodeIterator {
|
||||||
public:
|
public:
|
||||||
typedef ExplicitNodeIterator<Tp> _Self;
|
typedef ExplicitNodeIterator<Tp> _Self;
|
||||||
typedef BinaryNode<Tp> _Node;
|
typedef BinaryNode<Tp> _Node;
|
||||||
typedef Tp value_type;
|
typedef Tp value_type;
|
||||||
typedef Tp* pointer;
|
typedef Tp* pointer;
|
||||||
typedef Tp& reference;
|
typedef Tp& reference;
|
||||||
ExplicitNodeIterator() :
|
ExplicitNodeIterator() :
|
||||||
element(NULL) {
|
element(NULL) {
|
||||||
}
|
}
|
||||||
ExplicitNodeIterator(_Node* node) :
|
ExplicitNodeIterator(_Node* node) :
|
||||||
element(node) {
|
element(node) {
|
||||||
}
|
}
|
||||||
BinaryNode<Tp>* element;
|
BinaryNode<Tp>* element;
|
||||||
_Self up() {
|
_Self up() {
|
||||||
return _Self(element->parent);
|
return _Self(element->parent);
|
||||||
}
|
}
|
||||||
_Self left() {
|
_Self left() {
|
||||||
if (element != NULL) {
|
if (element != NULL) {
|
||||||
return _Self(element->left);
|
return _Self(element->left);
|
||||||
} else {
|
} else {
|
||||||
return _Self(NULL);
|
return _Self(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
_Self right() {
|
_Self right() {
|
||||||
if (element != NULL) {
|
if (element != NULL) {
|
||||||
return _Self(element->right);
|
return _Self(element->right);
|
||||||
} else {
|
} else {
|
||||||
return _Self(NULL);
|
return _Self(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
bool operator==(const _Self& __x) const {
|
bool operator==(const _Self& __x) const {
|
||||||
return element == __x.element;
|
return element == __x.element;
|
||||||
}
|
}
|
||||||
bool operator!=(const _Self& __x) const {
|
bool operator!=(const _Self& __x) const {
|
||||||
return element != __x.element;
|
return element != __x.element;
|
||||||
}
|
}
|
||||||
pointer
|
pointer
|
||||||
operator->() const {
|
operator->() const {
|
||||||
if (element != NULL) {
|
if (element != NULL) {
|
||||||
return element->value;
|
return element->value;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pointer operator*() const {
|
pointer operator*() const {
|
||||||
return this->operator->();
|
return this->operator->();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,77 +75,77 @@ public:
|
|||||||
template<typename Tp>
|
template<typename Tp>
|
||||||
class BinaryTree {
|
class BinaryTree {
|
||||||
public:
|
public:
|
||||||
typedef ExplicitNodeIterator<Tp> iterator;
|
typedef ExplicitNodeIterator<Tp> iterator;
|
||||||
typedef BinaryNode<Tp> Node;
|
typedef BinaryNode<Tp> Node;
|
||||||
typedef std::pair<iterator, iterator> children;
|
typedef std::pair<iterator, iterator> children;
|
||||||
BinaryTree() :
|
BinaryTree() :
|
||||||
rootNode(NULL) {
|
rootNode(NULL) {
|
||||||
}
|
}
|
||||||
BinaryTree(Node* rootNode) :
|
BinaryTree(Node* rootNode) :
|
||||||
rootNode(rootNode) {
|
rootNode(rootNode) {
|
||||||
}
|
}
|
||||||
iterator begin() const {
|
iterator begin() const {
|
||||||
return iterator(rootNode);
|
return iterator(rootNode);
|
||||||
}
|
}
|
||||||
static iterator end() {
|
static iterator end() {
|
||||||
return iterator(NULL);
|
return iterator(NULL);
|
||||||
}
|
}
|
||||||
iterator insert(bool insertLeft, iterator parentNode, Node* newNode ) {
|
iterator insert(bool insertLeft, iterator parentNode, Node* newNode ) {
|
||||||
newNode->parent = parentNode.element;
|
newNode->parent = parentNode.element;
|
||||||
if (parentNode.element != NULL) {
|
if (parentNode.element != NULL) {
|
||||||
if (insertLeft) {
|
if (insertLeft) {
|
||||||
parentNode.element->left = newNode;
|
parentNode.element->left = newNode;
|
||||||
} else {
|
} else {
|
||||||
parentNode.element->right = newNode;
|
parentNode.element->right = newNode;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Insert first element.
|
//Insert first element.
|
||||||
rootNode = newNode;
|
rootNode = newNode;
|
||||||
}
|
}
|
||||||
return iterator(newNode);
|
return iterator(newNode);
|
||||||
}
|
}
|
||||||
//No recursion to children. Needs to be done externally.
|
//No recursion to children. Needs to be done externally.
|
||||||
children erase(iterator node) {
|
children erase(iterator node) {
|
||||||
if (node.element == rootNode) {
|
if (node.element == rootNode) {
|
||||||
//We're root node
|
//We're root node
|
||||||
rootNode = NULL;
|
rootNode = NULL;
|
||||||
} else {
|
} else {
|
||||||
//Delete parent's reference
|
//Delete parent's reference
|
||||||
if (node.up().left() == node) {
|
if (node.up().left() == node) {
|
||||||
node.up().element->left = NULL;
|
node.up().element->left = NULL;
|
||||||
} else {
|
} else {
|
||||||
node.up().element->right = NULL;
|
node.up().element->right = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return children(node.element->left, node.element->right);
|
return children(node.element->left, node.element->right);
|
||||||
}
|
}
|
||||||
static uint32_t countLeft(iterator start) {
|
static uint32_t countLeft(iterator start) {
|
||||||
if (start == end()) {
|
if (start == end()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//We also count the start node itself.
|
//We also count the start node itself.
|
||||||
uint32_t count = 1;
|
uint32_t count = 1;
|
||||||
while (start.left() != end()) {
|
while (start.left() != end()) {
|
||||||
count++;
|
count++;
|
||||||
start = start.left();
|
start = start.left();
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
static uint32_t countRight(iterator start) {
|
static uint32_t countRight(iterator start) {
|
||||||
if (start == end()) {
|
if (start == end()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//We also count the start node itself.
|
//We also count the start node itself.
|
||||||
uint32_t count = 1;
|
uint32_t count = 1;
|
||||||
while (start.right() != end()) {
|
while (start.right() != end()) {
|
||||||
count++;
|
count++;
|
||||||
start = start.right();
|
start = start.right();
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Node* rootNode;
|
Node* rootNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
target_sources(${LIB_FSFW_NAME}
|
target_sources(${LIB_FSFW_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
SharedRingBuffer.cpp
|
SharedRingBuffer.cpp
|
||||||
SimpleRingBuffer.cpp
|
SimpleRingBuffer.cpp
|
||||||
)
|
)
|
@ -5,8 +5,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Simple First-In-First-Out data structure. The maximum size
|
* @brief Simple First-In-First-Out data structure. The maximum size
|
||||||
* can be set in the constructor.
|
* can be set in the constructor.
|
||||||
* @details
|
* @details
|
||||||
* The maximum capacity can be determined at run-time, so this container
|
* The maximum capacity can be determined at run-time, so this container
|
||||||
* performs dynamic memory allocation!
|
* performs dynamic memory allocation!
|
||||||
@ -17,39 +17,39 @@
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class DynamicFIFO: public FIFOBase<T> {
|
class DynamicFIFO: public FIFOBase<T> {
|
||||||
public:
|
public:
|
||||||
DynamicFIFO(size_t maxCapacity): FIFOBase<T>(nullptr, maxCapacity),
|
DynamicFIFO(size_t maxCapacity): FIFOBase<T>(nullptr, maxCapacity),
|
||||||
fifoVector(maxCapacity) {
|
fifoVector(maxCapacity) {
|
||||||
// trying to pass the pointer of the uninitialized vector
|
// trying to pass the pointer of the uninitialized vector
|
||||||
// to the FIFOBase constructor directly lead to a super evil bug.
|
// to the FIFOBase constructor directly lead to a super evil bug.
|
||||||
// So we do it like this now.
|
// So we do it like this now.
|
||||||
this->setContainer(fifoVector.data());
|
this->setContainer(fifoVector.data());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Custom copy constructor which prevents setting the
|
* @brief Custom copy constructor which prevents setting the
|
||||||
* underlying pointer wrong. This function allocates memory!
|
* underlying pointer wrong. This function allocates memory!
|
||||||
* @details This is a very heavy operation so try to avoid this!
|
* @details This is a very heavy operation so try to avoid this!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
DynamicFIFO(const DynamicFIFO& other): FIFOBase<T>(other),
|
DynamicFIFO(const DynamicFIFO& other): FIFOBase<T>(other),
|
||||||
fifoVector(other.maxCapacity) {
|
fifoVector(other.maxCapacity) {
|
||||||
this->fifoVector = other.fifoVector;
|
this->fifoVector = other.fifoVector;
|
||||||
this->setContainer(fifoVector.data());
|
this->setContainer(fifoVector.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Custom assignment operator
|
* @brief Custom assignment operator
|
||||||
* @details This is a very heavy operation so try to avoid this!
|
* @details This is a very heavy operation so try to avoid this!
|
||||||
* @param other DyamicFIFO to copy from
|
* @param other DyamicFIFO to copy from
|
||||||
*/
|
*/
|
||||||
DynamicFIFO& operator=(const DynamicFIFO& other){
|
DynamicFIFO& operator=(const DynamicFIFO& other){
|
||||||
FIFOBase<T>::operator=(other);
|
FIFOBase<T>::operator=(other);
|
||||||
this->fifoVector = other.fifoVector;
|
this->fifoVector = other.fifoVector;
|
||||||
this->setContainer(fifoVector.data());
|
this->setContainer(fifoVector.data());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::vector<T> fifoVector;
|
std::vector<T> fifoVector;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CONTAINER_DYNAMICFIFO_H_ */
|
#endif /* FSFW_CONTAINER_DYNAMICFIFO_H_ */
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Simple First-In-First-Out data structure with size fixed at
|
* @brief Simple First-In-First-Out data structure with size fixed at
|
||||||
* compile time
|
* compile time
|
||||||
* @details
|
* @details
|
||||||
* Performs no dynamic memory allocation.
|
* Performs no dynamic memory allocation.
|
||||||
* The public interface of FIFOBase exposes the user interface for the FIFO.
|
* The public interface of FIFOBase exposes the user interface for the FIFO.
|
||||||
@ -16,32 +16,32 @@
|
|||||||
template<typename T, size_t capacity>
|
template<typename T, size_t capacity>
|
||||||
class FIFO: public FIFOBase<T> {
|
class FIFO: public FIFOBase<T> {
|
||||||
public:
|
public:
|
||||||
FIFO(): FIFOBase<T>(nullptr, capacity) {
|
FIFO(): FIFOBase<T>(nullptr, capacity) {
|
||||||
this->setContainer(fifoArray.data());
|
this->setContainer(fifoArray.data());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Custom copy constructor to set pointer correctly.
|
* @brief Custom copy constructor to set pointer correctly.
|
||||||
* @param other
|
* @param other
|
||||||
*/
|
*/
|
||||||
FIFO(const FIFO& other): FIFOBase<T>(other) {
|
FIFO(const FIFO& other): FIFOBase<T>(other) {
|
||||||
this->fifoArray = other.fifoArray;
|
this->fifoArray = other.fifoArray;
|
||||||
this->setContainer(fifoArray.data());
|
this->setContainer(fifoArray.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Custom assignment operator
|
* @brief Custom assignment operator
|
||||||
* @param other
|
* @param other
|
||||||
*/
|
*/
|
||||||
FIFO& operator=(const FIFO& other){
|
FIFO& operator=(const FIFO& other){
|
||||||
FIFOBase<T>::operator=(other);
|
FIFOBase<T>::operator=(other);
|
||||||
this->fifoArray = other.fifoArray;
|
this->fifoArray = other.fifoArray;
|
||||||
this->setContainer(fifoArray.data());
|
this->setContainer(fifoArray.data());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<T, capacity> fifoArray;
|
std::array<T, capacity> fifoArray;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CONTAINER_FIFO_H_ */
|
#endif /* FSFW_CONTAINER_FIFO_H_ */
|
||||||
|
@ -8,70 +8,70 @@
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class FIFOBase {
|
class FIFOBase {
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
|
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
|
||||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
|
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
|
||||||
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
|
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
|
||||||
|
|
||||||
/** Default ctor, takes pointer to first entry of underlying container
|
/** Default ctor, takes pointer to first entry of underlying container
|
||||||
* and maximum capacity */
|
* and maximum capacity */
|
||||||
FIFOBase(T* values, const size_t maxCapacity);
|
FIFOBase(T* values, const size_t maxCapacity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert value into FIFO
|
* Insert value into FIFO
|
||||||
* @param value
|
* @param value
|
||||||
* @return RETURN_OK on success, FULL if full
|
* @return RETURN_OK on success, FULL if full
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insert(T value);
|
ReturnValue_t insert(T value);
|
||||||
/**
|
/**
|
||||||
* Retrieve item from FIFO. This removes the item from the FIFO.
|
* Retrieve item from FIFO. This removes the item from the FIFO.
|
||||||
* @param value Must point to a valid T
|
* @param value Must point to a valid T
|
||||||
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
|
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
|
||||||
*/
|
*/
|
||||||
ReturnValue_t retrieve(T *value);
|
ReturnValue_t retrieve(T *value);
|
||||||
/**
|
/**
|
||||||
* Retrieve item from FIFO without removing it from FIFO.
|
* Retrieve item from FIFO without removing it from FIFO.
|
||||||
* @param value Must point to a valid T
|
* @param value Must point to a valid T
|
||||||
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
|
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
|
||||||
*/
|
*/
|
||||||
ReturnValue_t peek(T * value);
|
ReturnValue_t peek(T * value);
|
||||||
/**
|
/**
|
||||||
* Remove item from FIFO.
|
* Remove item from FIFO.
|
||||||
* @return RETURN_OK on success, EMPTY if empty
|
* @return RETURN_OK on success, EMPTY if empty
|
||||||
*/
|
*/
|
||||||
ReturnValue_t pop();
|
ReturnValue_t pop();
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Check if FIFO is empty
|
* Check if FIFO is empty
|
||||||
* @return True if empty, False if not
|
* @return True if empty, False if not
|
||||||
*/
|
*/
|
||||||
bool empty();
|
bool empty();
|
||||||
/***
|
/***
|
||||||
* Check if FIFO is Full
|
* Check if FIFO is Full
|
||||||
* @return True if full, False if not
|
* @return True if full, False if not
|
||||||
*/
|
*/
|
||||||
bool full();
|
bool full();
|
||||||
/***
|
/***
|
||||||
* Current used size (elements) used
|
* Current used size (elements) used
|
||||||
* @return size_t in elements
|
* @return size_t in elements
|
||||||
*/
|
*/
|
||||||
size_t size();
|
size_t size();
|
||||||
/***
|
/***
|
||||||
* Get maximal capacity of fifo
|
* Get maximal capacity of fifo
|
||||||
* @return size_t with max capacity of this fifo
|
* @return size_t with max capacity of this fifo
|
||||||
*/
|
*/
|
||||||
size_t getMaxCapacity() const;
|
size_t getMaxCapacity() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setContainer(T* data);
|
void setContainer(T* data);
|
||||||
size_t maxCapacity = 0;
|
size_t maxCapacity = 0;
|
||||||
|
|
||||||
T* values;
|
T* values;
|
||||||
|
|
||||||
size_t readIndex = 0;
|
size_t readIndex = 0;
|
||||||
size_t writeIndex = 0;
|
size_t writeIndex = 0;
|
||||||
size_t currentSize = 0;
|
size_t currentSize = 0;
|
||||||
|
|
||||||
size_t next(size_t current);
|
size_t next(size_t current);
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "FIFOBase.tpp"
|
#include "FIFOBase.tpp"
|
||||||
|
@ -7,87 +7,87 @@
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline FIFOBase<T>::FIFOBase(T* values, const size_t maxCapacity):
|
inline FIFOBase<T>::FIFOBase(T* values, const size_t maxCapacity):
|
||||||
maxCapacity(maxCapacity), values(values){};
|
maxCapacity(maxCapacity), values(values){};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ReturnValue_t FIFOBase<T>::insert(T value) {
|
inline ReturnValue_t FIFOBase<T>::insert(T value) {
|
||||||
if (full()) {
|
if (full()) {
|
||||||
return FULL;
|
return FULL;
|
||||||
} else {
|
} else {
|
||||||
values[writeIndex] = value;
|
values[writeIndex] = value;
|
||||||
writeIndex = next(writeIndex);
|
writeIndex = next(writeIndex);
|
||||||
++currentSize;
|
++currentSize;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ReturnValue_t FIFOBase<T>::retrieve(T* value) {
|
inline ReturnValue_t FIFOBase<T>::retrieve(T* value) {
|
||||||
if (empty()) {
|
if (empty()) {
|
||||||
return EMPTY;
|
return EMPTY;
|
||||||
} else {
|
} else {
|
||||||
if (value == nullptr){
|
if (value == nullptr){
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
*value = values[readIndex];
|
*value = values[readIndex];
|
||||||
readIndex = next(readIndex);
|
readIndex = next(readIndex);
|
||||||
--currentSize;
|
--currentSize;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ReturnValue_t FIFOBase<T>::peek(T* value) {
|
inline ReturnValue_t FIFOBase<T>::peek(T* value) {
|
||||||
if(empty()) {
|
if(empty()) {
|
||||||
return EMPTY;
|
return EMPTY;
|
||||||
} else {
|
} else {
|
||||||
if (value == nullptr){
|
if (value == nullptr){
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
*value = values[readIndex];
|
*value = values[readIndex];
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ReturnValue_t FIFOBase<T>::pop() {
|
inline ReturnValue_t FIFOBase<T>::pop() {
|
||||||
T value;
|
T value;
|
||||||
return this->retrieve(&value);
|
return this->retrieve(&value);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool FIFOBase<T>::empty() {
|
inline bool FIFOBase<T>::empty() {
|
||||||
return (currentSize == 0);
|
return (currentSize == 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool FIFOBase<T>::full() {
|
inline bool FIFOBase<T>::full() {
|
||||||
return (currentSize == maxCapacity);
|
return (currentSize == maxCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline size_t FIFOBase<T>::size() {
|
inline size_t FIFOBase<T>::size() {
|
||||||
return currentSize;
|
return currentSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline size_t FIFOBase<T>::next(size_t current) {
|
inline size_t FIFOBase<T>::next(size_t current) {
|
||||||
++current;
|
++current;
|
||||||
if (current == maxCapacity) {
|
if (current == maxCapacity) {
|
||||||
current = 0;
|
current = 0;
|
||||||
}
|
}
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline size_t FIFOBase<T>::getMaxCapacity() const {
|
inline size_t FIFOBase<T>::getMaxCapacity() const {
|
||||||
return maxCapacity;
|
return maxCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void FIFOBase<T>::setContainer(T *data) {
|
inline void FIFOBase<T>::setContainer(T *data) {
|
||||||
this->values = data;
|
this->values = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,30 +8,30 @@
|
|||||||
*/
|
*/
|
||||||
template<typename T, size_t MAX_SIZE, typename count_t = uint8_t>
|
template<typename T, size_t MAX_SIZE, typename count_t = uint8_t>
|
||||||
class FixedArrayList: public ArrayList<T, count_t> {
|
class FixedArrayList: public ArrayList<T, count_t> {
|
||||||
static_assert(MAX_SIZE <= (pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE");
|
static_assert(MAX_SIZE <= (pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE");
|
||||||
private:
|
private:
|
||||||
T data[MAX_SIZE];
|
T data[MAX_SIZE];
|
||||||
public:
|
public:
|
||||||
FixedArrayList() :
|
FixedArrayList() :
|
||||||
ArrayList<T, count_t>(data, MAX_SIZE) {
|
ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedArrayList(const FixedArrayList& other) :
|
FixedArrayList(const FixedArrayList& other) :
|
||||||
ArrayList<T, count_t>(data, MAX_SIZE) {
|
ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||||
memcpy(this->data, other.data, sizeof(this->data));
|
memcpy(this->data, other.data, sizeof(this->data));
|
||||||
this->entries = data;
|
this->entries = data;
|
||||||
this->size = other.size;
|
this->size = other.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedArrayList& operator=(FixedArrayList other) {
|
FixedArrayList& operator=(FixedArrayList other) {
|
||||||
memcpy(this->data, other.data, sizeof(this->data));
|
memcpy(this->data, other.data, sizeof(this->data));
|
||||||
this->entries = data;
|
this->entries = data;
|
||||||
this->size = other.size;
|
this->size = other.size;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~FixedArrayList() {
|
virtual ~FixedArrayList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,212 +18,212 @@
|
|||||||
*/
|
*/
|
||||||
template<typename key_t, typename T>
|
template<typename key_t, typename T>
|
||||||
class FixedMap: public SerializeIF {
|
class FixedMap: public SerializeIF {
|
||||||
static_assert (std::is_trivially_copyable<T>::value or
|
static_assert (std::is_trivially_copyable<T>::value or
|
||||||
std::is_base_of<SerializeIF, T>::value,
|
std::is_base_of<SerializeIF, T>::value,
|
||||||
"Types used in FixedMap must either be trivial copy-able or a "
|
"Types used in FixedMap must either be trivial copy-able or a "
|
||||||
"derived class from SerializeIF to be serialize-able");
|
"derived class from SerializeIF to be serialize-able");
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
|
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
|
||||||
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
||||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
|
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
|
||||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
|
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const key_t EMPTY_SLOT = -1;
|
static const key_t EMPTY_SLOT = -1;
|
||||||
ArrayList<std::pair<key_t, T>, uint32_t> theMap;
|
ArrayList<std::pair<key_t, T>, uint32_t> theMap;
|
||||||
uint32_t _size;
|
uint32_t _size;
|
||||||
|
|
||||||
uint32_t findIndex(key_t key) const {
|
uint32_t findIndex(key_t key) const {
|
||||||
if (_size == 0) {
|
if (_size == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
for (i = 0; i < _size; ++i) {
|
for (i = 0; i < _size; ++i) {
|
||||||
if (theMap[i].first == key) {
|
if (theMap[i].first == key) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
FixedMap(uint32_t maxSize) :
|
FixedMap(uint32_t maxSize) :
|
||||||
theMap(maxSize), _size(0) {
|
theMap(maxSize), _size(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Iterator: public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator {
|
class Iterator: public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator {
|
||||||
public:
|
public:
|
||||||
Iterator() :
|
Iterator() :
|
||||||
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator() {
|
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator(std::pair<key_t, T> *pair) :
|
Iterator(std::pair<key_t, T> *pair) :
|
||||||
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) {
|
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
friend bool operator==(const typename FixedMap::Iterator& lhs,
|
friend bool operator==(const typename FixedMap::Iterator& lhs,
|
||||||
const typename FixedMap::Iterator& rhs) {
|
const typename FixedMap::Iterator& rhs) {
|
||||||
return (lhs.value == rhs.value);
|
return (lhs.value == rhs.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator!=(const typename FixedMap::Iterator& lhs,
|
friend bool operator!=(const typename FixedMap::Iterator& lhs,
|
||||||
const typename FixedMap::Iterator& rhs) {
|
const typename FixedMap::Iterator& rhs) {
|
||||||
return not (lhs.value == rhs.value);
|
return not (lhs.value == rhs.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator begin() const {
|
Iterator begin() const {
|
||||||
return Iterator(&theMap[0]);
|
return Iterator(&theMap[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator end() const {
|
Iterator end() const {
|
||||||
return Iterator(&theMap[_size]);
|
return Iterator(&theMap[_size]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t size() const {
|
uint32_t size() const {
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr) {
|
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr) {
|
||||||
if (exists(key) == HasReturnvaluesIF::RETURN_OK) {
|
if (exists(key) == HasReturnvaluesIF::RETURN_OK) {
|
||||||
return KEY_ALREADY_EXISTS;
|
return KEY_ALREADY_EXISTS;
|
||||||
}
|
}
|
||||||
if (_size == theMap.maxSize()) {
|
if (_size == theMap.maxSize()) {
|
||||||
return MAP_FULL;
|
return MAP_FULL;
|
||||||
}
|
}
|
||||||
theMap[_size].first = key;
|
theMap[_size].first = key;
|
||||||
theMap[_size].second = value;
|
theMap[_size].second = value;
|
||||||
if (storedValue != nullptr) {
|
if (storedValue != nullptr) {
|
||||||
*storedValue = Iterator(&theMap[_size]);
|
*storedValue = Iterator(&theMap[_size]);
|
||||||
}
|
}
|
||||||
++_size;
|
++_size;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t insert(std::pair<key_t, T> pair) {
|
ReturnValue_t insert(std::pair<key_t, T> pair) {
|
||||||
return insert(pair.first, pair.second);
|
return insert(pair.first, pair.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t exists(key_t key) const {
|
ReturnValue_t exists(key_t key) const {
|
||||||
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
||||||
if (findIndex(key) < _size) {
|
if (findIndex(key) < _size) {
|
||||||
result = HasReturnvaluesIF::RETURN_OK;
|
result = HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t erase(Iterator *iter) {
|
ReturnValue_t erase(Iterator *iter) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if ((i = findIndex((*iter).value->first)) >= _size) {
|
if ((i = findIndex((*iter).value->first)) >= _size) {
|
||||||
return KEY_DOES_NOT_EXIST;
|
return KEY_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
theMap[i] = theMap[_size - 1];
|
theMap[i] = theMap[_size - 1];
|
||||||
--_size;
|
--_size;
|
||||||
--((*iter).value);
|
--((*iter).value);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t erase(key_t key) {
|
ReturnValue_t erase(key_t key) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if ((i = findIndex(key)) >= _size) {
|
if ((i = findIndex(key)) >= _size) {
|
||||||
return KEY_DOES_NOT_EXIST;
|
return KEY_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
theMap[i] = theMap[_size - 1];
|
theMap[i] = theMap[_size - 1];
|
||||||
--_size;
|
--_size;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
T *findValue(key_t key) const {
|
T *findValue(key_t key) const {
|
||||||
return &theMap[findIndex(key)].second;
|
return &theMap[findIndex(key)].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator find(key_t key) const {
|
Iterator find(key_t key) const {
|
||||||
ReturnValue_t result = exists(key);
|
ReturnValue_t result = exists(key);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
return Iterator(&theMap[findIndex(key)]);
|
return Iterator(&theMap[findIndex(key)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t find(key_t key, T **value) const {
|
ReturnValue_t find(key_t key, T **value) const {
|
||||||
ReturnValue_t result = exists(key);
|
ReturnValue_t result = exists(key);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
*value = &theMap[findIndex(key)].second;
|
*value = &theMap[findIndex(key)].second;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() {
|
bool empty() {
|
||||||
if(_size == 0) {
|
if(_size == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool full() {
|
bool full() {
|
||||||
if(_size >= theMap.maxSize()) {
|
if(_size >= theMap.maxSize()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
_size = 0;
|
_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t maxSize() const {
|
uint32_t maxSize() const {
|
||||||
return theMap.maxSize();
|
return theMap.maxSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||||
size_t maxSize, Endianness streamEndianness) const {
|
size_t maxSize, Endianness streamEndianness) const {
|
||||||
ReturnValue_t result = SerializeAdapter::serialize(&this->_size,
|
ReturnValue_t result = SerializeAdapter::serialize(&this->_size,
|
||||||
buffer, size, maxSize, streamEndianness);
|
buffer, size, maxSize, streamEndianness);
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
|
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
|
||||||
result = SerializeAdapter::serialize(&theMap[i].first, buffer,
|
result = SerializeAdapter::serialize(&theMap[i].first, buffer,
|
||||||
size, maxSize, streamEndianness);
|
size, maxSize, streamEndianness);
|
||||||
result = SerializeAdapter::serialize(&theMap[i].second, buffer, size,
|
result = SerializeAdapter::serialize(&theMap[i].second, buffer, size,
|
||||||
maxSize, streamEndianness);
|
maxSize, streamEndianness);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t getSerializedSize() const {
|
virtual size_t getSerializedSize() const {
|
||||||
uint32_t printSize = sizeof(_size);
|
uint32_t printSize = sizeof(_size);
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
for (i = 0; i < _size; ++i) {
|
for (i = 0; i < _size; ++i) {
|
||||||
printSize += SerializeAdapter::getSerializedSize(
|
printSize += SerializeAdapter::getSerializedSize(
|
||||||
&theMap[i].first);
|
&theMap[i].first);
|
||||||
printSize += SerializeAdapter::getSerializedSize(&theMap[i].second);
|
printSize += SerializeAdapter::getSerializedSize(&theMap[i].second);
|
||||||
}
|
}
|
||||||
|
|
||||||
return printSize;
|
return printSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
Endianness streamEndianness) {
|
Endianness streamEndianness) {
|
||||||
ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size,
|
ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size,
|
||||||
buffer, size, streamEndianness);
|
buffer, size, streamEndianness);
|
||||||
if (this->_size > theMap.maxSize()) {
|
if (this->_size > theMap.maxSize()) {
|
||||||
return SerializeIF::TOO_MANY_ELEMENTS;
|
return SerializeIF::TOO_MANY_ELEMENTS;
|
||||||
}
|
}
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
|
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
|
||||||
result = SerializeAdapter::deSerialize(&theMap[i].first, buffer,
|
result = SerializeAdapter::deSerialize(&theMap[i].first, buffer,
|
||||||
size, streamEndianness);
|
size, streamEndianness);
|
||||||
result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size,
|
result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size,
|
||||||
streamEndianness);
|
streamEndianness);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,172 +34,172 @@
|
|||||||
template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>>
|
template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>>
|
||||||
class FixedOrderedMultimap {
|
class FixedOrderedMultimap {
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MULTIMAP;
|
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MULTIMAP;
|
||||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x01);
|
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x01);
|
||||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x02);
|
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x02);
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Constructor which needs a size_t for the maximum allowed size
|
* Constructor which needs a size_t for the maximum allowed size
|
||||||
*
|
*
|
||||||
* Can not be resized during runtime
|
* Can not be resized during runtime
|
||||||
*
|
*
|
||||||
* Allocates memory at construction
|
* Allocates memory at construction
|
||||||
* @param maxSize size_t of Maximum allowed size
|
* @param maxSize size_t of Maximum allowed size
|
||||||
*/
|
*/
|
||||||
FixedOrderedMultimap(size_t maxSize):theMap(maxSize), _size(0){
|
FixedOrderedMultimap(size_t maxSize):theMap(maxSize), _size(0){
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Virtual destructor frees Memory by deleting its member
|
* Virtual destructor frees Memory by deleting its member
|
||||||
*/
|
*/
|
||||||
virtual ~FixedOrderedMultimap() {
|
virtual ~FixedOrderedMultimap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Special iterator for FixedOrderedMultimap
|
* Special iterator for FixedOrderedMultimap
|
||||||
*/
|
*/
|
||||||
class Iterator: public ArrayList<std::pair<key_t, T>, size_t>::Iterator {
|
class Iterator: public ArrayList<std::pair<key_t, T>, size_t>::Iterator {
|
||||||
public:
|
public:
|
||||||
Iterator() :
|
Iterator() :
|
||||||
ArrayList<std::pair<key_t, T>, size_t>::Iterator() {
|
ArrayList<std::pair<key_t, T>, size_t>::Iterator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator(std::pair<key_t, T> *pair) :
|
Iterator(std::pair<key_t, T> *pair) :
|
||||||
ArrayList<std::pair<key_t, T>, size_t>::Iterator(pair) {
|
ArrayList<std::pair<key_t, T>, size_t>::Iterator(pair) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Returns an iterator pointing to the first element
|
* Returns an iterator pointing to the first element
|
||||||
* @return Iterator pointing to first element
|
* @return Iterator pointing to first element
|
||||||
*/
|
*/
|
||||||
Iterator begin() const {
|
Iterator begin() const {
|
||||||
return Iterator(&theMap[0]);
|
return Iterator(&theMap[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an iterator pointing to one element past the end
|
* Returns an iterator pointing to one element past the end
|
||||||
* @return Iterator pointing to one element past the end
|
* @return Iterator pointing to one element past the end
|
||||||
*/
|
*/
|
||||||
Iterator end() const {
|
Iterator end() const {
|
||||||
return Iterator(&theMap[_size]);
|
return Iterator(&theMap[_size]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Returns the current size of the map (not maximum size!)
|
* Returns the current size of the map (not maximum size!)
|
||||||
* @return Current size
|
* @return Current size
|
||||||
*/
|
*/
|
||||||
size_t size() const{
|
size_t size() const{
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the map, does not deallocate any memory
|
* Clears the map, does not deallocate any memory
|
||||||
*/
|
*/
|
||||||
void clear(){
|
void clear(){
|
||||||
_size = 0;
|
_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the maximum size of the map
|
* Returns the maximum size of the map
|
||||||
* @return Maximum size of the map
|
* @return Maximum size of the map
|
||||||
*/
|
*/
|
||||||
size_t maxSize() const{
|
size_t maxSize() const{
|
||||||
return theMap.maxSize();
|
return theMap.maxSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Used to insert a key and value separately.
|
* Used to insert a key and value separately.
|
||||||
*
|
*
|
||||||
* @param[in] key Key of the new element
|
* @param[in] key Key of the new element
|
||||||
* @param[in] value Value of the new element
|
* @param[in] value Value of the new element
|
||||||
* @param[in/out] (optional) storedValue On success this points to the new value, otherwise a nullptr
|
* @param[in/out] (optional) storedValue On success this points to the new value, otherwise a nullptr
|
||||||
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available
|
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr);
|
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr);
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Used to insert new pair instead of single values
|
* Used to insert new pair instead of single values
|
||||||
*
|
*
|
||||||
* @param pair Pair to be inserted
|
* @param pair Pair to be inserted
|
||||||
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available
|
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insert(std::pair<key_t, T> pair);
|
ReturnValue_t insert(std::pair<key_t, T> pair);
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Can be used to check if a certain key is in the map
|
* Can be used to check if a certain key is in the map
|
||||||
* @param key Key to be checked
|
* @param key Key to be checked
|
||||||
* @return RETURN_OK if the key exists KEY_DOES_NOT_EXIST otherwise
|
* @return RETURN_OK if the key exists KEY_DOES_NOT_EXIST otherwise
|
||||||
*/
|
*/
|
||||||
ReturnValue_t exists(key_t key) const;
|
ReturnValue_t exists(key_t key) const;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Used to delete the element in the iterator
|
* Used to delete the element in the iterator
|
||||||
*
|
*
|
||||||
* The iterator will point to the element before or begin(),
|
* The iterator will point to the element before or begin(),
|
||||||
* but never to one element in front of the map.
|
* but never to one element in front of the map.
|
||||||
*
|
*
|
||||||
* @warning The iterator needs to be valid and dereferenceable
|
* @warning The iterator needs to be valid and dereferenceable
|
||||||
* @param[in/out] iter Pointer to iterator to the element that needs to be ereased
|
* @param[in/out] iter Pointer to iterator to the element that needs to be ereased
|
||||||
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
|
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
|
||||||
*/
|
*/
|
||||||
ReturnValue_t erase(Iterator *iter);
|
ReturnValue_t erase(Iterator *iter);
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Used to erase by key
|
* Used to erase by key
|
||||||
* @param key Key to be erased
|
* @param key Key to be erased
|
||||||
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
|
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
|
||||||
*/
|
*/
|
||||||
ReturnValue_t erase(key_t key);
|
ReturnValue_t erase(key_t key);
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Find returns the first appearance of the key
|
* Find returns the first appearance of the key
|
||||||
*
|
*
|
||||||
* If the key does not exist, it points to end()
|
* If the key does not exist, it points to end()
|
||||||
*
|
*
|
||||||
* @param key Key to search for
|
* @param key Key to search for
|
||||||
* @return Iterator pointing to the first entry of key
|
* @return Iterator pointing to the first entry of key
|
||||||
*/
|
*/
|
||||||
Iterator find(key_t key) const{
|
Iterator find(key_t key) const{
|
||||||
ReturnValue_t result = exists(key);
|
ReturnValue_t result = exists(key);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
return Iterator(&theMap[findFirstIndex(key)]);
|
return Iterator(&theMap[findFirstIndex(key)]);
|
||||||
};
|
};
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Finds first entry of the given key and returns a
|
* Finds first entry of the given key and returns a
|
||||||
* pointer to the value
|
* pointer to the value
|
||||||
*
|
*
|
||||||
* @param key Key to search for
|
* @param key Key to search for
|
||||||
* @param value Found value
|
* @param value Found value
|
||||||
* @return RETURN_OK if it points to the value,
|
* @return RETURN_OK if it points to the value,
|
||||||
* KEY_DOES_NOT_EXIST if the key is not in the map
|
* KEY_DOES_NOT_EXIST if the key is not in the map
|
||||||
*/
|
*/
|
||||||
ReturnValue_t find(key_t key, T **value) const;
|
ReturnValue_t find(key_t key, T **value) const;
|
||||||
|
|
||||||
friend bool operator==(const typename FixedOrderedMultimap::Iterator& lhs,
|
friend bool operator==(const typename FixedOrderedMultimap::Iterator& lhs,
|
||||||
const typename FixedOrderedMultimap::Iterator& rhs) {
|
const typename FixedOrderedMultimap::Iterator& rhs) {
|
||||||
return (lhs.value == rhs.value);
|
return (lhs.value == rhs.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator!=(const typename FixedOrderedMultimap::Iterator& lhs,
|
friend bool operator!=(const typename FixedOrderedMultimap::Iterator& lhs,
|
||||||
const typename FixedOrderedMultimap::Iterator& rhs) {
|
const typename FixedOrderedMultimap::Iterator& rhs) {
|
||||||
return not (lhs.value == rhs.value);
|
return not (lhs.value == rhs.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef KEY_COMPARE compare;
|
typedef KEY_COMPARE compare;
|
||||||
compare myComp;
|
compare myComp;
|
||||||
ArrayList<std::pair<key_t, T>, size_t> theMap;
|
ArrayList<std::pair<key_t, T>, size_t> theMap;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
|
|
||||||
size_t findFirstIndex(key_t key, size_t startAt = 0) const;
|
size_t findFirstIndex(key_t key, size_t startAt = 0) const;
|
||||||
|
|
||||||
size_t findNicePlace(key_t key) const;
|
size_t findNicePlace(key_t key) const;
|
||||||
|
|
||||||
void removeFromPosition(size_t position);
|
void removeFromPosition(size_t position);
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "FixedOrderedMultimap.tpp"
|
#include "FixedOrderedMultimap.tpp"
|
||||||
|
@ -4,105 +4,105 @@
|
|||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(key_t key, T value, Iterator *storedValue) {
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(key_t key, T value, Iterator *storedValue) {
|
||||||
if (_size == theMap.maxSize()) {
|
if (_size == theMap.maxSize()) {
|
||||||
return MAP_FULL;
|
return MAP_FULL;
|
||||||
}
|
}
|
||||||
size_t position = findNicePlace(key);
|
size_t position = findNicePlace(key);
|
||||||
memmove(static_cast<void*>(&theMap[position + 1]),static_cast<void*>(&theMap[position]),
|
memmove(static_cast<void*>(&theMap[position + 1]),static_cast<void*>(&theMap[position]),
|
||||||
(_size - position) * sizeof(std::pair<key_t,T>));
|
(_size - position) * sizeof(std::pair<key_t,T>));
|
||||||
theMap[position].first = key;
|
theMap[position].first = key;
|
||||||
theMap[position].second = value;
|
theMap[position].second = value;
|
||||||
++_size;
|
++_size;
|
||||||
if (storedValue != nullptr) {
|
if (storedValue != nullptr) {
|
||||||
*storedValue = Iterator(&theMap[position]);
|
*storedValue = Iterator(&theMap[position]);
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(std::pair<key_t, T> pair) {
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(std::pair<key_t, T> pair) {
|
||||||
return insert(pair.first, pair.second);
|
return insert(pair.first, pair.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::exists(key_t key) const {
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::exists(key_t key) const {
|
||||||
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
||||||
if (findFirstIndex(key) < _size) {
|
if (findFirstIndex(key) < _size) {
|
||||||
result = HasReturnvaluesIF::RETURN_OK;
|
result = HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(Iterator *iter) {
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(Iterator *iter) {
|
||||||
size_t i;
|
size_t i;
|
||||||
if ((i = findFirstIndex((*iter).value->first)) >= _size) {
|
if ((i = findFirstIndex((*iter).value->first)) >= _size) {
|
||||||
return KEY_DOES_NOT_EXIST;
|
return KEY_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
removeFromPosition(i);
|
removeFromPosition(i);
|
||||||
if (*iter != begin()) {
|
if (*iter != begin()) {
|
||||||
(*iter)--;
|
(*iter)--;
|
||||||
} else {
|
} else {
|
||||||
*iter = begin();
|
*iter = begin();
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(key_t key) {
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(key_t key) {
|
||||||
size_t i;
|
size_t i;
|
||||||
if ((i = findFirstIndex(key)) >= _size) {
|
if ((i = findFirstIndex(key)) >= _size) {
|
||||||
return KEY_DOES_NOT_EXIST;
|
return KEY_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
removeFromPosition(i);
|
removeFromPosition(i);
|
||||||
i = findFirstIndex(key, i);
|
i = findFirstIndex(key, i);
|
||||||
} while (i < _size);
|
} while (i < _size);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::find(key_t key, T **value) const {
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::find(key_t key, T **value) const {
|
||||||
ReturnValue_t result = exists(key);
|
ReturnValue_t result = exists(key);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
*value = &theMap[findFirstIndex(key)].second;
|
*value = &theMap[findFirstIndex(key)].second;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findFirstIndex(key_t key, size_t startAt) const {
|
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findFirstIndex(key_t key, size_t startAt) const {
|
||||||
if (startAt >= _size) {
|
if (startAt >= _size) {
|
||||||
return startAt + 1;
|
return startAt + 1;
|
||||||
}
|
}
|
||||||
size_t i = startAt;
|
size_t i = startAt;
|
||||||
for (i = startAt; i < _size; ++i) {
|
for (i = startAt; i < _size; ++i) {
|
||||||
if (theMap[i].first == key) {
|
if (theMap[i].first == key) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findNicePlace(key_t key) const {
|
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findNicePlace(key_t key) const {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (i = 0; i < _size; ++i) {
|
for (i = 0; i < _size; ++i) {
|
||||||
if (myComp(key, theMap[i].first)) {
|
if (myComp(key, theMap[i].first)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline void FixedOrderedMultimap<key_t, T, KEY_COMPARE>::removeFromPosition(size_t position) {
|
inline void FixedOrderedMultimap<key_t, T, KEY_COMPARE>::removeFromPosition(size_t position) {
|
||||||
if (_size <= position) {
|
if (_size <= position) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memmove(static_cast<void*>(&theMap[position]), static_cast<void*>(&theMap[position + 1]),
|
memmove(static_cast<void*>(&theMap[position]), static_cast<void*>(&theMap[position + 1]),
|
||||||
(_size - position - 1) * sizeof(std::pair<key_t,T>));
|
(_size - position - 1) * sizeof(std::pair<key_t,T>));
|
||||||
--_size;
|
--_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,85 +6,85 @@
|
|||||||
|
|
||||||
template<typename T, typename count_t = uint8_t>
|
template<typename T, typename count_t = uint8_t>
|
||||||
class HybridIterator: public LinkedElement<T>::Iterator,
|
class HybridIterator: public LinkedElement<T>::Iterator,
|
||||||
public ArrayList<T, count_t>::Iterator {
|
public ArrayList<T, count_t>::Iterator {
|
||||||
public:
|
public:
|
||||||
HybridIterator() {}
|
HybridIterator() {}
|
||||||
|
|
||||||
HybridIterator(typename LinkedElement<T>::Iterator *iter) :
|
HybridIterator(typename LinkedElement<T>::Iterator *iter) :
|
||||||
LinkedElement<T>::Iterator(*iter), value(iter->value),
|
LinkedElement<T>::Iterator(*iter), value(iter->value),
|
||||||
linked(true) {
|
linked(true) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HybridIterator(LinkedElement<T> *start) :
|
HybridIterator(LinkedElement<T> *start) :
|
||||||
LinkedElement<T>::Iterator(start), value(start->value),
|
LinkedElement<T>::Iterator(start), value(start->value),
|
||||||
linked(true) {
|
linked(true) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HybridIterator(typename ArrayList<T, count_t>::Iterator start,
|
HybridIterator(typename ArrayList<T, count_t>::Iterator start,
|
||||||
typename ArrayList<T, count_t>::Iterator end) :
|
typename ArrayList<T, count_t>::Iterator end) :
|
||||||
ArrayList<T, count_t>::Iterator(start), value(start.value),
|
ArrayList<T, count_t>::Iterator(start), value(start.value),
|
||||||
linked(false), end(end.value) {
|
linked(false), end(end.value) {
|
||||||
if (value == this->end) {
|
if (value == this->end) {
|
||||||
value = NULL;
|
value = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HybridIterator(T *firstElement, T *lastElement) :
|
HybridIterator(T *firstElement, T *lastElement) :
|
||||||
ArrayList<T, count_t>::Iterator(firstElement), value(firstElement),
|
ArrayList<T, count_t>::Iterator(firstElement), value(firstElement),
|
||||||
linked(false), end(++lastElement) {
|
linked(false), end(++lastElement) {
|
||||||
if (value == end) {
|
if (value == end) {
|
||||||
value = NULL;
|
value = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HybridIterator& operator++() {
|
HybridIterator& operator++() {
|
||||||
if (linked) {
|
if (linked) {
|
||||||
LinkedElement<T>::Iterator::operator++();
|
LinkedElement<T>::Iterator::operator++();
|
||||||
if (LinkedElement<T>::Iterator::value != nullptr) {
|
if (LinkedElement<T>::Iterator::value != nullptr) {
|
||||||
value = LinkedElement<T>::Iterator::value->value;
|
value = LinkedElement<T>::Iterator::value->value;
|
||||||
} else {
|
} else {
|
||||||
value = nullptr;
|
value = nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ArrayList<T, count_t>::Iterator::operator++();
|
ArrayList<T, count_t>::Iterator::operator++();
|
||||||
value = ArrayList<T, count_t>::Iterator::value;
|
value = ArrayList<T, count_t>::Iterator::value;
|
||||||
|
|
||||||
if (value == end) {
|
if (value == end) {
|
||||||
value = nullptr;
|
value = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
HybridIterator operator++(int) {
|
HybridIterator operator++(int) {
|
||||||
HybridIterator tmp(*this);
|
HybridIterator tmp(*this);
|
||||||
operator++();
|
operator++();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const HybridIterator& other) const {
|
bool operator==(const HybridIterator& other) const {
|
||||||
return value == other.value;
|
return value == other.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const HybridIterator& other) const {
|
bool operator!=(const HybridIterator& other) const {
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
T operator*() {
|
T operator*() {
|
||||||
return *value;
|
return *value;
|
||||||
}
|
}
|
||||||
|
|
||||||
T *operator->() {
|
T *operator->() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* value = nullptr;
|
T* value = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool linked = false;
|
bool linked = false;
|
||||||
T *end = nullptr;
|
T *end = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ */
|
#endif /* FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -22,50 +22,50 @@
|
|||||||
*/
|
*/
|
||||||
class PlacementFactory {
|
class PlacementFactory {
|
||||||
public:
|
public:
|
||||||
PlacementFactory(StorageManagerIF* backend) :
|
PlacementFactory(StorageManagerIF* backend) :
|
||||||
dataBackend(backend) {
|
dataBackend(backend) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Generates an object of type T in the backend storage.
|
* Generates an object of type T in the backend storage.
|
||||||
*
|
*
|
||||||
* @warning Do not use with any Type that allocates memory internally!
|
* @warning Do not use with any Type that allocates memory internally!
|
||||||
*
|
*
|
||||||
* @tparam T Type of Object
|
* @tparam T Type of Object
|
||||||
* @param args Constructor Arguments to be passed
|
* @param args Constructor Arguments to be passed
|
||||||
* @return A pointer to the new object or a nullptr in case of failure
|
* @return A pointer to the new object or a nullptr in case of failure
|
||||||
*/
|
*/
|
||||||
template<typename T, typename ... Args>
|
template<typename T, typename ... Args>
|
||||||
T* generate(Args&&... args) {
|
T* generate(Args&&... args) {
|
||||||
store_address_t tempId;
|
store_address_t tempId;
|
||||||
uint8_t* pData = nullptr;
|
uint8_t* pData = nullptr;
|
||||||
ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T),
|
ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T),
|
||||||
&pData);
|
&pData);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
T* temp = new (pData) T(std::forward<Args>(args)...);
|
T* temp = new (pData) T(std::forward<Args>(args)...);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
/***
|
/***
|
||||||
* Function to destroy the object allocated with generate and free space in backend.
|
* Function to destroy the object allocated with generate and free space in backend.
|
||||||
* This must be called by the user.
|
* This must be called by the user.
|
||||||
*
|
*
|
||||||
* @param thisElement Element to be destroyed
|
* @param thisElement Element to be destroyed
|
||||||
* @return RETURN_OK if the element was destroyed, different errors on failure
|
* @return RETURN_OK if the element was destroyed, different errors on failure
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ReturnValue_t destroy(T* thisElement) {
|
ReturnValue_t destroy(T* thisElement) {
|
||||||
if (thisElement == nullptr){
|
if (thisElement == nullptr){
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
//Need to call destructor first, in case something was allocated by the object (shouldn't do that, however).
|
//Need to call destructor first, in case something was allocated by the object (shouldn't do that, however).
|
||||||
thisElement->~T();
|
thisElement->~T();
|
||||||
uint8_t* pointer = (uint8_t*) (thisElement);
|
uint8_t* pointer = (uint8_t*) (thisElement);
|
||||||
return dataBackend->deleteData(pointer, sizeof(T));
|
return dataBackend->deleteData(pointer, sizeof(T));
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
StorageManagerIF* dataBackend;
|
StorageManagerIF* dataBackend;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_ */
|
#endif /* FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_ */
|
||||||
|
@ -7,107 +7,107 @@
|
|||||||
template<uint8_t N_READ_PTRS = 1>
|
template<uint8_t N_READ_PTRS = 1>
|
||||||
class RingBufferBase {
|
class RingBufferBase {
|
||||||
public:
|
public:
|
||||||
RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) :
|
RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) :
|
||||||
start(startAddress), write(startAddress), size(size),
|
start(startAddress), write(startAddress), size(size),
|
||||||
overwriteOld(overwriteOld) {
|
overwriteOld(overwriteOld) {
|
||||||
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
|
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
|
||||||
read[count] = startAddress;
|
read[count] = startAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~RingBufferBase() {}
|
virtual ~RingBufferBase() {}
|
||||||
|
|
||||||
bool isFull(uint8_t n = 0) {
|
bool isFull(uint8_t n = 0) {
|
||||||
return (availableWriteSpace(n) == 0);
|
return (availableWriteSpace(n) == 0);
|
||||||
}
|
}
|
||||||
bool isEmpty(uint8_t n = 0) {
|
bool isEmpty(uint8_t n = 0) {
|
||||||
return (getAvailableReadData(n) == 0);
|
return (getAvailableReadData(n) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getAvailableReadData(uint8_t n = 0) const {
|
size_t getAvailableReadData(uint8_t n = 0) const {
|
||||||
return ((write + size) - read[n]) % size;
|
return ((write + size) - read[n]) % size;
|
||||||
}
|
}
|
||||||
size_t availableWriteSpace(uint8_t n = 0) const {
|
size_t availableWriteSpace(uint8_t n = 0) const {
|
||||||
//One less to avoid ambiguous full/empty problem.
|
//One less to avoid ambiguous full/empty problem.
|
||||||
return (((read[n] + size) - write - 1) % size);
|
return (((read[n] + size) - write - 1) % size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool overwritesOld() const {
|
bool overwritesOld() const {
|
||||||
return overwriteOld;
|
return overwriteOld;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getMaxSize() const {
|
size_t getMaxSize() const {
|
||||||
return size - 1;
|
return size - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
write = start;
|
write = start;
|
||||||
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
|
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
|
||||||
read[count] = start;
|
read[count] = start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t writeTillWrap() {
|
size_t writeTillWrap() {
|
||||||
return (start + size) - write;
|
return (start + size) - write;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readTillWrap(uint8_t n = 0) {
|
size_t readTillWrap(uint8_t n = 0) {
|
||||||
return (start + size) - read[n];
|
return (start + size) - read[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getStart() const {
|
size_t getStart() const {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const size_t start;
|
const size_t start;
|
||||||
size_t write;
|
size_t write;
|
||||||
size_t read[N_READ_PTRS];
|
size_t read[N_READ_PTRS];
|
||||||
const size_t size;
|
const size_t size;
|
||||||
const bool overwriteOld;
|
const bool overwriteOld;
|
||||||
|
|
||||||
void incrementWrite(uint32_t amount) {
|
void incrementWrite(uint32_t amount) {
|
||||||
write = ((write + amount - start) % size) + start;
|
write = ((write + amount - start) % size) + start;
|
||||||
}
|
}
|
||||||
void incrementRead(uint32_t amount, uint8_t n = 0) {
|
void incrementRead(uint32_t amount, uint8_t n = 0) {
|
||||||
read[n] = ((read[n] + amount - start) % size) + start;
|
read[n] = ((read[n] + amount - start) % size) + start;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t readData(uint32_t amount, uint8_t n = 0) {
|
ReturnValue_t readData(uint32_t amount, uint8_t n = 0) {
|
||||||
if (getAvailableReadData(n) >= amount) {
|
if (getAvailableReadData(n) >= amount) {
|
||||||
incrementRead(amount, n);
|
incrementRead(amount, n);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t writeData(uint32_t amount) {
|
ReturnValue_t writeData(uint32_t amount) {
|
||||||
if (availableWriteSpace() >= amount or overwriteOld) {
|
if (availableWriteSpace() >= amount or overwriteOld) {
|
||||||
incrementWrite(amount);
|
incrementWrite(amount);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getRead(uint8_t n = 0) const {
|
size_t getRead(uint8_t n = 0) const {
|
||||||
return read[n];
|
return read[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRead(uint32_t read, uint8_t n = 0) {
|
void setRead(uint32_t read, uint8_t n = 0) {
|
||||||
if (read >= start && read < (start+size)) {
|
if (read >= start && read < (start+size)) {
|
||||||
this->read[n] = read;
|
this->read[n] = read;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getWrite() const {
|
uint32_t getWrite() const {
|
||||||
return write;
|
return write;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWrite(uint32_t write) {
|
void setWrite(uint32_t write) {
|
||||||
this->write = write;
|
this->write = write;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CONTAINER_RINGBUFFERBASE_H_ */
|
#endif /* FSFW_CONTAINER_RINGBUFFERBASE_H_ */
|
||||||
|
@ -3,23 +3,23 @@
|
|||||||
#include "../ipc/MutexHelper.h"
|
#include "../ipc/MutexHelper.h"
|
||||||
|
|
||||||
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size,
|
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size,
|
||||||
bool overwriteOld, size_t maxExcessBytes):
|
bool overwriteOld, size_t maxExcessBytes):
|
||||||
SystemObject(objectId), SimpleRingBuffer(size, overwriteOld,
|
SystemObject(objectId), SimpleRingBuffer(size, overwriteOld,
|
||||||
maxExcessBytes) {
|
maxExcessBytes) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
|
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
|
||||||
const size_t size, bool overwriteOld, size_t maxExcessBytes):
|
const size_t size, bool overwriteOld, size_t maxExcessBytes):
|
||||||
SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld,
|
SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld,
|
||||||
maxExcessBytes) {
|
maxExcessBytes) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) {
|
void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) {
|
||||||
this->fifoDepth = fifoDepth;
|
this->fifoDepth = fifoDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SharedRingBuffer::lockRingBufferMutex(
|
ReturnValue_t SharedRingBuffer::lockRingBufferMutex(
|
||||||
@ -38,20 +38,20 @@ MutexIF* SharedRingBuffer::getMutexHandle() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SharedRingBuffer::initialize() {
|
ReturnValue_t SharedRingBuffer::initialize() {
|
||||||
if(fifoDepth > 0) {
|
if(fifoDepth > 0) {
|
||||||
receiveSizesFIFO = new DynamicFIFO<size_t>(fifoDepth);
|
receiveSizesFIFO = new DynamicFIFO<size_t>(fifoDepth);
|
||||||
}
|
}
|
||||||
return SystemObject::initialize();
|
return SystemObject::initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFIFO() {
|
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFIFO() {
|
||||||
if(receiveSizesFIFO == nullptr) {
|
if(receiveSizesFIFO == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer"
|
sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer"
|
||||||
<< " was not configured to have sizes FIFO, returning nullptr!"
|
<< " was not configured to have sizes FIFO, returning nullptr!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return receiveSizesFIFO;
|
return receiveSizesFIFO;
|
||||||
}
|
}
|
||||||
|
@ -15,76 +15,76 @@
|
|||||||
* and unlock operations.
|
* and unlock operations.
|
||||||
*/
|
*/
|
||||||
class SharedRingBuffer: public SystemObject,
|
class SharedRingBuffer: public SystemObject,
|
||||||
public SimpleRingBuffer {
|
public SimpleRingBuffer {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* This constructor allocates a new internal buffer with the supplied size.
|
* This constructor allocates a new internal buffer with the supplied size.
|
||||||
* @param size
|
* @param size
|
||||||
* @param overwriteOld
|
* @param overwriteOld
|
||||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||||
* will be overwritten.
|
* will be overwritten.
|
||||||
*/
|
*/
|
||||||
SharedRingBuffer(object_id_t objectId, const size_t size,
|
SharedRingBuffer(object_id_t objectId, const size_t size,
|
||||||
bool overwriteOld, size_t maxExcessBytes);
|
bool overwriteOld, size_t maxExcessBytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function can be used to add an optional FIFO to the class
|
* @brief This function can be used to add an optional FIFO to the class
|
||||||
* @details
|
* @details
|
||||||
* This FIFO will be allocated in the initialize function (and will
|
* This FIFO will be allocated in the initialize function (and will
|
||||||
* have a fixed maximum size after that). It can be used to store
|
* have a fixed maximum size after that). It can be used to store
|
||||||
* values like packet sizes, for example for a shared ring buffer
|
* values like packet sizes, for example for a shared ring buffer
|
||||||
* used by producer/consumer tasks.
|
* used by producer/consumer tasks.
|
||||||
*/
|
*/
|
||||||
void setToUseReceiveSizeFIFO(size_t fifoDepth);
|
void setToUseReceiveSizeFIFO(size_t fifoDepth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor takes an external buffer with the specified size.
|
* This constructor takes an external buffer with the specified size.
|
||||||
* @param buffer
|
* @param buffer
|
||||||
* @param size
|
* @param size
|
||||||
* @param overwriteOld
|
* @param overwriteOld
|
||||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||||
* will be overwritten.
|
* will be overwritten.
|
||||||
*/
|
*/
|
||||||
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
|
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
|
||||||
bool overwriteOld, size_t maxExcessBytes);
|
bool overwriteOld, size_t maxExcessBytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unless a read-only constant value is read, all operations on the
|
* Unless a read-only constant value is read, all operations on the
|
||||||
* shared ring buffer should be protected by calling this function.
|
* shared ring buffer should be protected by calling this function.
|
||||||
* @param timeoutType
|
* @param timeoutType
|
||||||
* @param timeout
|
* @param timeout
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t lockRingBufferMutex(MutexIF::TimeoutType timeoutType,
|
virtual ReturnValue_t lockRingBufferMutex(MutexIF::TimeoutType timeoutType,
|
||||||
dur_millis_t timeout);
|
dur_millis_t timeout);
|
||||||
/**
|
/**
|
||||||
* Any locked mutex also has to be unlocked, otherwise, access to the
|
* Any locked mutex also has to be unlocked, otherwise, access to the
|
||||||
* shared ring buffer will be blocked.
|
* shared ring buffer will be blocked.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t unlockRingBufferMutex();
|
virtual ReturnValue_t unlockRingBufferMutex();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The mutex handle can be accessed directly, for example to perform
|
* The mutex handle can be accessed directly, for example to perform
|
||||||
* the lock with the #MutexHelper for a RAII compliant lock operation.
|
* the lock with the #MutexHelper for a RAII compliant lock operation.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
MutexIF* getMutexHandle() const;
|
MutexIF* getMutexHandle() const;
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the shared ring buffer was configured to have a sizes FIFO, a handle
|
* If the shared ring buffer was configured to have a sizes FIFO, a handle
|
||||||
* to that FIFO can be retrieved with this function.
|
* to that FIFO can be retrieved with this function.
|
||||||
* Do not forget to protect access with a lock if required!
|
* Do not forget to protect access with a lock if required!
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
DynamicFIFO<size_t>* getReceiveSizesFIFO();
|
DynamicFIFO<size_t>* getReceiveSizesFIFO();
|
||||||
private:
|
private:
|
||||||
MutexIF* mutex = nullptr;
|
MutexIF* mutex = nullptr;
|
||||||
|
|
||||||
size_t fifoDepth = 0;
|
size_t fifoDepth = 0;
|
||||||
DynamicFIFO<size_t>* receiveSizesFIFO = nullptr;
|
DynamicFIFO<size_t>* receiveSizesFIFO = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,31 +2,31 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld,
|
SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld,
|
||||||
size_t maxExcessBytes) :
|
size_t maxExcessBytes) :
|
||||||
RingBufferBase<>(0, size, overwriteOld),
|
RingBufferBase<>(0, size, overwriteOld),
|
||||||
maxExcessBytes(maxExcessBytes) {
|
maxExcessBytes(maxExcessBytes) {
|
||||||
if(maxExcessBytes > size) {
|
if(maxExcessBytes > size) {
|
||||||
this->maxExcessBytes = size;
|
this->maxExcessBytes = size;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this->maxExcessBytes = maxExcessBytes;
|
this->maxExcessBytes = maxExcessBytes;
|
||||||
}
|
}
|
||||||
buffer = new uint8_t[size + maxExcessBytes];
|
buffer = new uint8_t[size + maxExcessBytes];
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size,
|
SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size,
|
||||||
bool overwriteOld, size_t maxExcessBytes):
|
bool overwriteOld, size_t maxExcessBytes):
|
||||||
RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {
|
RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {
|
||||||
if(maxExcessBytes > size) {
|
if(maxExcessBytes > size) {
|
||||||
this->maxExcessBytes = size;
|
this->maxExcessBytes = size;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this->maxExcessBytes = maxExcessBytes;
|
this->maxExcessBytes = maxExcessBytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleRingBuffer::~SimpleRingBuffer() {
|
SimpleRingBuffer::~SimpleRingBuffer() {
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
|
ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
|
||||||
@ -48,58 +48,58 @@ ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SimpleRingBuffer::confirmBytesWritten(size_t amount) {
|
void SimpleRingBuffer::confirmBytesWritten(size_t amount) {
|
||||||
if(getExcessBytes() > 0) {
|
if(getExcessBytes() > 0) {
|
||||||
moveExcessBytesToStart();
|
moveExcessBytesToStart();
|
||||||
}
|
}
|
||||||
incrementWrite(amount);
|
incrementWrite(amount);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data,
|
ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data,
|
||||||
size_t amount) {
|
size_t amount) {
|
||||||
if (availableWriteSpace() >= amount or overwriteOld) {
|
if (availableWriteSpace() >= amount or overwriteOld) {
|
||||||
size_t amountTillWrap = writeTillWrap();
|
size_t amountTillWrap = writeTillWrap();
|
||||||
if (amountTillWrap >= amount) {
|
if (amountTillWrap >= amount) {
|
||||||
// remaining size in buffer is sufficient to fit full amount.
|
// remaining size in buffer is sufficient to fit full amount.
|
||||||
memcpy(&buffer[write], data, amount);
|
memcpy(&buffer[write], data, amount);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy(&buffer[write], data, amountTillWrap);
|
memcpy(&buffer[write], data, amountTillWrap);
|
||||||
memcpy(buffer, data + amountTillWrap, amount - amountTillWrap);
|
memcpy(buffer, data + amountTillWrap, amount - amountTillWrap);
|
||||||
}
|
}
|
||||||
incrementWrite(amount);
|
incrementWrite(amount);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount,
|
ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount,
|
||||||
bool incrementReadPtr, bool readRemaining, size_t* trueAmount) {
|
bool incrementReadPtr, bool readRemaining, size_t* trueAmount) {
|
||||||
size_t availableData = getAvailableReadData(READ_PTR);
|
size_t availableData = getAvailableReadData(READ_PTR);
|
||||||
size_t amountTillWrap = readTillWrap(READ_PTR);
|
size_t amountTillWrap = readTillWrap(READ_PTR);
|
||||||
if (availableData < amount) {
|
if (availableData < amount) {
|
||||||
if (readRemaining) {
|
if (readRemaining) {
|
||||||
// more data available than amount specified.
|
// more data available than amount specified.
|
||||||
amount = availableData;
|
amount = availableData;
|
||||||
} else {
|
} else {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (trueAmount != nullptr) {
|
if (trueAmount != nullptr) {
|
||||||
*trueAmount = amount;
|
*trueAmount = amount;
|
||||||
}
|
}
|
||||||
if (amountTillWrap >= amount) {
|
if (amountTillWrap >= amount) {
|
||||||
memcpy(data, &buffer[read[READ_PTR]], amount);
|
memcpy(data, &buffer[read[READ_PTR]], amount);
|
||||||
} else {
|
} else {
|
||||||
memcpy(data, &buffer[read[READ_PTR]], amountTillWrap);
|
memcpy(data, &buffer[read[READ_PTR]], amountTillWrap);
|
||||||
memcpy(data + amountTillWrap, buffer, amount - amountTillWrap);
|
memcpy(data + amountTillWrap, buffer, amount - amountTillWrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(incrementReadPtr) {
|
if(incrementReadPtr) {
|
||||||
deleteData(amount, readRemaining);
|
deleteData(amount, readRemaining);
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SimpleRingBuffer::getExcessBytes() const {
|
size_t SimpleRingBuffer::getExcessBytes() const {
|
||||||
@ -114,18 +114,18 @@ void SimpleRingBuffer::moveExcessBytesToStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SimpleRingBuffer::deleteData(size_t amount,
|
ReturnValue_t SimpleRingBuffer::deleteData(size_t amount,
|
||||||
bool deleteRemaining, size_t* trueAmount) {
|
bool deleteRemaining, size_t* trueAmount) {
|
||||||
size_t availableData = getAvailableReadData(READ_PTR);
|
size_t availableData = getAvailableReadData(READ_PTR);
|
||||||
if (availableData < amount) {
|
if (availableData < amount) {
|
||||||
if (deleteRemaining) {
|
if (deleteRemaining) {
|
||||||
amount = availableData;
|
amount = availableData;
|
||||||
} else {
|
} else {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (trueAmount != nullptr) {
|
if (trueAmount != nullptr) {
|
||||||
*trueAmount = amount;
|
*trueAmount = amount;
|
||||||
}
|
}
|
||||||
incrementRead(amount, READ_PTR);
|
incrementRead(amount, READ_PTR);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Circular buffer implementation, useful for buffering
|
* @brief Circular buffer implementation, useful for buffering
|
||||||
* into data streams.
|
* into data streams.
|
||||||
* @details
|
* @details
|
||||||
* Note that the deleteData() has to be called to increment the read pointer.
|
* Note that the deleteData() has to be called to increment the read pointer.
|
||||||
@ -25,104 +25,104 @@ public:
|
|||||||
* with getFreeElement.
|
* with getFreeElement.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
SimpleRingBuffer(const size_t size, bool overwriteOld,
|
SimpleRingBuffer(const size_t size, bool overwriteOld,
|
||||||
size_t maxExcessBytes = 0);
|
size_t maxExcessBytes = 0);
|
||||||
/**
|
/**
|
||||||
* This constructor takes an external buffer with the specified size.
|
* This constructor takes an external buffer with the specified size.
|
||||||
* @param buffer
|
* @param buffer
|
||||||
* @param size
|
* @param size
|
||||||
* @param overwriteOld
|
* @param overwriteOld
|
||||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||||
* will be overwritten.
|
* will be overwritten.
|
||||||
* @param maxExcessBytes
|
* @param maxExcessBytes
|
||||||
* If the buffer can accomodate additional bytes for contigous write
|
* If the buffer can accomodate additional bytes for contigous write
|
||||||
* operations with getFreeElement, this is the maximum allowed additional
|
* operations with getFreeElement, this is the maximum allowed additional
|
||||||
* size
|
* size
|
||||||
*/
|
*/
|
||||||
SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld,
|
SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld,
|
||||||
size_t maxExcessBytes = 0);
|
size_t maxExcessBytes = 0);
|
||||||
|
|
||||||
virtual ~SimpleRingBuffer();
|
virtual ~SimpleRingBuffer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write to circular buffer and increment write pointer by amount.
|
* Write to circular buffer and increment write pointer by amount.
|
||||||
* @param data
|
* @param data
|
||||||
* @param amount
|
* @param amount
|
||||||
* @return -@c RETURN_OK if write operation was successfull
|
* @return -@c RETURN_OK if write operation was successfull
|
||||||
* -@c RETURN_FAILED if
|
* -@c RETURN_FAILED if
|
||||||
*/
|
*/
|
||||||
ReturnValue_t writeData(const uint8_t* data, size_t amount);
|
ReturnValue_t writeData(const uint8_t* data, size_t amount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a pointer to a free element. If the remaining buffer is
|
* Returns a pointer to a free element. If the remaining buffer is
|
||||||
* not large enough, the data will be written past the actual size
|
* not large enough, the data will be written past the actual size
|
||||||
* and the amount of excess bytes will be cached. This function
|
* and the amount of excess bytes will be cached. This function
|
||||||
* does not increment the write pointer!
|
* does not increment the write pointer!
|
||||||
* @param writePointer Pointer to a pointer which can be used to write
|
* @param writePointer Pointer to a pointer which can be used to write
|
||||||
* contiguous blocks into the ring buffer
|
* contiguous blocks into the ring buffer
|
||||||
* @param amount
|
* @param amount
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount);
|
ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This increments the write pointer and also copies the excess bytes
|
* This increments the write pointer and also copies the excess bytes
|
||||||
* to the beginning. It should be called if the write operation
|
* to the beginning. It should be called if the write operation
|
||||||
* conducted after calling getFreeElement() was performed.
|
* conducted after calling getFreeElement() was performed.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
void confirmBytesWritten(size_t amount);
|
void confirmBytesWritten(size_t amount);
|
||||||
|
|
||||||
virtual size_t getExcessBytes() const;
|
virtual size_t getExcessBytes() const;
|
||||||
/**
|
/**
|
||||||
* Helper functions which moves any excess bytes to the start
|
* Helper functions which moves any excess bytes to the start
|
||||||
* of the ring buffer.
|
* of the ring buffer.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual void moveExcessBytesToStart();
|
virtual void moveExcessBytesToStart();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read from circular buffer at read pointer.
|
* Read from circular buffer at read pointer.
|
||||||
* @param data
|
* @param data
|
||||||
* @param amount
|
* @param amount
|
||||||
* @param incrementReadPtr
|
* @param incrementReadPtr
|
||||||
* If this is set to true, the read pointer will be incremented.
|
* If this is set to true, the read pointer will be incremented.
|
||||||
* If readRemaining is set to true, the read pointer will be incremented
|
* If readRemaining is set to true, the read pointer will be incremented
|
||||||
* accordingly.
|
* accordingly.
|
||||||
* @param readRemaining
|
* @param readRemaining
|
||||||
* If this is set to true, the data will be read even if the amount
|
* If this is set to true, the data will be read even if the amount
|
||||||
* specified exceeds the read data available.
|
* specified exceeds the read data available.
|
||||||
* @param trueAmount [out]
|
* @param trueAmount [out]
|
||||||
* If readRemaining was set to true, the true amount read will be assigned
|
* If readRemaining was set to true, the true amount read will be assigned
|
||||||
* to the passed value.
|
* to the passed value.
|
||||||
* @return
|
* @return
|
||||||
* - @c RETURN_OK if data was read successfully
|
* - @c RETURN_OK if data was read successfully
|
||||||
* - @c RETURN_FAILED if not enough data was available and readRemaining
|
* - @c RETURN_FAILED if not enough data was available and readRemaining
|
||||||
* was set to false.
|
* was set to false.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t readData(uint8_t* data, size_t amount,
|
ReturnValue_t readData(uint8_t* data, size_t amount,
|
||||||
bool incrementReadPtr = false, bool readRemaining = false,
|
bool incrementReadPtr = false, bool readRemaining = false,
|
||||||
size_t* trueAmount = nullptr);
|
size_t* trueAmount = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete data by incrementing read pointer.
|
* Delete data by incrementing read pointer.
|
||||||
* @param amount
|
* @param amount
|
||||||
* @param deleteRemaining
|
* @param deleteRemaining
|
||||||
* If the amount specified is larger than the remaing size to read and this
|
* If the amount specified is larger than the remaing size to read and this
|
||||||
* is set to true, the remaining amount will be deleted as well
|
* is set to true, the remaining amount will be deleted as well
|
||||||
* @param trueAmount [out]
|
* @param trueAmount [out]
|
||||||
* If deleteRemaining was set to true, the amount deleted will be assigned
|
* If deleteRemaining was set to true, the amount deleted will be assigned
|
||||||
* to the passed value.
|
* to the passed value.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false,
|
ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false,
|
||||||
size_t* trueAmount = nullptr);
|
size_t* trueAmount = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint8_t READ_PTR = 0;
|
static const uint8_t READ_PTR = 0;
|
||||||
uint8_t* buffer = nullptr;
|
uint8_t* buffer = nullptr;
|
||||||
size_t maxExcessBytes;
|
size_t maxExcessBytes;
|
||||||
size_t excessBytes = 0;
|
size_t excessBytes = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CONTAINER_SIMPLERINGBUFFER_H_ */
|
#endif /* FSFW_CONTAINER_SIMPLERINGBUFFER_H_ */
|
||||||
|
@ -5,71 +5,71 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Linked list data structure,
|
* @brief Linked list data structure,
|
||||||
* each entry has a pointer to the next entry (singly)
|
* each entry has a pointer to the next entry (singly)
|
||||||
* @ingroup container
|
* @ingroup container
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class LinkedElement {
|
class LinkedElement {
|
||||||
public:
|
public:
|
||||||
T *value;
|
T *value;
|
||||||
class Iterator {
|
class Iterator {
|
||||||
public:
|
public:
|
||||||
LinkedElement<T> *value = nullptr;
|
LinkedElement<T> *value = nullptr;
|
||||||
Iterator() {}
|
Iterator() {}
|
||||||
|
|
||||||
Iterator(LinkedElement<T> *element) :
|
Iterator(LinkedElement<T> *element) :
|
||||||
value(element) {
|
value(element) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator& operator++() {
|
Iterator& operator++() {
|
||||||
value = value->getNext();
|
value = value->getNext();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator operator++(int) {
|
Iterator operator++(int) {
|
||||||
Iterator tmp(*this);
|
Iterator tmp(*this);
|
||||||
operator++();
|
operator++();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(Iterator other) {
|
bool operator==(Iterator other) {
|
||||||
return value == other.value;
|
return value == other.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(Iterator other) {
|
bool operator!=(Iterator other) {
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
T *operator->() {
|
T *operator->() {
|
||||||
return value->value;
|
return value->value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
LinkedElement(T* setElement, LinkedElement<T>* setNext = nullptr):
|
LinkedElement(T* setElement, LinkedElement<T>* setNext = nullptr):
|
||||||
value(setElement), next(setNext) {}
|
value(setElement), next(setNext) {}
|
||||||
|
|
||||||
virtual ~LinkedElement(){}
|
virtual ~LinkedElement(){}
|
||||||
|
|
||||||
virtual LinkedElement* getNext() const {
|
virtual LinkedElement* getNext() const {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setNext(LinkedElement* next) {
|
virtual void setNext(LinkedElement* next) {
|
||||||
this->next = next;
|
this->next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setEnd() {
|
virtual void setEnd() {
|
||||||
this->next = nullptr;
|
this->next = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkedElement* begin() {
|
LinkedElement* begin() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
LinkedElement* end() {
|
LinkedElement* end() {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
LinkedElement *next;
|
LinkedElement *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -77,52 +77,52 @@ class SinglyLinkedList {
|
|||||||
public:
|
public:
|
||||||
using ElementIterator = typename LinkedElement<T>::Iterator;
|
using ElementIterator = typename LinkedElement<T>::Iterator;
|
||||||
|
|
||||||
SinglyLinkedList() {}
|
SinglyLinkedList() {}
|
||||||
|
|
||||||
SinglyLinkedList(ElementIterator start) :
|
SinglyLinkedList(ElementIterator start) :
|
||||||
start(start.value) {}
|
start(start.value) {}
|
||||||
|
|
||||||
SinglyLinkedList(LinkedElement<T>* startElement) :
|
SinglyLinkedList(LinkedElement<T>* startElement) :
|
||||||
start(startElement) {}
|
start(startElement) {}
|
||||||
|
|
||||||
ElementIterator begin() const {
|
ElementIterator begin() const {
|
||||||
return ElementIterator::Iterator(start);
|
return ElementIterator::Iterator(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns iterator to nulltr */
|
/** Returns iterator to nulltr */
|
||||||
ElementIterator end() const {
|
ElementIterator end() const {
|
||||||
return ElementIterator::Iterator();
|
return ElementIterator::Iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns last element in singly linked list.
|
* Returns last element in singly linked list.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ElementIterator back() const {
|
ElementIterator back() const {
|
||||||
LinkedElement<T> *element = start;
|
LinkedElement<T> *element = start;
|
||||||
while (element->getNext() != nullptr) {
|
while (element->getNext() != nullptr) {
|
||||||
element = element->getNext();
|
element = element->getNext();
|
||||||
}
|
}
|
||||||
return ElementIterator::Iterator(element);
|
return ElementIterator::Iterator(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getSize() const {
|
size_t getSize() const {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
LinkedElement<T> *element = start;
|
LinkedElement<T> *element = start;
|
||||||
while (element != nullptr) {
|
while (element != nullptr) {
|
||||||
size++;
|
size++;
|
||||||
element = element->getNext();
|
element = element->getNext();
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
void setStart(LinkedElement<T>* firstElement) {
|
void setStart(LinkedElement<T>* firstElement) {
|
||||||
start = firstElement;
|
start = firstElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNext(LinkedElement<T>* currentElement,
|
void setNext(LinkedElement<T>* currentElement,
|
||||||
LinkedElement<T>* nextElement) {
|
LinkedElement<T>* nextElement) {
|
||||||
currentElement->setNext(nextElement);
|
currentElement->setNext(nextElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLast(LinkedElement<T>* lastElement) {
|
void setLast(LinkedElement<T>* lastElement) {
|
||||||
lastElement->setEnd();
|
lastElement->setEnd();
|
||||||
@ -148,7 +148,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LinkedElement<T> *start = nullptr;
|
LinkedElement<T> *start = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SINGLYLINKEDLIST_H_ */
|
#endif /* SINGLYLINKEDLIST_H_ */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
target_sources(${LIB_FSFW_NAME}
|
target_sources(${LIB_FSFW_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
ControllerBase.cpp
|
ControllerBase.cpp
|
||||||
)
|
)
|
@ -5,128 +5,128 @@
|
|||||||
#include "../action/HasActionsIF.h"
|
#include "../action/HasActionsIF.h"
|
||||||
|
|
||||||
ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
||||||
size_t commandQueueDepth) :
|
size_t commandQueueDepth) :
|
||||||
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF),
|
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF),
|
||||||
submode(SUBMODE_NONE), modeHelper(this),
|
submode(SUBMODE_NONE), modeHelper(this),
|
||||||
healthHelper(this, setObjectId) {
|
healthHelper(this, setObjectId) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
commandQueueDepth);
|
commandQueueDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerBase::~ControllerBase() {
|
ControllerBase::~ControllerBase() {
|
||||||
QueueFactory::instance()->deleteMessageQueue(commandQueue);
|
QueueFactory::instance()->deleteMessageQueue(commandQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ControllerBase::initialize() {
|
ReturnValue_t ControllerBase::initialize() {
|
||||||
ReturnValue_t result = SystemObject::initialize();
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t parentQueue = 0;
|
MessageQueueId_t parentQueue = 0;
|
||||||
if (parentId != objects::NO_OBJECT) {
|
if (parentId != objects::NO_OBJECT) {
|
||||||
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
|
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
|
||||||
if (parent == nullptr) {
|
if (parent == nullptr) {
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
parentQueue = parent->getCommandQueue();
|
parentQueue = parent->getCommandQueue();
|
||||||
|
|
||||||
parent->registerChild(getObjectId());
|
parent->registerChild(getObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
result = healthHelper.initialize(parentQueue);
|
result = healthHelper.initialize(parentQueue);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = modeHelper.initialize(parentQueue);
|
result = modeHelper.initialize(parentQueue);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t ControllerBase::getCommandQueue() const {
|
MessageQueueId_t ControllerBase::getCommandQueue() const {
|
||||||
return commandQueue->getId();
|
return commandQueue->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::handleQueue() {
|
void ControllerBase::handleQueue() {
|
||||||
CommandMessage command;
|
CommandMessage command;
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
for (result = commandQueue->receiveMessage(&command);
|
for (result = commandQueue->receiveMessage(&command);
|
||||||
result == RETURN_OK;
|
result == RETURN_OK;
|
||||||
result = commandQueue->receiveMessage(&command)) {
|
result = commandQueue->receiveMessage(&command)) {
|
||||||
|
|
||||||
result = modeHelper.handleModeCommand(&command);
|
result = modeHelper.handleModeCommand(&command);
|
||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = healthHelper.handleHealthCommand(&command);
|
result = healthHelper.handleHealthCommand(&command);
|
||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
result = handleCommandMessage(&command);
|
result = handleCommandMessage(&command);
|
||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
command.setToUnknownCommand();
|
command.setToUnknownCommand();
|
||||||
commandQueue->reply(&command);
|
commandQueue->reply(&command);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::startTransition(Mode_t mode, Submode_t submode) {
|
void ControllerBase::startTransition(Mode_t mode, Submode_t submode) {
|
||||||
changeHK(this->mode, this->submode, false);
|
changeHK(this->mode, this->submode, false);
|
||||||
triggerEvent(CHANGING_MODE, mode, submode);
|
triggerEvent(CHANGING_MODE, mode, submode);
|
||||||
this->mode = mode;
|
this->mode = mode;
|
||||||
this->submode = submode;
|
this->submode = submode;
|
||||||
modeHelper.modeChanged(mode, submode);
|
modeHelper.modeChanged(mode, submode);
|
||||||
modeChanged(mode, submode);
|
modeChanged(mode, submode);
|
||||||
announceMode(false);
|
announceMode(false);
|
||||||
changeHK(this->mode, this->submode, true);
|
changeHK(this->mode, this->submode, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::getMode(Mode_t* mode, Submode_t* submode) {
|
void ControllerBase::getMode(Mode_t* mode, Submode_t* submode) {
|
||||||
*mode = this->mode;
|
*mode = this->mode;
|
||||||
*submode = this->submode;
|
*submode = this->submode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::setToExternalControl() {
|
void ControllerBase::setToExternalControl() {
|
||||||
healthHelper.setHealth(EXTERNAL_CONTROL);
|
healthHelper.setHealth(EXTERNAL_CONTROL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::announceMode(bool recursive) {
|
void ControllerBase::announceMode(bool recursive) {
|
||||||
triggerEvent(MODE_INFO, mode, submode);
|
triggerEvent(MODE_INFO, mode, submode);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
|
ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
|
||||||
handleQueue();
|
handleQueue();
|
||||||
performControlOperation();
|
performControlOperation();
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::modeChanged(Mode_t mode, Submode_t submode) {
|
void ControllerBase::modeChanged(Mode_t mode, Submode_t submode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
||||||
switch (health) {
|
switch (health) {
|
||||||
case HEALTHY:
|
case HEALTHY:
|
||||||
case EXTERNAL_CONTROL:
|
case EXTERNAL_CONTROL:
|
||||||
healthHelper.setHealth(health);
|
healthHelper.setHealth(health);
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
default:
|
default:
|
||||||
return INVALID_HEALTH_STATE;
|
return INVALID_HEALTH_STATE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HasHealthIF::HealthState ControllerBase::getHealth() {
|
HasHealthIF::HealthState ControllerBase::getHealth() {
|
||||||
return healthHelper.getHealth();
|
return healthHelper.getHealth();
|
||||||
}
|
}
|
||||||
void ControllerBase::setTaskIF(PeriodicTaskIF* task_){
|
void ControllerBase::setTaskIF(PeriodicTaskIF* task_){
|
||||||
executingTask = task_;
|
executingTask = task_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
|
void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
|
||||||
|
@ -17,39 +17,39 @@
|
|||||||
* a mode and a health state. This avoids boilerplate code.
|
* a mode and a health state. This avoids boilerplate code.
|
||||||
*/
|
*/
|
||||||
class ControllerBase: public HasModesIF,
|
class ControllerBase: public HasModesIF,
|
||||||
public HasHealthIF,
|
public HasHealthIF,
|
||||||
public ExecutableObjectIF,
|
public ExecutableObjectIF,
|
||||||
public SystemObject,
|
public SystemObject,
|
||||||
public HasReturnvaluesIF {
|
public HasReturnvaluesIF {
|
||||||
public:
|
public:
|
||||||
static const Mode_t MODE_NORMAL = 2;
|
static const Mode_t MODE_NORMAL = 2;
|
||||||
|
|
||||||
ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
||||||
size_t commandQueueDepth = 3);
|
size_t commandQueueDepth = 3);
|
||||||
virtual ~ControllerBase();
|
virtual ~ControllerBase();
|
||||||
|
|
||||||
/** SystemObject override */
|
/** SystemObject override */
|
||||||
virtual ReturnValue_t initialize() override;
|
virtual ReturnValue_t initialize() override;
|
||||||
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const override;
|
virtual MessageQueueId_t getCommandQueue() const override;
|
||||||
|
|
||||||
/** HasHealthIF overrides */
|
/** HasHealthIF overrides */
|
||||||
virtual ReturnValue_t setHealth(HealthState health) override;
|
virtual ReturnValue_t setHealth(HealthState health) override;
|
||||||
virtual HasHealthIF::HealthState getHealth() override;
|
virtual HasHealthIF::HealthState getHealth() override;
|
||||||
|
|
||||||
/** ExecutableObjectIF overrides */
|
/** ExecutableObjectIF overrides */
|
||||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
virtual void setTaskIF(PeriodicTaskIF* task) override;
|
virtual void setTaskIF(PeriodicTaskIF* task) override;
|
||||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implemented by child class. Handle command messages which are not
|
* Implemented by child class. Handle command messages which are not
|
||||||
* mode or health messages.
|
* mode or health messages.
|
||||||
* @param message
|
* @param message
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0;
|
virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,35 +60,35 @@ protected:
|
|||||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t *msToReachTheMode) = 0;
|
uint32_t *msToReachTheMode) = 0;
|
||||||
|
|
||||||
const object_id_t parentId;
|
const object_id_t parentId;
|
||||||
|
|
||||||
Mode_t mode;
|
Mode_t mode;
|
||||||
|
|
||||||
Submode_t submode;
|
Submode_t submode;
|
||||||
|
|
||||||
MessageQueueIF* commandQueue = nullptr;
|
MessageQueueIF* commandQueue = nullptr;
|
||||||
|
|
||||||
ModeHelper modeHelper;
|
ModeHelper modeHelper;
|
||||||
|
|
||||||
HealthHelper healthHelper;
|
HealthHelper healthHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pointer to the task which executes this component,
|
* Pointer to the task which executes this component,
|
||||||
* is invalid before setTaskIF was called.
|
* is invalid before setTaskIF was called.
|
||||||
*/
|
*/
|
||||||
PeriodicTaskIF* executingTask = nullptr;
|
PeriodicTaskIF* executingTask = nullptr;
|
||||||
|
|
||||||
/** Handle mode and health messages */
|
/** Handle mode and health messages */
|
||||||
virtual void handleQueue();
|
virtual void handleQueue();
|
||||||
|
|
||||||
/** Mode helpers */
|
/** Mode helpers */
|
||||||
virtual void modeChanged(Mode_t mode, Submode_t submode);
|
virtual void modeChanged(Mode_t mode, Submode_t submode);
|
||||||
virtual void startTransition(Mode_t mode, Submode_t submode);
|
virtual void startTransition(Mode_t mode, Submode_t submode);
|
||||||
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
||||||
virtual void setToExternalControl();
|
virtual void setToExternalControl();
|
||||||
virtual void announceMode(bool recursive);
|
virtual void announceMode(bool recursive);
|
||||||
/** HK helpers */
|
/** HK helpers */
|
||||||
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
|
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CONTROLLER_CONTROLLERBASE_H_ */
|
#endif /* FSFW_CONTROLLER_CONTROLLERBASE_H_ */
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "../ipc/QueueFactory.h"
|
#include "../ipc/QueueFactory.h"
|
||||||
#include "../tmtcpacket/pus/TcPacketStored.h"
|
#include "../tmtcpacket/pus/TcPacketStored.h"
|
||||||
#include "../tmtcpacket/pus/TmPacketStored.h"
|
#include "../tmtcpacket/pus/TmPacketStored.h"
|
||||||
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
object_id_t CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
object_id_t CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
||||||
object_id_t CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
object_id_t CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
||||||
@ -104,9 +105,27 @@ ReturnValue_t CommandingServiceBase::initialize() {
|
|||||||
void CommandingServiceBase::handleCommandQueue() {
|
void CommandingServiceBase::handleCommandQueue() {
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
ReturnValue_t result = RETURN_FAILED;
|
ReturnValue_t result = RETURN_FAILED;
|
||||||
for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK;
|
while(true) {
|
||||||
result = commandQueue->receiveMessage(&reply)) {
|
result = commandQueue->receiveMessage(&reply);
|
||||||
handleCommandMessage(&reply);
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
handleCommandMessage(&reply);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if(result == MessageQueueIF::EMPTY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "CommandingServiceBase::handleCommandQueue: Receiving message failed"
|
||||||
|
"with code" << result << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("CommandingServiceBase::handleCommandQueue: Receiving message "
|
||||||
|
"failed with code %d\n", result);
|
||||||
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user