Last active
December 14, 2015 11:39
-
-
Save benloong/5080675 to your computer and use it in GitHub Desktop.
simple object_manager and object_handle
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
#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 |
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 "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