2016-04-27 00:27:24 +02:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "IdManager.h"
|
2018-10-11 00:17:19 +02:00
|
|
|
#include "Utilities/Thread.h"
|
2016-04-27 00:27:24 +02:00
|
|
|
|
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);
|
2016-05-13 16:01:48 +02:00
|
|
|
|
2017-01-29 17:50:18 +01:00
|
|
|
id_manager::id_map::pointer idm::allocate_id(const id_manager::id_key& info, u32 base, u32 step, u32 count)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-29 17:50:18 +01:00
|
|
|
// Base type id is stored in value
|
|
|
|
|
auto& vec = g_map[info.value()];
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-29 17:50:18 +01:00
|
|
|
// Preallocate memory
|
|
|
|
|
vec.reserve(count);
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-29 17:50:18 +01:00
|
|
|
if (vec.size() < count)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-29 17:50:18 +01:00
|
|
|
// Try to emplace back
|
|
|
|
|
const u32 _next = base + step * ::size32(vec);
|
2017-01-25 18:50:30 +01:00
|
|
|
|
2017-01-29 17:50:18 +01:00
|
|
|
if (_next >= base && _next < base + step * count)
|
2017-01-25 18:50:30 +01:00
|
|
|
{
|
2017-01-29 17:50:18 +01:00
|
|
|
g_id = _next;
|
2018-10-11 00:17:19 +02:00
|
|
|
vec.emplace_back(id_manager::id_key(_next, info.type()), nullptr);
|
2017-01-29 17:50:18 +01:00
|
|
|
return &vec.back();
|
2017-01-25 18:50:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check all IDs starting from "next id" (TODO)
|
2017-01-29 17:50:18 +01:00
|
|
|
for (u32 i = 0, next = base; i < count; i++, next += step)
|
2017-01-25 18:50:30 +01:00
|
|
|
{
|
2017-01-29 17:50:18 +01:00
|
|
|
const auto ptr = &vec[i];
|
2016-04-27 00:27:24 +02:00
|
|
|
|
2017-01-29 17:50:18 +01:00
|
|
|
// Look for free ID
|
|
|
|
|
if (!ptr->second)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
g_id = next;
|
2018-10-11 00:17:19 +02:00
|
|
|
ptr->first = id_manager::id_key(next, info.type());
|
2017-01-29 17:50:18 +01:00
|
|
|
return ptr;
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-29 17:50:18 +01:00
|
|
|
// Out of IDs
|
2017-01-26 02:03:03 +01:00
|
|
|
return nullptr;
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void idm::init()
|
|
|
|
|
{
|
2017-01-29 17:50:18 +01:00
|
|
|
// Allocate
|
|
|
|
|
g_map.resize(id_manager::typeinfo::get_count());
|
2017-08-06 12:13:12 +02:00
|
|
|
idm::clear();
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void idm::clear()
|
|
|
|
|
{
|
|
|
|
|
// Call recorded finalization functions for all IDs
|
2017-01-29 17:50:18 +01:00
|
|
|
for (auto& map : g_map)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2017-01-29 17:50:18 +01:00
|
|
|
for (auto& pair : map)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2018-10-11 00:17:19 +02:00
|
|
|
pair.second.reset();
|
|
|
|
|
pair.first = {};
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
|
2017-01-29 17:50:18 +01:00
|
|
|
map.clear();
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
|
|
|
|
}
|