1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-03 17:37:18 +00:00
OpenMW/components/misc/objectpool.hpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

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