mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-12-28 09:23:34 +00:00
Fixed Object Manager (detached)
This commit is contained in:
parent
9923f96431
commit
f8afee3325
@ -17,3 +17,17 @@ namespace idm
|
||||
g_cur_id = 1; // first ID
|
||||
}
|
||||
}
|
||||
|
||||
namespace fxm
|
||||
{
|
||||
std::mutex g_fx_mutex;
|
||||
|
||||
std::unordered_map<std::type_index, std::shared_ptr<void>> g_fx_map;
|
||||
|
||||
void clear()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_fx_mutex);
|
||||
|
||||
g_fx_map.clear();
|
||||
}
|
||||
}
|
||||
|
@ -27,16 +27,9 @@ public:
|
||||
// ID Manager
|
||||
// 0 is invalid ID
|
||||
// 1..0x7fffffff : general purpose IDs
|
||||
// 0x80000000+ : occupied by fixed IDs
|
||||
// 0x80000000+ : reserved
|
||||
namespace idm
|
||||
{
|
||||
// for internal use
|
||||
inline u32 get_type_fixed_id(const std::type_info& type)
|
||||
{
|
||||
// TODO: better way of fixed ID generation
|
||||
return 0x80000000 | static_cast<u32>(type.hash_code());
|
||||
}
|
||||
|
||||
// reinitialize ID manager
|
||||
void clear();
|
||||
|
||||
@ -53,14 +46,6 @@ namespace idm
|
||||
return f != g_id_map.end() && f->second.info == typeid(T);
|
||||
}
|
||||
|
||||
// check if fixed ID exists
|
||||
template<typename T> bool check_fixed()
|
||||
{
|
||||
static const u32 id = get_type_fixed_id(typeid(T));
|
||||
|
||||
return check<T>(id);
|
||||
}
|
||||
|
||||
// must be called from the constructor called through make() or make_ptr() to get further ID of current object
|
||||
inline u32 get_current_id()
|
||||
{
|
||||
@ -75,37 +60,6 @@ namespace idm
|
||||
return g_cur_id & 0x7fffffff;
|
||||
}
|
||||
|
||||
// add fixed ID of specified type only if it doesn't exist (each type has unique id)
|
||||
template<typename T, typename... Args> std::enable_if_t<std::is_constructible<T, Args...>::value, std::shared_ptr<T>> make_fixed(Args&&... args)
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
|
||||
static const u32 id = get_type_fixed_id(typeid(T));
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
const auto found = g_id_map.find(id);
|
||||
|
||||
// ensure that this ID doesn't exist
|
||||
if (found == g_id_map.end())
|
||||
{
|
||||
auto ptr = std::make_shared<T>(std::forward<Args>(args)...);
|
||||
|
||||
g_id_map.emplace(id, ID_data_t(ptr));
|
||||
|
||||
return std::move(ptr);
|
||||
}
|
||||
|
||||
// ensure that this ID is not occupied by the object of another type
|
||||
if (found->second.info == typeid(T))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
throw EXCEPTION("Collision occured ('%s' and '%s', id=0x%x)", found->second.info.name(), typeid(T).name(), id);
|
||||
}
|
||||
|
||||
// add new ID of specified type with specified constructor arguments (returns object)
|
||||
template<typename T, typename... Args> std::enable_if_t<std::is_constructible<T, Args...>::value, std::shared_ptr<T>> make_ptr(Args&&... args)
|
||||
{
|
||||
@ -154,26 +108,6 @@ namespace idm
|
||||
throw EXCEPTION("Out of IDs");
|
||||
}
|
||||
|
||||
// get fixed ID of specified type
|
||||
template<typename T> std::shared_ptr<T> get_fixed()
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
static const u32 id = get_type_fixed_id(typeid(T));
|
||||
|
||||
const auto found = g_id_map.find(id);
|
||||
|
||||
if (found == g_id_map.end() || found->second.info != typeid(T))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::static_pointer_cast<T>(found->second.data);
|
||||
}
|
||||
|
||||
// get ID of specified type
|
||||
template<typename T> std::shared_ptr<T> get(u32 id)
|
||||
{
|
||||
@ -192,7 +126,7 @@ namespace idm
|
||||
return std::static_pointer_cast<T>(found->second.data);
|
||||
}
|
||||
|
||||
// load all IDs of specified type T
|
||||
// get all IDs of specified type T (unsorted)
|
||||
template<typename T> std::vector<std::shared_ptr<T>> get_all()
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
@ -235,14 +169,6 @@ namespace idm
|
||||
return true;
|
||||
}
|
||||
|
||||
// remove fixed ID created with type T
|
||||
template<typename T> bool remove_fixed()
|
||||
{
|
||||
static const u32 id = get_type_fixed_id(typeid(T));
|
||||
|
||||
return remove<T>(id);
|
||||
}
|
||||
|
||||
template<typename T> u32 get_count()
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
@ -310,4 +236,83 @@ namespace idm
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Fixed Object Manager
|
||||
// allows to manage shared objects of any specified type, but only one object per type;
|
||||
// object are deleted when the emulation is stopped
|
||||
namespace fxm
|
||||
{
|
||||
// reinitialize
|
||||
void clear();
|
||||
|
||||
// add fixed object of specified type only if it doesn't exist (one unique object per type may exist)
|
||||
template<typename T, typename... Args> std::enable_if_t<std::is_constructible<T, Args...>::value, std::shared_ptr<T>> make(Args&&... args)
|
||||
{
|
||||
extern std::mutex g_fx_mutex;
|
||||
extern std::unordered_map<std::type_index, std::shared_ptr<void>> g_fx_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_fx_mutex);
|
||||
|
||||
const auto found = g_fx_map.find(typeid(T));
|
||||
|
||||
// only if object of this type doesn't exist
|
||||
if (found == g_fx_map.end())
|
||||
{
|
||||
auto ptr = std::make_shared<T>(std::forward<Args>(args)...);
|
||||
|
||||
g_fx_map.emplace(typeid(T), ptr);
|
||||
|
||||
return std::move(ptr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// check whether the object exists
|
||||
template<typename T> bool check()
|
||||
{
|
||||
extern std::mutex g_fx_mutex;
|
||||
extern std::unordered_map<std::type_index, std::shared_ptr<void>> g_fx_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_fx_mutex);
|
||||
|
||||
return g_fx_map.find(typeid(T)) != g_fx_map.end();
|
||||
}
|
||||
|
||||
// get fixed object of specified type
|
||||
template<typename T> std::shared_ptr<T> get()
|
||||
{
|
||||
extern std::mutex g_fx_mutex;
|
||||
extern std::unordered_map<std::type_index, std::shared_ptr<void>> g_fx_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_fx_mutex);
|
||||
|
||||
const auto found = g_fx_map.find(typeid(T));
|
||||
|
||||
if (found == g_fx_map.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::static_pointer_cast<T>(found->second);
|
||||
}
|
||||
|
||||
// remove fixed object created with type T
|
||||
template<typename T> bool remove()
|
||||
{
|
||||
extern std::mutex g_fx_mutex;
|
||||
extern std::unordered_map<std::type_index, std::shared_ptr<void>> g_fx_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_fx_mutex);
|
||||
|
||||
const auto found = g_fx_map.find(typeid(T));
|
||||
|
||||
if (found == g_fx_map.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return g_fx_map.erase(found), true;
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ s32 cellCameraInit()
|
||||
return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
const auto camera = idm::make_fixed<camera_t>();
|
||||
const auto camera = fxm::make<camera_t>();
|
||||
|
||||
if (!camera)
|
||||
{
|
||||
@ -138,7 +138,7 @@ s32 cellCameraEnd()
|
||||
{
|
||||
cellCamera.Warning("cellCameraEnd()");
|
||||
|
||||
if (!idm::remove_fixed<camera_t>())
|
||||
if (!fxm::remove<camera_t>())
|
||||
{
|
||||
return CELL_CAMERA_ERROR_NOT_INIT;
|
||||
}
|
||||
@ -174,7 +174,7 @@ s32 cellCameraGetType(s32 dev_num, vm::ptr<s32> type)
|
||||
{
|
||||
cellCamera.Warning("cellCameraGetType(dev_num=%d, type=*0x%x)", dev_num, type);
|
||||
|
||||
const auto camera = idm::get_fixed<camera_t>();
|
||||
const auto camera = fxm::get<camera_t>();
|
||||
|
||||
if (!camera)
|
||||
{
|
||||
@ -228,7 +228,7 @@ s32 cellCameraGetAttribute(s32 dev_num, s32 attrib, vm::ptr<u32> arg1, vm::ptr<u
|
||||
|
||||
const auto attr_name = get_camera_attr_name(attrib);
|
||||
|
||||
const auto camera = idm::get_fixed<camera_t>();
|
||||
const auto camera = fxm::get<camera_t>();
|
||||
|
||||
if (!camera)
|
||||
{
|
||||
@ -252,7 +252,7 @@ s32 cellCameraSetAttribute(s32 dev_num, s32 attrib, u32 arg1, u32 arg2)
|
||||
|
||||
const auto attr_name = get_camera_attr_name(attrib);
|
||||
|
||||
const auto camera = idm::get_fixed<camera_t>();
|
||||
const auto camera = fxm::get<camera_t>();
|
||||
|
||||
if (!camera)
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ s32 cellRudpInit(vm::ptr<CellRudpAllocator> allocator)
|
||||
{
|
||||
cellRudp.Warning("cellRudpInit(allocator=*0x%x)", allocator);
|
||||
|
||||
const auto rudp = idm::make_fixed<rudp_t>();
|
||||
const auto rudp = fxm::make<rudp_t>();
|
||||
|
||||
if (!rudp)
|
||||
{
|
||||
@ -59,7 +59,7 @@ s32 cellRudpEnd()
|
||||
{
|
||||
cellRudp.Warning("cellRudpEnd()");
|
||||
|
||||
if (!idm::remove_fixed<rudp_t>())
|
||||
if (!fxm::remove<rudp_t>())
|
||||
{
|
||||
return CELL_RUDP_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
@ -77,7 +77,7 @@ s32 cellRudpSetEventHandler(vm::ptr<CellRudpEventHandler> handler, vm::ptr<void>
|
||||
{
|
||||
cellRudp.Todo("cellRudpSetEventHandler(handler=*0x%x, arg=*0x%x)", handler, arg);
|
||||
|
||||
const auto rudp = idm::get_fixed<rudp_t>();
|
||||
const auto rudp = fxm::get<rudp_t>();
|
||||
|
||||
if (!rudp)
|
||||
{
|
||||
|
@ -374,8 +374,9 @@ void Emulator::Stop()
|
||||
LOG_NOTICE(GENERAL, "All threads stopped...");
|
||||
|
||||
idm::clear();
|
||||
fxm::clear();
|
||||
|
||||
LOG_NOTICE(GENERAL, "ID manager cleared...");
|
||||
LOG_NOTICE(GENERAL, "Objects cleared...");
|
||||
|
||||
finalize_psv_modules();
|
||||
clear_all_psv_objects();
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <forward_list>
|
||||
#include <typeindex>
|
||||
|
||||
#include "Utilities/GNU.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user