MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/common/PoolObject.hpp

111 lines
3.5 KiB
C++
Raw Normal View History

2024-06-07 11:12:56 +03:00
/*
* TPoolObject.hpp
*
* Created on: 24 авг. 2016 г.
* Author: user
*/
#ifndef SOURCE_COMMON_POOLOBJECT_HPP_
#define SOURCE_COMMON_TPOOLOBJECT_HPP_
//! Шаблонный класс с реализацие логики работы с пулом объектов
/**!
* \tparam T тип, хранимый в пуле
* \tparam size размер пула
*/
template<typename T, typename M, unsigned int size>
class PoolObject {
public:
//! функция запроса ресурса из пула
/* Запрос от внешних модулей. В случае, если ресурс
* уже был запрошен, повторно не предоставляется (возвращается нулевой указатель).
* \param [in] id идентификатор ресурса
* \return указатель на ресурс или nullptr в случае недоступности ресурса
*/
T * grabObject(M id);
//! Функция освобождения ресурса
/* Запрос от внешних модулей. Ресурс освобождается для возможности
* его дальнейшего использования.
* TODO: в текущей реализации есть возможность последующего использования ресурса
* по указателю, что может повредить другому запрашивающему этот ресурс модулю.
* Подумать над возможным решением этой проблемы (Proxy?)
* \param [in] resource указатель на освобождаемый ресурс
*/
void freeObject(T * & resource);
//! Конструктор по умолчанию
PoolObject() {}
//! Деструктор по умолчанию
virtual ~PoolObject() {}
protected:
//! Функция создания ресурса
/* Виртуальная функция, делегирующая создание ресурса дочернему классу, реализующему
* работу с пулом ресурсов конкретного типа.
* \param [in] id идентификатор ресурса
*/
virtual T * createObject(M id) = 0;
T * getObjectPtr(M id);
void makeFree(M id);
private:
struct TRecord {
T * pObject;
bool isUse;
TRecord() : pObject(0), isUse(false)
{}
};
TRecord pool[size];
};
template<typename T, typename M, unsigned int size>
inline T * PoolObject<T, M, size>::grabObject(M id) {
unsigned int n_id = static_cast<unsigned int>(id);
if(n_id > size) return nullptr;
if(!pool[n_id].isUse) {
if(!pool[n_id].pObject)
pool[n_id].pObject = createObject(id);
pool[n_id].isUse = true;
return pool[n_id].pObject;
} else {
return nullptr;
}
}
template<typename T, typename M, unsigned int size>
inline void PoolObject<T, M, size>::freeObject(T * & resource) {
for (int i = 0; i < size; i++){
if (pool[i].pObject == resource){
pool[i].isUse = false;
break;
}
}
resource = nullptr;
}
template<typename T, typename M, unsigned int size>
inline T * PoolObject<T, M, size>::getObjectPtr(M id) {
unsigned int n_id = static_cast<unsigned int>(id);
if(n_id < size && pool[n_id].isUse) return pool[n_id].pObject;
else return 0;
}
template<typename T, typename M, unsigned int size>
inline void PoolObject<T, M, size>::makeFree(M id) {
unsigned int n_id = static_cast<unsigned int>(id);
pool[n_id].isUse = false;
}
#endif /* SOURCE_COMMON_POOLOBJECT_HPP_ */