diff --git a/rpcs3/Emu/IdManager.cpp b/rpcs3/Emu/IdManager.cpp index 636eac6b34..3c287716e3 100644 --- a/rpcs3/Emu/IdManager.cpp +++ b/rpcs3/Emu/IdManager.cpp @@ -24,7 +24,7 @@ u32 id_manager::typeinfo::add_type() return ::size32(list) - 1; } -idm::map_type::pointer idm::allocate_id(u32 tag, u32 min, u32 max) +id_manager::id_map::pointer idm::allocate_id(u32 tag, u32 min, u32 max) { // Check all IDs starting from "next id" for (u32 i = 0; i <= max - min; i++) @@ -58,7 +58,7 @@ std::shared_ptr idm::deallocate_id(u32 tag, u32 id) return ptr; } -idm::map_type::pointer idm::find_id(u32 type, u32 id) +id_manager::id_map::pointer idm::find_id(u32 type, u32 id) { const auto found = g_map[type].find(id); diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index ce86d726fb..0a1eb22d21 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -112,6 +112,53 @@ namespace id_manager template const u32 typeinfo::registered::index = typeinfo::add_type(); + + // ID value with additional type stored + class id_key + { + u32 m_value; // ID value + u32 m_type; // True object type + + public: + id_key() = default; + + id_key(u32 value, u32 type = 0) + : m_value(value) + , m_type(type) + { + } + + u32 id() const + { + return m_value; + } + + u32 type() const + { + return m_type; + } + + bool operator ==(const id_key& rhs) const + { + return m_value == rhs.m_value; + } + + bool operator !=(const id_key& rhs) const + { + return m_value != rhs.m_value; + } + }; + + // Custom hasher for ID values + struct id_hash final + { + std::size_t operator ()(const id_key& key) const + { + return key.id(); + } + }; + + using id_map = std::unordered_map, id_hash>; } // Object manager for emulated process. Multiple objects of specified arbitrary type are given unique IDs. @@ -123,21 +170,10 @@ class idm // 2) g_id[id_base] indicates next ID allocated in g_map. // 3) g_map[id_base] contains the additional copy of object pointer. - // Custom hasher for ID values - struct id_hash_t final - { - std::size_t operator ()(u32 value) const - { - return value; - } - }; - - using map_type = std::unordered_map, id_hash_t>; - static shared_mutex g_mutex; // Type Index -> ID -> Object. Use global since only one process is supported atm. - static std::vector g_map; + static std::vector g_map; // Next ID for each category static std::vector g_id; @@ -192,14 +228,14 @@ class idm }; // Prepares new ID, returns nullptr if out of resources - static map_type::pointer allocate_id(u32 tag, u32 min, u32 max); + static id_manager::id_map::pointer allocate_id(u32 tag, u32 min, u32 max); // Deallocate ID, returns object static std::shared_ptr deallocate_id(u32 tag, u32 id); // Allocate new ID and construct it from the provider() template - static map_type::pointer create_id(F&& provider) + static id_manager::id_map::pointer create_id(F&& provider) { id_manager::typeinfo::update(); id_manager::typeinfo::update::tag>(); @@ -214,13 +250,13 @@ class idm place->second = provider(); // Update ID value if required - set_id_value(static_cast(place->second.get()), place->first); + set_id_value(static_cast(place->second.get()), place->first.id()); return &*g_map[get_type()].emplace(*place).first; } catch (...) { - deallocate_id(get_tag(), place->first); + deallocate_id(get_tag(), place->first.id()); throw; } } @@ -229,7 +265,7 @@ class idm } // Get ID (internal) - static map_type::pointer find_id(u32 type, u32 id); + static id_manager::id_map::pointer find_id(u32 type, u32 id); // Remove ID and return object static std::shared_ptr delete_id(u32 type, u32 tag, u32 id); @@ -263,7 +299,7 @@ public: { id_manager::on_init::func(static_cast(pair->second.get()), pair->second); id_manager::on_stop::func(nullptr); - return pair->first; + return pair->first.id(); } throw EXCEPTION("Out of IDs ('%s')", typeid(T).name()); @@ -277,7 +313,7 @@ public: { id_manager::on_init::func(static_cast(pair->second.get()), pair->second); id_manager::on_stop::func(nullptr); - return pair->first; + return pair->first.id(); } throw EXCEPTION("Out of IDs ('%s')", typeid(T).name()); @@ -357,7 +393,7 @@ public: { for (auto& id : g_map[type]) { - if (pred(id.first, *static_cast(id.second.get())), bool_if_void()) + if (pred(id.first.id(), *static_cast(id.second.get())), bool_if_void()) { return static_cast(std::static_pointer_cast(id.second)); }