glob pool vec implementation in tpp file

This commit is contained in:
Robin Müller 2020-05-17 22:16:25 +02:00
parent 8b1fef730d
commit 9da0b0b2b2
2 changed files with 186 additions and 167 deletions

View File

@ -1,5 +1,5 @@
#ifndef POOLVECTOR_H_ #ifndef GLOBALPOOLVECTOR_H_
#define POOLVECTOR_H_ #define GLOBALPOOLVECTOR_H_
#include <framework/datapool/DataSetIF.h> #include <framework/datapool/DataSetIF.h>
#include <framework/datapool/PoolEntry.h> #include <framework/datapool/PoolEntry.h>
@ -8,139 +8,79 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
/** /**
* \brief This is the access class for array-type data pool entries. * @brief This is the access class for array-type data pool entries.
* *
* \details To ensure safe usage of the data pool, operation is not done directly on the data pool * @details
* entries, but on local copies. This class provides simple type- and length-safe access * To ensure safe usage of the data pool, operation is not done directly on the
* to vector-style data pool entries (i.e. entries with length > 1). * data pool entries, but on local copies. This class provides simple type-
* The class can be instantiated as read-write and read only. * and length-safe access to vector-style data pool entries (i.e. entries with
* It provides a commit-and-roll-back semantic, which means that no array entry in * length > 1). The class can be instantiated as read-write and read only.
* the data pool is changed until the commit call is executed. *
* There are two template parameters: * It provides a commit-and-roll-back semantic, which means that no array
* \tparam T This template parameter specifies the data type of an array entry. Currently, all * entry in the data pool is changed until the commit call is executed.
* plain data types are supported, but in principle any type is possible. * There are two template parameters:
* \tparam vector_size This template parameter specifies the vector size of this entry. * @tparam T
* Using a template parameter for this is not perfect, but avoids dynamic memory allocation. * This template parameter specifies the data type of an array entry. Currently,
* \ingroup data_pool * all plain data types are supported, but in principle any type is possible.
* @tparam vector_size
* This template parameter specifies the vector size of this entry. Using a
* template parameter for this is not perfect, but avoids
* dynamic memory allocation.
* @ingroup data_pool
*/ */
template<typename T, uint16_t vector_size> template<typename T, uint16_t vectorSize>
class GlobPoolVector: public PoolVariableIF { class GlobPoolVector: public PoolVariableIF {
private:
/**
* \brief To access the correct data pool entry on read and commit calls, the data pool id
* is stored.
*/
uint32_t dataPoolId;
/**
* \brief The valid information as it was stored in the data pool is copied to this attribute.
*/
uint8_t valid;
/**
* \brief The information whether the class is read-write or read-only is stored here.
*/
ReadWriteMode_t readWriteMode;
protected:
/**
* \brief This is a call to read the array's values from the global data pool.
* \details When executed, this operation tries to fetch the pool entry with matching
* data pool id from the global data pool and copies all array values and the valid
* information to its local attributes. In case of a failure (wrong type, size or
* pool id not found), the variable is set to zero and invalid.
* The operation does NOT provide any mutual exclusive protection by itself.
*/
ReturnValue_t read() {
PoolEntry<T>* read_out = glob::dataPool.getData<T>(this->dataPoolId,
vector_size);
if (read_out != NULL) {
this->valid = read_out->valid;
memcpy(this->value, read_out->address, read_out->getByteSize());
return HasReturnvaluesIF::RETURN_OK;
} else {
memset(this->value, 0, vector_size * sizeof(T));
sif::error << "PoolVector: read of DP Variable 0x" << std::hex
<< dataPoolId << std::dec << " failed." << std::endl;
this->valid = INVALID;
return HasReturnvaluesIF::RETURN_FAILED;
}
}
/**
* \brief The commit call copies the array values back to the data pool.
* \details It checks type and size, as well as if the variable is writable. If so,
* the value is copied and the valid flag is automatically set to "valid".
* The operation does NOT provide any mutual exclusive protection by itself.
*
*/
ReturnValue_t commit() {
PoolEntry<T>* write_back = glob::dataPool.getData<T>(this->dataPoolId,
vector_size);
if ((write_back != NULL) && (this->readWriteMode != VAR_READ)) {
write_back->valid = valid;
memcpy(write_back->address, this->value, write_back->getByteSize());
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
public: public:
/** /**
* \brief This is the local copy of the data pool entry. * @brief In the constructor, the variable can register itself in a
* \detials The user can work on this attribute * DataSet (if no nullptr is passed).
* just like he would on a local array of this type. * @details
*/ * It DOES NOT fetch the current value from the data pool, but sets the
T value[vector_size]; * value attribute to default (0). The value is fetched within the
/** * read() operation.
* \brief In the constructor, the variable can register itself in a DataSet (if not NULL is * @param set_id
* passed). * This is the id in the global data pool this instance of the access
* \details It DOES NOT fetch the current value from the data pool, but sets the value * class corresponds to.
* attribute to default (0). The value is fetched within the read() operation. * @param dataSet
* \param set_id This is the id in the global data pool this instance of the access class * The data set in which the variable shall register itself. If nullptr,
* corresponds to. * the variable is not registered.
* \param dataSet The data set in which the variable shall register itself. If NULL, * @param setWritable
* the variable is not registered. * If this flag is set to true, changes in the value attribute can be
* \param setWritable If this flag is set to true, changes in the value attribute can be * written back to the data pool, otherwise not.
* written back to the data pool, otherwise not.
*/ */
GlobPoolVector(uint32_t set_id, DataSetIF* set, GlobPoolVector(uint32_t set_id, DataSetIF* set,
ReadWriteMode_t setReadWriteMode) : ReadWriteMode_t setReadWriteMode);
dataPoolId(set_id), valid(false), readWriteMode(setReadWriteMode) {
memset(this->value, 0, vector_size * sizeof(T));
if (set != NULL) {
set->registerVariable(this);
}
}
/** /**
* Copy ctor to copy classes containing Pool Variables. * @brief This is the local copy of the data pool entry.
* @details The user can work on this attribute
* just like he would on a local array of this type.
*/ */
// PoolVector(const PoolVector& rhs) { T value[vectorSize];
// PoolVector<T, vector_size> temp(rhs.dataPoolId, rhs.)
// memcpy(value, rhs.value, sizeof(T)*vector_size);
// }
/** /**
* \brief The classes destructor is empty. * @brief The classes destructor is empty.
* \details If commit() was not called, the local value is * @details If commit() was not called, the local value is
* discarded and not written back to the data pool. * discarded and not written back to the data pool.
*/ */
~GlobPoolVector() { ~GlobPoolVector() {};
}
;
/** /**
* \brief The operation returns the number of array entries in this variable. * @brief The operation returns the number of array entries
* in this variable.
*/ */
uint8_t getSize() { uint8_t getSize() {
return vector_size; return vectorSize;
} }
/** /**
* \brief This operation returns the data pool id of the variable. * @brief This operation returns the data pool id of the variable.
*/ */
uint32_t getDataPoolId() const { uint32_t getDataPoolId() const {
return dataPoolId; return dataPoolId;
} }
/** /**
* This operation sets the data pool id of the variable. * @brief This operation sets the data pool id of the variable.
* The method is necessary to set id's of data pool member variables with bad initialization. * @details
* The method is necessary to set id's of data pool member variables
* with bad initialization.
*/ */
void setDataPoolId(uint32_t poolId) { void setDataPoolId(uint32_t poolId) {
dataPoolId = poolId; dataPoolId = poolId;
@ -151,9 +91,10 @@ public:
ReadWriteMode_t getReadWriteMode() const { ReadWriteMode_t getReadWriteMode() const {
return readWriteMode; return readWriteMode;
} }
;
/** /**
* \brief With this call, the valid information of the variable is returned. * @brief With this call, the valid information of the variable is returned.
*/ */
bool isValid() const { bool isValid() const {
if (valid != INVALID) if (valid != INVALID)
@ -161,65 +102,60 @@ public:
else else
return false; return false;
} }
void setValid(uint8_t valid) {this->valid = valid;}
uint8_t getValid() {return valid;}
void setValid(uint8_t valid) { T &operator [](int i) {return value[i];}
this->valid = valid; const T &operator [](int i) const {return value[i];}
}
uint8_t getValid() {
return valid;
}
T &operator [](int i) {
return value[i];
}
const T &operator [](int i) const {
return value[i];
}
GlobPoolVector<T, vector_size> &operator=(
GlobPoolVector<T, vector_size> newPoolVector) {
for (uint16_t i = 0; i < vector_size; i++) {
this->value[i] = newPoolVector.value[i];
}
return *this;
}
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const size_t max_size, bool bigEndian) const override { const size_t max_size, bool bigEndian) const override;
uint16_t i; virtual size_t getSerializedSize() const override;
ReturnValue_t result;
for (i = 0; i < vector_size; i++) {
result = SerializeAdapter<T>::serialize(&(value[i]), buffer, size,
max_size, bigEndian);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
return result;
}
virtual size_t getSerializedSize() const override {
return vector_size * SerializeAdapter<T>::getSerializedSize(value);
}
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) override { bool bigEndian) override;
uint16_t i; protected:
ReturnValue_t result; /**
for (i = 0; i < vector_size; i++) { * @brief This is a call to read the array's values
result = SerializeAdapter<T>::deSerialize(&(value[i]), buffer, size, * from the global data pool.
bigEndian); * @details
if (result != HasReturnvaluesIF::RETURN_OK) { * When executed, this operation tries to fetch the pool entry with matching
return result; * data pool id from the global data pool and copies all array values
} * and the valid information to its local attributes.
} * In case of a failure (wrong type, size or pool id not found), the
return result; * variable is set to zero and invalid. The operation does NOT provide
} * any mutual exclusive protection by itself.
*/
ReturnValue_t read();
/**
* @brief The commit call copies the array values back to the data pool.
* @details
* It checks type and size, as well as if the variable is writable. If so,
* the value is copied and the valid flag is automatically set to "valid".
* The operation does NOT provide any mutual exclusive protection by itself.
*/
ReturnValue_t commit();
private:
/**
* @brief To access the correct data pool entry on read and commit calls,
* the data pool id is stored.
*/
uint32_t dataPoolId;
/**
* @brief The valid information as it was stored in the data pool
* is copied to this attribute.
*/
uint8_t valid;
/**
* @brief The information whether the class is read-write or
* read-only is stored here.
*/
ReadWriteMode_t readWriteMode;
}; };
#include <framework/datapoolglob/GlobalPoolVector.tpp>
template<typename T, uint16_t vectorSize> template<typename T, uint16_t vectorSize>
using gp_vec_t = GlobPoolVector<T, vectorSize>; using gp_vec_t = GlobPoolVector<T, vectorSize>;

View File

@ -0,0 +1,83 @@
#ifndef GLOBALPOOLVECTOR_TPP_
#define GLOBALPOOLVECTOR_TPP_
template<typename T, uint16_t vectorSize>
inline GlobPoolVector<T, vectorSize>::GlobPoolVector(uint32_t set_id,
DataSetIF* set, ReadWriteMode_t setReadWriteMode) :
dataPoolId(set_id), valid(false), readWriteMode(setReadWriteMode) {
memset(this->value, 0, vectorSize * sizeof(T));
if (set != nullptr) {
set->registerVariable(this);
}
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t GlobPoolVector<T, vectorSize>::read() {
PoolEntry<T>* read_out = glob::dataPool.getData<T>(this->dataPoolId,
vectorSize);
if (read_out != nullptr) {
this->valid = read_out->valid;
memcpy(this->value, read_out->address, read_out->getByteSize());
return HasReturnvaluesIF::RETURN_OK;
} else {
memset(this->value, 0, vectorSize * sizeof(T));
sif::error << "PoolVector: Read of DP Variable 0x" << std::hex
<< std::setw(8) << std::setfill('0') << dataPoolId <<
std::dec << " failed." << std::endl;
this->valid = INVALID;
return HasReturnvaluesIF::RETURN_FAILED;
}
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t GlobPoolVector<T, vectorSize>::commit() {
PoolEntry<T>* writeBack = glob::dataPool.getData<T>(this->dataPoolId,
vectorSize);
if ((writeBack != nullptr) && (this->readWriteMode != VAR_READ)) {
writeBack->valid = valid;
memcpy(writeBack->address, this->value, writeBack->getByteSize());
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t GlobPoolVector<T, vectorSize>::serialize(uint8_t** buffer,
size_t* size, const size_t max_size, bool bigEndian) const {
uint16_t i;
ReturnValue_t result;
for (i = 0; i < vectorSize; i++) {
result = SerializeAdapter<T>::serialize(&(value[i]), buffer, size,
max_size, bigEndian);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
return result;
}
template<typename T, uint16_t vectorSize>
inline size_t GlobPoolVector<T, vectorSize>::getSerializedSize() const {
return vectorSize * SerializeAdapter<T>::getSerializedSize(value);
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t GlobPoolVector<T, vectorSize>::deSerialize(
const uint8_t** buffer, size_t* size, bool bigEndian) {
uint16_t i;
ReturnValue_t result;
for (i = 0; i < vectorSize; i++) {
result = SerializeAdapter<T>::deSerialize(&(value[i]), buffer, size,
bigEndian);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
return result;
}
#endif