IdManager fix

Debug build fixed
Allowed get/remove with forward declarations
This commit is contained in:
Nekotekina 2016-06-21 11:22:30 +03:00
parent c96057296a
commit eb889920e6
2 changed files with 42 additions and 17 deletions

View File

@ -15,11 +15,11 @@ std::vector<id_manager::typeinfo>& id_manager::typeinfo::access()
return list; return list;
} }
u32 id_manager::typeinfo::add_type(typeinfo info) u32 id_manager::typeinfo::add_type()
{ {
auto& list = access(); auto& list = access();
list.emplace_back(info); list.emplace_back();
return ::size32(list) - 1; return ::size32(list) - 1;
} }

View File

@ -80,20 +80,30 @@ namespace id_manager
static std::vector<typeinfo>& access(); static std::vector<typeinfo>& access();
// Add to the global list // Add to the global list
static u32 add_type(typeinfo info); static u32 add_type();
public: public:
void(*on_init)(void*); void(*on_init)(void*) = nullptr;
void(*on_stop)(void*); void(*on_stop)(void*) = nullptr;
// Get type index // Get type index
template<typename T> template<typename T>
static inline u32 get_index() static inline u32 get_index()
{ {
// Forbid forward declarations (It'd be better to allow them sometimes but it seems too dangerous) return registered<T>::index;
}
// Register functions
template<typename T>
static inline void update()
{
// Forbid forward declarations
static constexpr auto size = sizeof(std::conditional_t<std::is_void<T>::value, void*, T>); static constexpr auto size = sizeof(std::conditional_t<std::is_void<T>::value, void*, T>);
return registered<T>::index; auto& info = access()[get_index<T>()];
info.on_init = [](void* ptr) { return_ id_manager::on_init<T>::func(static_cast<T*>(ptr)); };
info.on_stop = [](void* ptr) { return_ id_manager::on_stop<T>::func(static_cast<T*>(ptr)); };
} }
// Read all registered types // Read all registered types
@ -101,14 +111,16 @@ namespace id_manager
{ {
return access(); return access();
} }
template<typename T>
static inline auto get_stop()
{
return access()[get_index<T>()].on_stop;
}
}; };
template<typename T> template<typename T>
const u32 typeinfo::registered<T>::index = typeinfo::add_type( const u32 typeinfo::registered<T>::index = typeinfo::add_type();
{
PURE_EXPR(id_manager::on_init<T>::func(static_cast<T*>(ptr)), void* ptr),
PURE_EXPR(id_manager::on_stop<T>::func(static_cast<T*>(ptr)), void* ptr),
});
} }
// Object manager for emulated process. Multiple objects of specified arbitrary type are given unique IDs. // Object manager for emulated process. Multiple objects of specified arbitrary type are given unique IDs.
@ -198,6 +210,9 @@ class idm
template<typename T, typename F> template<typename T, typename F>
static map_type::pointer create_id(F&& provider) static map_type::pointer create_id(F&& provider)
{ {
id_manager::typeinfo::update<T>();
id_manager::typeinfo::update<typename id_manager::id_traits<T>::tag>();
writer_lock lock(g_mutex); writer_lock lock(g_mutex);
if (auto place = allocate_id(get_tag<T>(), id_manager::id_traits<T>::min, id_manager::id_traits<T>::max)) if (auto place = allocate_id(get_tag<T>(), id_manager::id_traits<T>::min, id_manager::id_traits<T>::max))
@ -374,7 +389,7 @@ public:
if (LIKELY(ptr)) if (LIKELY(ptr))
{ {
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get())); id_manager::typeinfo::get_stop<T>()(static_cast<T*>(ptr.get()));
} }
return ptr.operator bool(); return ptr.operator bool();
@ -388,7 +403,7 @@ public:
if (LIKELY(ptr)) if (LIKELY(ptr))
{ {
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get())); id_manager::typeinfo::get_stop<T>()(static_cast<T*>(ptr.get()));
} }
return{ ptr, static_cast<T*>(ptr.get()) }; return{ ptr, static_cast<T*>(ptr.get()) };
@ -414,7 +429,7 @@ public:
g_map[get_type<T>()].erase(id); g_map[get_type<T>()].erase(id);
} }
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get())); id_manager::typeinfo::get_stop<T>()(static_cast<T*>(ptr.get()));
return{ ptr, static_cast<T*>(ptr.get()) }; return{ ptr, static_cast<T*>(ptr.get()) };
} }
@ -447,6 +462,8 @@ public:
template<typename T, typename Make = T, typename... Args> template<typename T, typename Make = T, typename... Args>
static std::enable_if_t<std::is_constructible<Make, Args...>::value, std::shared_ptr<T>> make(Args&&... args) static std::enable_if_t<std::is_constructible<Make, Args...>::value, std::shared_ptr<T>> make(Args&&... args)
{ {
id_manager::typeinfo::update<T>();
std::shared_ptr<T> ptr; std::shared_ptr<T> ptr;
{ {
writer_lock lock(g_mutex); writer_lock lock(g_mutex);
@ -471,6 +488,8 @@ public:
template<typename T, typename Make = T, typename... Args> template<typename T, typename Make = T, typename... Args>
static std::enable_if_t<std::is_constructible<Make, Args...>::value, std::shared_ptr<T>> make_always(Args&&... args) static std::enable_if_t<std::is_constructible<Make, Args...>::value, std::shared_ptr<T>> make_always(Args&&... args)
{ {
id_manager::typeinfo::update<T>();
std::shared_ptr<T> ptr; std::shared_ptr<T> ptr;
std::shared_ptr<void> old; std::shared_ptr<void> old;
{ {
@ -495,6 +514,8 @@ public:
template<typename T, typename F> template<typename T, typename F>
static auto import(F&& provider) -> decltype(static_cast<std::shared_ptr<T>>(provider())) static auto import(F&& provider) -> decltype(static_cast<std::shared_ptr<T>>(provider()))
{ {
id_manager::typeinfo::update<T>();
std::shared_ptr<T> ptr; std::shared_ptr<T> ptr;
{ {
writer_lock lock(g_mutex); writer_lock lock(g_mutex);
@ -519,6 +540,8 @@ public:
template<typename T, typename F> template<typename T, typename F>
static auto import_always(F&& provider) -> decltype(static_cast<std::shared_ptr<T>>(provider())) static auto import_always(F&& provider) -> decltype(static_cast<std::shared_ptr<T>>(provider()))
{ {
id_manager::typeinfo::update<T>();
std::shared_ptr<T> ptr; std::shared_ptr<T> ptr;
std::shared_ptr<void> old; std::shared_ptr<void> old;
{ {
@ -543,6 +566,8 @@ public:
template<typename T, typename Make = T, typename... Args> template<typename T, typename Make = T, typename... Args>
static std::enable_if_t<std::is_constructible<Make, Args...>::value, std::shared_ptr<T>> get_always(Args&&... args) static std::enable_if_t<std::is_constructible<Make, Args...>::value, std::shared_ptr<T>> get_always(Args&&... args)
{ {
id_manager::typeinfo::update<T>();
std::shared_ptr<T> ptr; std::shared_ptr<T> ptr;
{ {
writer_lock lock(g_mutex); writer_lock lock(g_mutex);
@ -591,7 +616,7 @@ public:
if (ptr) if (ptr)
{ {
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get())); id_manager::typeinfo::get_stop<T>()(static_cast<T*>(ptr.get()));
} }
return ptr.operator bool(); return ptr.operator bool();
@ -605,7 +630,7 @@ public:
if (ptr) if (ptr)
{ {
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get())); id_manager::typeinfo::get_stop<T>()(static_cast<T*>(ptr.get()));
} }
return{ ptr, static_cast<T*>(ptr.get()) }; return{ ptr, static_cast<T*>(ptr.get()) };