111 lines
3.5 KiB
C++
111 lines
3.5 KiB
C++
/*
|
||
* 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_ */
|