#ifndef GLOBALPOOLVARIABLE_H_ #define GLOBALPOOLVARIABLE_H_ #include "../datapool/DataSetIF.h" #include "../datapoolglob/GlobalDataPool.h" #include "../datapool/PoolVariableIF.h" #include "../datapool/PoolEntry.h" #include "../serialize/SerializeAdapter.h" #include "../serviceinterface/ServiceInterfaceStream.h" template class PoolVarList; /** * @brief This is the access class for non-array data pool entries. * * @details * To ensure safe usage of the data pool, operation is not done directly * on the data pool entries, but on local copies. This class provides simple * type-safe access to single data pool entries (i.e. entries with length = 1). * The class can be instantiated as read-write and read only. * It provides a commit-and-roll-back semantic, which means that the * variable's value in the data pool is not changed until the * commit call is executed. * @tparam T The template parameter sets the type of the variable. * Currently, all plain data types are supported, but in principle * any type is possible. * @ingroup data_pool */ template class GlobPoolVar: public PoolVariableIF { template friend class PoolVarList; static_assert(not std::is_same::value, "Do not use boolean for the PoolEntry type, use uint8_t instead!" "There is no boolean type in CCSDS."); public: /** * @brief In the constructor, the variable can register itself in a * DataSet (if nullptr is not passed). * @details * It DOES NOT fetch the current value from the data pool, but * sets the value attribute to default (0). * The value is fetched within the read() operation. * @param set_id This is the id in the global data pool * this instance of the access class corresponds to. * @param dataSet The data set in which the variable shall register * itself. If NULL, the variable is not registered. * @param setWritable If this flag is set to true, changes in the value * attribute can be written back to the data pool, otherwise not. */ GlobPoolVar(uint32_t set_id, DataSetIF* dataSet, ReadWriteMode_t setReadWriteMode); /** * @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 simple local variable. */ T value = 0; /** * @brief Copy ctor to copy classes containing Pool Variables. * (Robin): This only copies member variables, which is done * by the default copy ctor. maybe we can ommit this ctor? */ GlobPoolVar(const GlobPoolVar& rhs); /** * @brief The classes destructor is empty. * @details If commit() was not called, the local value is * discarded and not written back to the data pool. */ ~GlobPoolVar() {} /** * @brief This is a call to read the value 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 the value and the valid * information to its local attributes. In case of a failure (wrong type or * pool id not found), the variable is set to zero and invalid. * The read call is protected with a lock. * It is recommended to use DataSets to read and commit multiple variables * at once to avoid the overhead of unnecessary lock und unlock operations. */ ReturnValue_t read(uint32_t lockTimeout) override; /** * @brief The commit call writes back the variable's value 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. * The commit call is protected with a lock. * It is recommended to use DataSets to read and commit multiple variables * at once to avoid the overhead of unnecessary lock und unlock operations. */ ReturnValue_t commit(uint32_t lockTimeout) override; protected: /** * @brief Like #read, but without a lock protection of the global pool. * @details * The operation does NOT provide any mutual exclusive protection by itself. * This can be used if the lock is handled externally to avoid the overhead * of consecutive lock und unlock operations. * Declared protected to discourage free public usage. */ ReturnValue_t readWithoutLock() override; /** * @brief Like #commit, but without a lock protection of the global pool. * @details * The operation does NOT provide any mutual exclusive protection by itself. * This can be used if the lock is handled externally to avoid the overhead * of consecutive lock und unlock operations. * Declared protected to discourage free public usage. */ ReturnValue_t commitWithoutLock() override; /** * @brief To access the correct data pool entry on read and commit calls, * the data pool 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. */ pool_rwm_t readWriteMode; /** * Empty ctor for List initialization */ GlobPoolVar(); public: /** * \brief This operation returns the data pool id of the variable. */ uint32_t getDataPoolId() const override; /** * This method returns if the variable is write-only, read-write or read-only. */ ReadWriteMode_t getReadWriteMode() const override; /** * 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. */ void setDataPoolId(uint32_t poolId); /** * \brief With this call, the valid information of the variable is returned. */ bool isValid() const override; uint8_t getValid(); void setValid(bool valid) override; operator T() { return value; } operator T() const { return value; } GlobPoolVar &operator=(T newValue) { value = newValue; return *this; } GlobPoolVar &operator=(GlobPoolVar newPoolVariable) { value = newPoolVariable.value; return *this; } virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t max_size, SerializeIF::Endianness streamEndianness) const override { return SerializeAdapter::serialize(&value, buffer, size, max_size, streamEndianness); } virtual size_t getSerializedSize() const { return SerializeAdapter::getSerializedSize(&value); } virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, SerializeIF::Endianness streamEndianness) { return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness); } }; #include "../datapoolglob/GlobalPoolVariable.tpp" typedef GlobPoolVar gp_bool_t; typedef GlobPoolVar gp_uint8_t; typedef GlobPoolVar gp_uint16_t; typedef GlobPoolVar gp_uint32_t; typedef GlobPoolVar gp_int8_t; typedef GlobPoolVar gp_int16_t; typedef GlobPoolVar gp_int32_t; typedef GlobPoolVar gp_float_t; typedef GlobPoolVar gp_double_t; #endif /* POOLVARIABLE_H_ */