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_ */
|