IdManager bugfixed

This commit is contained in:
Nekotekina 2017-01-28 17:59:43 +03:00
parent d4c3905355
commit 4203f53b67
2 changed files with 28 additions and 20 deletions

View File

@ -37,7 +37,7 @@ id_manager::id_map::pointer idm::allocate_id(std::pair<u32, u32> types, u32 base
return nullptr;
}
const u32 _next = map.rbegin()->first.id() + step;
const u32 _next = next + step * count;
if (_next > base && _next < base + step * count)
{
@ -46,9 +46,15 @@ id_manager::id_map::pointer idm::allocate_id(std::pair<u32, u32> types, u32 base
}
// Check all IDs starting from "next id" (TODO)
for (next; next < base + step * count; next += step)
for (u32 i = 0; i < count; i++, next += step)
{
// Get ID
// Get correct ID value
if (next >= base + step * count)
{
next = base;
}
// Try to allocate ID storage
const auto result = map.emplace(id_manager::id_key(next, types.second), nullptr);
if (result.second)
@ -64,9 +70,9 @@ id_manager::id_map::pointer idm::allocate_id(std::pair<u32, u32> types, u32 base
return nullptr;
}
id_manager::id_map::pointer idm::find_id(u32 type, u32 true_type, u32 id)
id_manager::id_map::const_pointer idm::find_id(u32 type, u32 true_type, u32 id)
{
auto& map = g_map[type];
const auto& map = g_map[type];
const auto found = map.find(id);

View File

@ -5,7 +5,7 @@
#include <memory>
#include <vector>
#include <map>
#include <unordered_map>
// idm/fxm: helper namespace
namespace id_manager
@ -149,7 +149,15 @@ namespace id_manager
}
};
using id_map = std::map<id_key, std::shared_ptr<void>>;
struct id_hash
{
std::size_t operator()(const id_key& id) const
{
return id ^ (id >> 8);
}
};
using id_map = std::unordered_map<id_key, std::shared_ptr<void>, id_hash>;
}
// Object manager for emulated process. Multiple objects of specified arbitrary type are given unique IDs.
@ -236,7 +244,7 @@ class idm
static std::shared_ptr<void> delete_id(u32 type, u32 true_type, u32 id);
// Get ID (additionally check true_type if not equal)
static id_manager::id_map::pointer find_id(u32 type, u32 true_type, u32 id);
static id_manager::id_map::const_pointer find_id(u32 type, u32 true_type, u32 id);
// Allocate new ID and assign the object from the provider()
template<typename T, typename Type, typename F>
@ -509,28 +517,26 @@ public:
template<typename T, typename Get = T>
static inline explicit_bool_t remove(u32 id)
{
auto ptr = delete_id(get_type<T>(), get_type<Get>(), id);
if (LIKELY(ptr))
if (auto ptr = (writer_lock{id_manager::g_mutex}, delete_id(get_type<T>(), get_type<Get>(), id)))
{
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get()));
return true;
}
return ptr.operator bool();
return false;
}
// Remove the ID and return the object
template<typename T, typename Get = T>
static inline std::shared_ptr<Get> withdraw(u32 id)
{
auto ptr = delete_id(get_type<T>(), get_type<Get>(), id);
if (LIKELY(ptr))
if (auto ptr = (writer_lock{id_manager::g_mutex}, delete_id(get_type<T>(), get_type<Get>(), id)))
{
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get()));
return {ptr, static_cast<Get*>(ptr.get())};
}
return {ptr, static_cast<Get*>(ptr.get())};
return nullptr;
}
// Remove the ID after accessing the object under writer lock, return the object and propagate return value
@ -553,8 +559,6 @@ public:
func(*static_cast<Get*>(found->second.get()));
ptr = delete_id(get_type<T>(), get_type<Get>(), id);
g_map[get_type<T>()].erase(id);
}
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get()));
@ -590,8 +594,6 @@ public:
}
ptr = delete_id(get_type<T>(), get_type<Get>(), id);
g_map[get_type<T>()].erase(id);
}
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get()));