2016-04-27 00:27:24 +02:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "IdManager.h"
|
|
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
shared_mutex id_manager::g_mutex;
|
2016-05-13 16:01:48 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
thread_local DECLARE(idm::g_id);
|
|
|
|
|
DECLARE(idm::g_map);
|
|
|
|
|
DECLARE(fxm::g_vec);
|
2016-05-13 16:01:48 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
std::vector<id_manager::typeinfo>& id_manager::typeinfo::access()
|
|
|
|
|
{
|
|
|
|
|
static std::vector<typeinfo> list;
|
2016-05-13 16:01:48 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-21 10:22:30 +02:00
|
|
|
u32 id_manager::typeinfo::add_type()
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
|
|
|
|
auto& list = access();
|
|
|
|
|
|
2016-06-21 10:22:30 +02:00
|
|
|
list.emplace_back();
|
2016-04-27 00:27:24 +02:00
|
|
|
|
|
|
|
|
return ::size32(list) - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
id_manager::id_map::pointer idm::allocate_id(std::pair<u32, u32> types, u32 base, u32 step, u32 count)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
auto& map = g_map[types.first];
|
|
|
|
|
|
|
|
|
|
// Assume next ID
|
|
|
|
|
u32 next = base;
|
|
|
|
|
|
|
|
|
|
if (std::size_t _count = map.size())
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
if (_count >= count)
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const u32 _next = map.rbegin()->first.id() + step;
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
if (_next > base && _next < base + step * count)
|
|
|
|
|
{
|
|
|
|
|
next = _next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check all IDs starting from "next id" (TODO)
|
|
|
|
|
for (next; next < base + step * count; next += step)
|
|
|
|
|
{
|
2016-04-27 00:27:24 +02:00
|
|
|
// Get ID
|
2017-01-25 18:50:30 +01:00
|
|
|
const auto result = map.emplace(id_manager::id_key(next, types.second), nullptr);
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
if (result.second)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
// Acknowledge the ID
|
|
|
|
|
g_id = next;
|
|
|
|
|
|
|
|
|
|
return std::addressof(*result.first);
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Nothing found
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
id_manager::id_map::pointer idm::find_id(u32 type, u32 id)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
auto& map = g_map[type];
|
|
|
|
|
|
|
|
|
|
const auto found = map.find(id);
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
return found == map.end() ? nullptr : std::addressof(*found);
|
|
|
|
|
}
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
id_manager::id_map::pointer idm::find_id(u32 type, u32 true_type, u32 id)
|
|
|
|
|
{
|
|
|
|
|
auto& map = g_map[type];
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
const auto found = map.find(id);
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
return found == map.end() || found->first.type() != true_type ? nullptr : std::addressof(*found);
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
std::shared_ptr<void> idm::delete_id(u32 type, u32 id)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
auto& map = g_map[type];
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
const auto found = map.find(id);
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
std::shared_ptr<void> result;
|
|
|
|
|
|
|
|
|
|
if (found != map.end())
|
|
|
|
|
{
|
|
|
|
|
result = std::move(found->second);
|
|
|
|
|
map.erase(found);
|
|
|
|
|
}
|
2016-08-01 01:26:55 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
return result;
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
std::shared_ptr<void> idm::delete_id(u32 type, u32 true_type, u32 id)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
auto& map = g_map[type];
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
const auto found = map.find(id);
|
2016-08-01 01:26:55 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
std::shared_ptr<void> result;
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
if (found != map.end() && found->first.type() == true_type)
|
|
|
|
|
{
|
|
|
|
|
result = std::move(found->second);
|
|
|
|
|
map.erase(found);
|
|
|
|
|
}
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
return result;
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void idm::init()
|
|
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
g_map.resize(id_manager::typeinfo::get().size());
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void idm::clear()
|
|
|
|
|
{
|
|
|
|
|
// Call recorded finalization functions for all IDs
|
|
|
|
|
for (std::size_t i = 0; i < g_map.size(); i++)
|
|
|
|
|
{
|
2016-06-25 07:16:15 +02:00
|
|
|
const auto on_stop = id_manager::typeinfo::get()[i].on_stop;
|
|
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
for (auto& id : g_map[i])
|
|
|
|
|
{
|
2016-06-25 07:16:15 +02:00
|
|
|
on_stop(id.second.get());
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_map[i].clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fxm::init()
|
|
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
g_vec.resize(id_manager::typeinfo::get().size(), {});
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fxm::clear()
|
|
|
|
|
{
|
|
|
|
|
// Call recorded finalization functions for all IDs
|
2017-01-25 18:50:30 +01:00
|
|
|
for (std::size_t i = 0; i < g_vec.size(); i++)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
if (g_vec[i])
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
id_manager::typeinfo::get()[i].on_stop(g_vec[i].get());
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
2017-01-25 18:50:30 +01:00
|
|
|
g_vec[i].reset();
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
}
|