reworked objectmanager

This commit is contained in:
Lauchmelder 2021-12-26 19:38:22 +01:00
parent e23d22153c
commit 967bf6b161
7 changed files with 71 additions and 57 deletions

View file

@ -23,7 +23,8 @@ add_library(lol STATIC
"src/Buffer.cpp"
"src/buffers/VertexBuffer.cpp"
"src/buffers/ElementBuffer.cpp"
"src/Image.cpp")
"src/Image.cpp"
"src/ObjectManager.cpp")
target_include_directories(lol PUBLIC
${GLM_INCLUDE_DIRS}

View file

@ -82,6 +82,4 @@ namespace lol
private:
unsigned int id;
};
typedef ObjectManager<Shader> ShaderManager;
}

View file

@ -28,8 +28,6 @@ namespace lol
unsigned int id;
};
typedef ObjectManager<Texture> TextureManager;
class Texture2D : public Texture
{

View file

@ -36,7 +36,4 @@ namespace lol
std::shared_ptr<ElementBuffer> elementBuffer;
};
// Object manager for managing said shared pointers
typedef ObjectManager<VertexArray> VAOManager;
}

View file

@ -0,0 +1,16 @@
#pragma once
#include <stdexcept>
#define TYPENAME(x) #x
namespace lol
{
class ObjectNotFoundException : public std::runtime_error
{
public:
ObjectNotFoundException(unsigned int id) :
std::runtime_error("Failed to Get() object with ID " + std::to_string(id) + " from ObjectManager. It does not exist.")
{ }
};
}

View file

@ -3,6 +3,9 @@
#include <map>
#include <memory>
#include <lol/util/NonCopyable.hpp>
#include <lol/util/Exceptions.hpp>
namespace lol
{
@ -17,75 +20,43 @@ namespace lol
* As a consequence, even if no objects are using an object stored in here it will continue to
* exist.
*/
template<typename Type>
class ObjectManager : public NonCopyable
{
public:
static ObjectManager<Type>& GetInstance()
{
static ObjectManager<Type> instance;
return instance;
}
ObjectManager() {}
/**
* Add new (existing) object to manager
*/
inline void Register(unsigned int id, const std::shared_ptr<Type>& obj)
template<typename T, typename... Args>
std::shared_ptr<T> Create(unsigned int id, Args... args)
{
objects.insert(std::make_pair(id, obj));
std::shared_ptr<T> object = std::make_shared<T>(args...);
objects.insert({id, object});
return object;
}
/**
* Remove object from manager
*/
inline void Delete(unsigned int id)
{
objects.erase(id);
}
void Delete(unsigned int id);
/**
* Retrieve object from manager
*/
inline std::shared_ptr<Type> Get(unsigned int id)
std::shared_ptr<void> Get(unsigned int id);
template<typename T>
std::shared_ptr<T> Get(unsigned int id)
{
auto it = objects.find(id);
if (it == objects.end())
return nullptr;
return it->second;
std::shared_ptr<void> object = Get(id);
return std::static_pointer_cast<T>(object);
}
inline void CleanupUnused()
{
for(auto& [key, val] : objects)
{
if (val.use_count() < 3)
objects.erase(key);
}
}
inline void Cleanup()
{
objects.clear();
}
inline void Return(unsigned int id)
{
auto it = objects.find(id);
if (it == objects.end())
return;
if (it->second.use_count() < 3) // I hope I don't forget about this if I ever go multithreaded
objects.erase(it);
}
void ClearUnused();
void Clear();
private:
ObjectManager() {}
private:
std::map<unsigned int, std::shared_ptr<Type>> objects;
std::map<unsigned int, std::shared_ptr<void>> objects;
};
}

33
src/ObjectManager.cpp Normal file
View file

@ -0,0 +1,33 @@
#include <lol/util/ObjectManager.hpp>
namespace lol
{
std::shared_ptr<void> ObjectManager::Get(unsigned int id)
{
auto it = objects.find(id);
if(it == objects.end())
throw ObjectNotFoundException(id);
return it->second;
}
void ObjectManager::Delete(unsigned int id)
{
objects.erase(id);
}
void ObjectManager::ClearUnused()
{
for(const auto& [key, value] : objects)
{
if(value.unique())
objects.erase(key);
}
}
void ObjectManager::Clear()
{
objects.clear();
}
}