Skip to content

Instantly share code, notes, and snippets.

@benloong
Last active December 14, 2015 11:39
Show Gist options
  • Save benloong/5080675 to your computer and use it in GitHub Desktop.
Save benloong/5080675 to your computer and use it in GitHub Desktop.
simple object_manager and object_handle
#ifndef OBJECT_MANAGER
#define OBJECT_MANAGER 0
#include <vector>
#include <cassert>
const size_t INVALID = -1;
template <typename T>
class object_manager;
template<typename U>
class object_handle
{
public:
friend class object_manager<U>;
typedef object_handle<U> this_type;
explicit object_handle(object_manager<U> & pool):pool(pool) {};
~object_handle() {}
this_type& operator=(const this_type& rhs)
{
this->pool = rhs.pool;
this->slot = rhs.slot;
return *this;
}
operator bool() const
{
return *slot != INVALID;
}
U * operator->() const
{
return &pool.objects[*slot];
}
U & operator*() const
{
return pool.objects[*slot];
}
bool operator!() const
{
return *slot == INVALID;
}
private:
size_t *slot;
object_manager<U> & pool;
};
/*
*/
template <typename T>
class object_manager
{
public:
typedef object_handle<T> handle_type;
typedef T object_type;
friend class object_handle<T>;
object_manager(){}
~object_manager() {
for (std::vector<size_t*>::iterator i = all_slots.begin(); i != all_slots.end(); ++i)
{
delete *i;
}
}
handle_type create_object()
{
//allocate new slot
size_t slot = objects.size();
objects.push_back(object_type());
slots.push_back(new size_t(slot)); // allocate new slot id
all_slots.push_back(slots.back());
handle_type handle(*this);
handle.slot = slots.back();
return handle;
}
void destroy_object(handle_type & handle)
{
assert(handle);
size_t slot = *handle.slot;
objects[slot] = objects.back();
slots[slot] = slots.back();
*slots[slot] = slot; //modify slot id
objects.pop_back();
slots.pop_back();
*handle.slot = INVALID; //set slot invalid
}
public:
std::vector<object_type> objects;
std::vector<size_t*> slots;
std::vector<size_t*> all_slots;
};
#endif
#include "object_manager.h"
#include <cassert>
#include <iostream>
struct simple_object
{
int x,y,z;
};
typedef object_manager<simple_object> simple_object_manager;
typedef object_handle<simple_object> simple_object_handle;
int main(int argc, char const *argv[])
{
simple_object_manager manager;
simple_object_handle h = manager.create_object();
simple_object_handle h2 = h;
assert(h2 && h);
std::cout<<"h2 valid: "<<(bool)h2<<std::endl;
manager.destroy_object(h);
std::cout<<"after destroyed h2 valid: "<<(bool)h2<<std::endl;
std::cout<<"after destroyed h valid: "<<(bool)h<<std::endl;
assert(!h2);
assert(!h);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment