IdManager.cpp: Fix cellFs IDs

This commit is contained in:
Eladash 2022-09-04 15:29:35 +03:00 committed by Ivan
parent 72a6696f5c
commit 5e2424da58
3 changed files with 29 additions and 9 deletions

View file

@ -160,9 +160,10 @@ extern lv2_fs_mount_point g_mp_sys_dev_hdd1;
struct lv2_fs_object
{
static const u32 id_base = 3;
static const u32 id_step = 1;
static const u32 id_count = 255 - id_base;
static constexpr u32 id_base = 3;
static constexpr u32 id_step = 1;
static constexpr u32 id_count = 255 - id_base;
static constexpr bool id_lowest = true;
SAVESTATE_INIT_POS(40);
// File Name (max 1055)

View file

@ -29,7 +29,7 @@ std::vector<std::pair<u128, id_manager::typeinfo>>& id_manager::get_typeinfo_map
return s_map;
}
idm::map_data* idm::allocate_id(std::vector<map_data>& vec, u32 type_id, u32 dst_id, u32 base, u32 step, u32 count, std::pair<u32, u32> invl_range)
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)
{
if (const u32 index = id_manager::get_index(dst_id, base, step, count, invl_range); index < count)
{
@ -46,7 +46,12 @@ idm::map_data* idm::allocate_id(std::vector<map_data>& vec, u32 type_id, u32 dst
return &vec[index];
}
if (vec.size() < count)
if (uses_lowest_id)
{
// Disable the optimization below (hurts accuracy for known cases)
vec.resize(count);
}
else if (vec.size() < count)
{
// Try to emplace back
const u32 _next = base + step * ::size32(vec);

View file

@ -35,6 +35,18 @@ namespace id_manager
return T::id_invl_range;
}
template <typename T>
consteval bool get_force_lowest_id()
{
return false;
}
template <typename T> requires requires () { bool{T::id_lowest}; }
consteval bool get_force_lowest_id()
{
return T::id_lowest;
}
template <typename T>
concept IdmCompatible = requires () { T::id_base, T::id_step, T::id_count; };
@ -56,6 +68,7 @@ namespace id_manager
};
static constexpr std::pair<u32, u32> invl_range = get_invl_range<T>();
static constexpr bool uses_lowest_id = get_force_lowest_id<T>();
static_assert(count && step && u64{step} * (count - 1) + base < u32{umax} + u64{base != 0 ? 1 : 0}, "ID traits: invalid object range");
@ -130,6 +143,7 @@ namespace id_manager
u32 base;
u32 step;
u32 count;
bool uses_lowest_id;
std::pair<u32, u32> invl_range;
// Get type index
@ -168,7 +182,7 @@ namespace id_manager
+id_traits_load_func<C>::load,
+[](utils::serial& ar, void* obj) { static_cast<C*>(obj)->save(ar); },
+id_traits_savable_func<C>::savable,
id_traits<C>::base, id_traits<C>::step, id_traits<C>::count, id_traits<C>::invl_range,
id_traits<C>::base, id_traits<C>::step, id_traits<C>::count, id_traits<C>::uses_lowest_id, id_traits<C>::invl_range,
};
const u128 key = u128{get_type<C>()} << 64 | std::bit_cast<u64>(C::savestate_init_pos);
@ -192,7 +206,7 @@ namespace id_manager
nullptr,
nullptr,
nullptr,
id_traits<Type>::base, id_traits<Type>::step, id_traits<Type>::count, id_traits<Type>::invl_range,
id_traits<Type>::base, id_traits<Type>::step, id_traits<Type>::count, id_traits<Type>::uses_lowest_id, id_traits<Type>::invl_range,
};
}
@ -426,7 +440,7 @@ class idm
using map_data = std::pair<id_manager::id_key, std::shared_ptr<void>>;
// Prepare new ID (returns nullptr if out of resources)
static map_data* allocate_id(std::vector<map_data>& vec, u32 type_id, u32 dst_id, u32 base, u32 step, u32 count, std::pair<u32, u32> invl_range);
static map_data* 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);
// Get object by internal index if exists (additionally check type if types are not equal)
template <typename T, typename Type>
@ -485,7 +499,7 @@ class idm
auto& map = g_fxo->get<id_manager::id_map<T>>();
if (auto* place = allocate_id(map.vec, get_type<Type>(), id, traits::base, traits::step, traits::count, traits::invl_range))
if (auto* place = allocate_id(map.vec, get_type<Type>(), id, traits::base, traits::step, traits::count, traits::uses_lowest_id, traits::invl_range))
{
// Get object, store it
place->second = provider();