1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-05 15:55:45 +00:00
OpenMW/components/misc/objectpool.hpp

88 lines
1.8 KiB
C++
Raw Normal View History

#ifndef OPENMW_COMPONENTS_MISC_OBJECTPOOL_H
#define OPENMW_COMPONENTS_MISC_OBJECTPOOL_H
#include <deque>
#include <memory>
#include <vector>
namespace Misc
{
2020-06-28 16:25:23 +00:00
template <class T>
class ObjectPool;
template <class T>
class ObjectPtrDeleter
{
2022-09-22 18:26:05 +00:00
public:
ObjectPtrDeleter(std::nullptr_t)
: mPool(nullptr)
{
}
2020-06-28 16:25:23 +00:00
2022-09-22 18:26:05 +00:00
ObjectPtrDeleter(ObjectPool<T>& pool)
: mPool(&pool)
{
}
2020-06-28 16:25:23 +00:00
2022-09-22 18:26:05 +00:00
void operator()(T* object) const { mPool->recycle(object); }
2020-06-28 16:25:23 +00:00
2022-09-22 18:26:05 +00:00
private:
ObjectPool<T>* mPool;
2020-06-28 16:25:23 +00:00
};
template <class T>
struct ObjectPtr final : std::unique_ptr<T, ObjectPtrDeleter<T>>
{
using std::unique_ptr<T, ObjectPtrDeleter<T>>::unique_ptr;
using std::unique_ptr<T, ObjectPtrDeleter<T>>::operator=;
ObjectPtr()
2022-09-22 18:26:05 +00:00
: ObjectPtr(nullptr)
{
}
2020-06-28 16:25:23 +00:00
ObjectPtr(std::nullptr_t)
2022-09-22 18:26:05 +00:00
: std::unique_ptr<T, ObjectPtrDeleter<T>>(nullptr, nullptr)
{
}
2020-06-28 16:25:23 +00:00
};
template <class T>
class ObjectPool
{
2020-06-28 16:25:23 +00:00
friend class ObjectPtrDeleter<T>;
2022-09-22 18:26:05 +00:00
public:
ObjectPool()
: mObjects(std::make_unique<std::deque<T>>())
{
}
2022-09-22 18:26:05 +00:00
ObjectPtr<T> get()
{
T* object;
if (!mUnused.empty())
{
2022-09-22 18:26:05 +00:00
object = mUnused.back();
mUnused.pop_back();
}
2022-09-22 18:26:05 +00:00
else
{
2022-09-22 18:26:05 +00:00
mObjects->emplace_back();
object = &mObjects->back();
}
2022-09-22 18:26:05 +00:00
return ObjectPtr<T>(object, ObjectPtrDeleter<T>(*this));
}
private:
std::unique_ptr<std::deque<T>> mObjects;
std::vector<T*> mUnused;
void recycle(T* object) { mUnused.push_back(object); }
};
}
#endif