Created
July 23, 2017 14:05
-
-
Save MehdiNS/dc854c03c646315368869c388ed5cb97 to your computer and use it in GitHub Desktop.
Implementation of a slotmap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <algorithm> | |
#include <string> | |
#include <memory> | |
#include <vector> | |
using namespace std; | |
using u32 = unsigned int; | |
using s32 = int; | |
struct Texture | |
{ | |
s32 m_id; | |
string m_debugname; | |
Texture(s32 id, const std::string& debugname) | |
{ | |
m_debugname = debugname; m_id = id; | |
// + allocate texture data | |
std::cout << "Creating texture (" << m_debugname << ")" << std::endl; | |
} | |
~Texture() | |
{ | |
if(m_id == -1) | |
{ | |
// + free texture data | |
std::cout << "Destructing texture (" << m_debugname << ")" << std::endl; | |
} | |
} | |
// "Holy Trinity" | |
Texture(const Texture& other) : | |
m_id{ other.m_id }, | |
m_debugname{ other.m_debugname } | |
{ | |
} | |
void swap(Texture &other) | |
{ | |
using std::swap; | |
swap(m_id, other.m_id); | |
swap(m_debugname, other.m_debugname); | |
} | |
Texture& operator=(const Texture& other) | |
{ | |
Texture{ other }.swap(*this); | |
return *this; | |
} | |
}; | |
template<class T> | |
class Slotmap | |
{ | |
public: | |
std::vector<T> m_resources; | |
std::vector<u32> m_freelist; | |
Slotmap() | |
{ | |
} | |
~Slotmap() | |
{ | |
std::cout << "\n(Destruction of the slot map)\n"; | |
destroyAll(); | |
} | |
void printAll() | |
{ | |
std::cout << "List of objects : "; | |
for (auto& elt : m_resources) | |
{ | |
std::cout << "[" << elt.m_debugname << " / " << elt.m_id<< "]\t"; | |
} | |
std::cout << "\n"; | |
} | |
template <class ... Args> | |
u32 add(Args&& ... args) | |
{ | |
if (!m_freelist.empty()) | |
{ | |
u32 free = m_freelist.back(); | |
m_freelist.pop_back(); | |
m_resources[free] = T(free, args...); | |
return free; | |
} | |
else | |
{ | |
u32 id = m_resources.size(); | |
m_resources.emplace_back(id, args...); | |
return id; | |
} | |
} | |
void destroy(u32 id) | |
{ | |
m_resources[id].m_id = -1; | |
m_freelist.emplace_back(id); | |
std::cout << m_resources[id].m_debugname << " is marked for deletion\n"; | |
} | |
void destroyAll() | |
{ | |
std::for_each(std::begin(m_resources), std::end(m_resources), [](T& t) {t.m_id = -1; }); | |
} | |
}; | |
int main() { | |
Slotmap<Texture> textureManager{}; | |
//textureManager.m_resources.reserve(16); | |
u32 o1 = textureManager.add("OBJ1"); | |
textureManager.printAll(); | |
u32 o2 = textureManager.add("OBJ2"); | |
textureManager.printAll(); | |
u32 o3 = textureManager.add("OBJ3"); | |
textureManager.printAll(); | |
textureManager.destroy(o2); | |
textureManager.printAll(); | |
u32 o4 = textureManager.add("OBJ4"); | |
textureManager.printAll(); | |
return 0; | |
} | |
// The above code generates this trace | |
/* | |
Creating texture (OBJ1) | |
List of objects : [OBJ1 / 0] | |
Creating texture (OBJ2) | |
List of objects : [OBJ1 / 0] [OBJ2 / 1] | |
Creating texture (OBJ3) | |
List of objects : [OBJ1 / 0] [OBJ2 / 1] [OBJ3 / 2] | |
OBJ2 is marked for deletion | |
List of objects : [OBJ1 / 0] [OBJ2 / -1] [OBJ3 / 2] | |
Creating texture (OBJ4) | |
Destructing texture (OBJ2) | |
List of objects : [OBJ1 / 0] [OBJ4 / 1] [OBJ3 / 2] | |
(Destruction of the slot map) | |
Destructing texture (OBJ1) | |
Destructing texture (OBJ4) | |
Destructing texture (OBJ3) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment