2020-12-05 13:08:24 +01:00
|
|
|
#include "stdafx.h"
|
2016-04-27 00:27:24 +02:00
|
|
|
#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
|
|
|
|
2022-07-04 15:02:17 +02:00
|
|
|
namespace id_manager
|
|
|
|
|
{
|
|
|
|
|
thread_local u32 g_id = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-05 13:12:21 +02:00
|
|
|
template <>
|
|
|
|
|
bool serialize<std::shared_ptr<utils::serial>>(utils::serial& ar, std::shared_ptr<utils::serial>& o)
|
|
|
|
|
{
|
|
|
|
|
if (!o || !ar.is_writing())
|
|
|
|
|
{
|
|
|
|
|
o.reset();
|
|
|
|
|
o = std::make_shared<utils::serial>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ar(o->data);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-04 15:02:17 +02:00
|
|
|
std::vector<std::pair<u128, id_manager::typeinfo>>& id_manager::get_typeinfo_map()
|
|
|
|
|
{
|
|
|
|
|
// Magic static
|
|
|
|
|
static std::vector<std::pair<u128, id_manager::typeinfo>> s_map;
|
2023-02-13 11:33:06 +01:00
|
|
|
return s_map;
|
2022-07-04 15:02:17 +02:00
|
|
|
}
|
2016-05-13 16:01:48 +02:00
|
|
|
|
2022-09-04 14:29:35 +02:00
|
|
|
idm::map_data* idm::allocate_id(std::vector<map_data>& vec, u32 type_id, u32 dst_id, u32 base, u32 step, u32 count, bool uses_lowest_id, std::pair<u32, u32> invl_range)
|
2016-04-27 00:27:24 +02:00
|
|
|
{
|
2022-07-04 15:02:17 +02:00
|
|
|
if (const u32 index = id_manager::get_index(dst_id, base, step, count, invl_range); index < count)
|
|
|
|
|
{
|
|
|
|
|
// Fixed position construction
|
|
|
|
|
ensure(index < vec.size());
|
|
|
|
|
|
|
|
|
|
if (vec[index].second)
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
id_manager::g_id = dst_id;
|
|
|
|
|
vec[index] = {id_manager::id_key(dst_id, type_id), nullptr};
|
|
|
|
|
return &vec[index];
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-04 14:29:35 +02:00
|
|
|
if (uses_lowest_id)
|
|
|
|
|
{
|
|
|
|
|
// Disable the optimization below (hurts accuracy for known cases)
|
|
|
|
|
vec.resize(count);
|
|
|
|
|
}
|
|
|
|
|
else 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);
|
2022-07-04 15:02:17 +02:00
|
|
|
id_manager::g_id = _next;
|
2021-03-30 18:37:51 +02:00
|
|
|
vec.emplace_back(id_manager::id_key(_next, type_id), nullptr);
|
2019-12-13 03:00:31 +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
|
|
|
{
|
2019-11-28 11:17:16 +01:00
|
|
|
// Incremenet ID invalidation counter
|
|
|
|
|
const u32 id = next | ((ptr->first + (1u << invl_range.first)) & (invl_range.second ? (((1u << invl_range.second) - 1) << invl_range.first) : 0));
|
2022-07-04 15:02:17 +02:00
|
|
|
id_manager::g_id = id;
|
2021-03-30 18:37:51 +02:00
|
|
|
ptr->first = id_manager::id_key(id, type_id);
|
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
|
|
|
}
|