mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
id_manager: embedded RTTI
This commit is contained in:
parent
e585939ac2
commit
e6bd91ada0
@ -558,9 +558,9 @@ s32 cellAdecOpen(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResource> res, vm::
|
||||
return CELL_ADEC_ERROR_ARG;
|
||||
}
|
||||
|
||||
auto&& adec = std::make_shared<AudioDecoder>(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg);
|
||||
auto&& adec = idm::make_ptr<ppu_thread, AudioDecoder>(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg);
|
||||
|
||||
*handle = idm::import_existing<ppu_thread>(adec);
|
||||
*handle = adec->id;
|
||||
|
||||
adec->run();
|
||||
|
||||
@ -576,9 +576,9 @@ s32 cellAdecOpenEx(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResourceEx> res,
|
||||
return CELL_ADEC_ERROR_ARG;
|
||||
}
|
||||
|
||||
auto&& adec = std::make_shared<AudioDecoder>(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg);
|
||||
auto&& adec = idm::make_ptr<ppu_thread, AudioDecoder>(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg);
|
||||
|
||||
*handle = idm::import_existing<ppu_thread>(adec);
|
||||
*handle = adec->id;
|
||||
|
||||
adec->run();
|
||||
|
||||
|
@ -976,9 +976,9 @@ s32 cellDmuxOpen(vm::cptr<CellDmuxType> type, vm::cptr<CellDmuxResource> res, vm
|
||||
}
|
||||
|
||||
// TODO: check demuxerResource and demuxerCb arguments
|
||||
auto&& dmux = std::make_shared<Demuxer>(res->memAddr, res->memSize, cb->cbMsgFunc, cb->cbArg);
|
||||
auto&& dmux = idm::make_ptr<ppu_thread, Demuxer>(res->memAddr, res->memSize, cb->cbMsgFunc, cb->cbArg);
|
||||
|
||||
*handle = idm::import_existing<ppu_thread>(dmux);
|
||||
*handle = dmux->id;
|
||||
|
||||
dmux->run();
|
||||
|
||||
@ -995,9 +995,9 @@ s32 cellDmuxOpenEx(vm::cptr<CellDmuxType> type, vm::cptr<CellDmuxResourceEx> res
|
||||
}
|
||||
|
||||
// TODO: check demuxerResourceEx and demuxerCb arguments
|
||||
auto&& dmux = std::make_shared<Demuxer>(resEx->memAddr, resEx->memSize, cb->cbMsgFunc, cb->cbArg);
|
||||
auto&& dmux = idm::make_ptr<ppu_thread, Demuxer>(resEx->memAddr, resEx->memSize, cb->cbMsgFunc, cb->cbArg);
|
||||
|
||||
*handle = idm::import_existing<ppu_thread>(dmux);
|
||||
*handle = dmux->id;
|
||||
|
||||
dmux->run();
|
||||
|
||||
@ -1021,9 +1021,9 @@ s32 cellDmuxOpen2(vm::cptr<CellDmuxType2> type2, vm::cptr<CellDmuxResource2> res
|
||||
}
|
||||
|
||||
// TODO: check demuxerType2, demuxerResource2 and demuxerCb arguments
|
||||
auto&& dmux = std::make_shared<Demuxer>(res2->memAddr, res2->memSize, cb->cbMsgFunc, cb->cbArg);
|
||||
auto&& dmux = idm::make_ptr<ppu_thread, Demuxer>(res2->memAddr, res2->memSize, cb->cbMsgFunc, cb->cbArg);
|
||||
|
||||
*handle = idm::import_existing<ppu_thread>(dmux);
|
||||
*handle = dmux->id;
|
||||
|
||||
dmux->run();
|
||||
|
||||
|
@ -737,12 +737,12 @@ struct fs_aio_thread : ppu_thread
|
||||
|
||||
struct fs_aio_manager
|
||||
{
|
||||
std::shared_ptr<fs_aio_thread> t = std::make_shared<fs_aio_thread>("FS AIO Thread", 500);
|
||||
std::shared_ptr<fs_aio_thread> thread;
|
||||
|
||||
fs_aio_manager()
|
||||
: thread(idm::make_ptr<ppu_thread, fs_aio_thread>("FS AIO Thread", 500))
|
||||
{
|
||||
idm::import_existing<ppu_thread>(t);
|
||||
t->run();
|
||||
thread->run();
|
||||
}
|
||||
};
|
||||
|
||||
@ -779,13 +779,13 @@ s32 cellFsAioRead(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, fs_aio_cb_t func)
|
||||
|
||||
const auto m = fxm::get_always<fs_aio_manager>();
|
||||
|
||||
m->t->cmd_list
|
||||
m->thread->cmd_list
|
||||
({
|
||||
{ 1, xid },
|
||||
{ aio, func },
|
||||
});
|
||||
|
||||
m->t->lock_notify();
|
||||
m->thread->lock_notify();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -800,13 +800,13 @@ s32 cellFsAioWrite(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, fs_aio_cb_t func)
|
||||
|
||||
const auto m = fxm::get_always<fs_aio_manager>();
|
||||
|
||||
m->t->cmd_list
|
||||
m->thread->cmd_list
|
||||
({
|
||||
{ 2, xid },
|
||||
{ aio, func },
|
||||
});
|
||||
|
||||
m->t->lock_notify();
|
||||
m->thread->lock_notify();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -607,9 +607,9 @@ s32 _spurs::create_handler(vm::ptr<CellSpurs> spurs, u32 ppuPriority)
|
||||
}
|
||||
};
|
||||
|
||||
auto&& eht = std::make_shared<handler_thread>(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr0", ppuPriority, 0x4000);
|
||||
auto&& eht = idm::make_ptr<ppu_thread, handler_thread>(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr0", ppuPriority, 0x4000);
|
||||
|
||||
spurs->ppu0 = idm::import_existing<ppu_thread>(eht);
|
||||
spurs->ppu0 = eht->id;
|
||||
|
||||
eht->gpr[3] = spurs.addr();
|
||||
eht->run();
|
||||
@ -804,11 +804,9 @@ s32 _spurs::create_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs, u32 p
|
||||
}
|
||||
};
|
||||
|
||||
auto&& eht = std::make_shared<event_helper_thread>(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr1", ppuPriority, 0x8000);
|
||||
auto&& eht = idm::make_ptr<ppu_thread, event_helper_thread>(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr1", ppuPriority, 0x8000);
|
||||
|
||||
const u32 tid = idm::import_existing<ppu_thread>(eht);
|
||||
|
||||
if (tid == 0)
|
||||
if (!eht)
|
||||
{
|
||||
sys_event_port_disconnect(spurs->eventPort);
|
||||
sys_event_port_destroy(spurs->eventPort);
|
||||
@ -825,7 +823,7 @@ s32 _spurs::create_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs, u32 p
|
||||
eht->gpr[3] = spurs.addr();
|
||||
eht->run();
|
||||
|
||||
spurs->ppu1 = tid;
|
||||
spurs->ppu1 = eht->id;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -399,10 +399,10 @@ s32 cellVdecOpen(vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm
|
||||
cellVdec.warning("cellVdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
|
||||
|
||||
// Create decoder thread
|
||||
auto&& vdec = std::make_shared<vdec_thread>(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg);
|
||||
auto&& vdec = idm::make_ptr<ppu_thread, vdec_thread>(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg);
|
||||
|
||||
// Hack: store thread id (normally it should be pointer)
|
||||
*handle = idm::import_existing<ppu_thread>(vdec);
|
||||
*handle = vdec->id;
|
||||
|
||||
vdec->run();
|
||||
|
||||
@ -414,10 +414,10 @@ s32 cellVdecOpenEx(vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> r
|
||||
cellVdec.warning("cellVdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
|
||||
|
||||
// Create decoder thread
|
||||
auto&& vdec = std::make_shared<vdec_thread>(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg);
|
||||
auto&& vdec = idm::make_ptr<ppu_thread, vdec_thread>(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg);
|
||||
|
||||
// Hack: store thread id (normally it should be pointer)
|
||||
*handle = idm::import_existing<ppu_thread>(vdec);
|
||||
*handle = vdec->id;
|
||||
|
||||
vdec->run();
|
||||
|
||||
@ -428,7 +428,7 @@ s32 cellVdecClose(u32 handle)
|
||||
{
|
||||
cellVdec.warning("cellVdecClose(handle=0x%x)", handle);
|
||||
|
||||
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
|
||||
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
|
||||
|
||||
if (!vdec)
|
||||
{
|
||||
@ -446,7 +446,7 @@ s32 cellVdecStartSeq(u32 handle)
|
||||
{
|
||||
cellVdec.trace("cellVdecStartSeq(handle=0x%x)", handle);
|
||||
|
||||
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
|
||||
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
|
||||
|
||||
if (!vdec)
|
||||
{
|
||||
@ -462,7 +462,7 @@ s32 cellVdecEndSeq(u32 handle)
|
||||
{
|
||||
cellVdec.warning("cellVdecEndSeq(handle=0x%x)", handle);
|
||||
|
||||
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
|
||||
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
|
||||
|
||||
if (!vdec)
|
||||
{
|
||||
@ -478,7 +478,7 @@ s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInf
|
||||
{
|
||||
cellVdec.trace("cellVdecDecodeAu(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, mode, auInfo);
|
||||
|
||||
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
|
||||
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
|
||||
|
||||
if (mode > CELL_VDEC_DEC_MODE_PB_SKIP || !vdec)
|
||||
{
|
||||
@ -509,7 +509,7 @@ s32 cellVdecGetPicture(u32 handle, vm::cptr<CellVdecPicFormat> format, vm::ptr<u
|
||||
{
|
||||
cellVdec.trace("cellVdecGetPicture(handle=0x%x, format=*0x%x, outBuff=*0x%x)", handle, format, outBuff);
|
||||
|
||||
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
|
||||
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
|
||||
|
||||
if (!format || !vdec)
|
||||
{
|
||||
@ -629,7 +629,7 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
|
||||
{
|
||||
cellVdec.trace("cellVdecGetPicItem(handle=0x%x, picItem=**0x%x)", handle, picItem);
|
||||
|
||||
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
|
||||
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
|
||||
|
||||
if (!vdec)
|
||||
{
|
||||
@ -824,7 +824,7 @@ s32 cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc)
|
||||
{
|
||||
cellVdec.trace("cellVdecSetFrameRate(handle=0x%x, frc=0x%x)", handle, frc);
|
||||
|
||||
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
|
||||
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
|
||||
|
||||
if (!vdec)
|
||||
{
|
||||
|
@ -489,9 +489,7 @@ s32 cellSurMixerCreate(vm::cptr<CellSurMixerConfig> config)
|
||||
|
||||
libmixer.warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)", config->chStrips1, config->chStrips2, config->chStrips6, config->chStrips8);
|
||||
|
||||
auto&& thread = std::make_shared<surmixer_thread>("Surmixer Thread");
|
||||
|
||||
idm::import_existing<ppu_thread>(thread);
|
||||
auto&& thread = idm::make_ptr<ppu_thread, surmixer_thread>("Surmixer Thread");
|
||||
|
||||
thread->run();
|
||||
|
||||
|
@ -80,6 +80,7 @@ std::string ppu_thread::dump() const
|
||||
{
|
||||
std::string ret;
|
||||
|
||||
ret += fmt::format("Type: %s\n", typeid(*this).name());
|
||||
ret += fmt::format("State: 0x%08x\n", state.load());
|
||||
ret += fmt::format("Priority: %d\n", prio);
|
||||
|
||||
|
@ -24,7 +24,7 @@ u32 id_manager::typeinfo::add_type()
|
||||
return ::size32(list) - 1;
|
||||
}
|
||||
|
||||
id_manager::id_map::pointer idm::allocate_id(u32 tag, u32 min, u32 max)
|
||||
id_manager::id_map::pointer idm::allocate_id(u32 tag, u32 type, u32 min, u32 max)
|
||||
{
|
||||
// Check all IDs starting from "next id"
|
||||
for (u32 i = 0; i <= max - min; i++)
|
||||
@ -33,7 +33,7 @@ id_manager::id_map::pointer idm::allocate_id(u32 tag, u32 min, u32 max)
|
||||
if (g_id[tag] < min || g_id[tag] > max) g_id[tag] = min;
|
||||
|
||||
// Get ID
|
||||
const auto r = g_map[tag].emplace(g_id[tag]++, nullptr);
|
||||
const auto r = g_map[tag].emplace(id_manager::id_key{g_id[tag]++, type}, nullptr);
|
||||
|
||||
if (r.second)
|
||||
{
|
||||
@ -58,19 +58,23 @@ std::shared_ptr<void> idm::deallocate_id(u32 tag, u32 id)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
id_manager::id_map::pointer idm::find_id(u32 type, u32 id)
|
||||
id_manager::id_map::pointer idm::find_id(u32 type, u32 true_type, u32 id)
|
||||
{
|
||||
const auto found = g_map[type].find(id);
|
||||
|
||||
if (found == g_map[type].end()) return nullptr;
|
||||
|
||||
if (true_type != get_type<void>() && found->first.type() != true_type) return nullptr;
|
||||
|
||||
return &*found;
|
||||
}
|
||||
|
||||
std::shared_ptr<void> idm::delete_id(u32 type, u32 tag, u32 id)
|
||||
std::shared_ptr<void> idm::delete_id(u32 type, u32 true_type, u32 tag, u32 id)
|
||||
{
|
||||
writer_lock lock(g_mutex);
|
||||
|
||||
if (!find_id(type, true_type, id)) return nullptr; // ???
|
||||
|
||||
auto&& ptr = deallocate_id(tag, id);
|
||||
|
||||
g_map[type].erase(id);
|
||||
|
@ -228,13 +228,13 @@ class idm
|
||||
};
|
||||
|
||||
// Prepares new ID, returns nullptr if out of resources
|
||||
static id_manager::id_map::pointer allocate_id(u32 tag, u32 min, u32 max);
|
||||
static id_manager::id_map::pointer allocate_id(u32 tag, u32 type, u32 min, u32 max);
|
||||
|
||||
// Deallocate ID, returns object
|
||||
static std::shared_ptr<void> deallocate_id(u32 tag, u32 id);
|
||||
|
||||
// Allocate new ID and construct it from the provider()
|
||||
template<typename T, typename F>
|
||||
template<typename T, typename Set, typename F>
|
||||
static id_manager::id_map::pointer create_id(F&& provider)
|
||||
{
|
||||
id_manager::typeinfo::update<T>();
|
||||
@ -242,7 +242,7 @@ class idm
|
||||
|
||||
writer_lock lock(g_mutex);
|
||||
|
||||
if (auto place = allocate_id(get_tag<T>(), id_manager::id_traits<T>::min, id_manager::id_traits<T>::max))
|
||||
if (auto place = allocate_id(get_tag<T>(), get_type<Set>(), id_manager::id_traits<T>::min, id_manager::id_traits<T>::max))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -265,10 +265,10 @@ class idm
|
||||
}
|
||||
|
||||
// Get ID (internal)
|
||||
static id_manager::id_map::pointer find_id(u32 type, u32 id);
|
||||
static id_manager::id_map::pointer find_id(u32 type, u32 true_type, u32 id);
|
||||
|
||||
// Remove ID and return object
|
||||
static std::shared_ptr<void> delete_id(u32 type, u32 tag, u32 id);
|
||||
static std::shared_ptr<void> delete_id(u32 type, u32 true_type, u32 tag, u32 id);
|
||||
|
||||
public:
|
||||
// Initialize object manager
|
||||
@ -279,13 +279,13 @@ public:
|
||||
|
||||
// Add a new ID of specified type with specified constructor arguments (returns object or nullptr)
|
||||
template<typename T, typename Make = T, typename... Args>
|
||||
static inline std::enable_if_t<std::is_constructible<Make, Args...>::value, std::shared_ptr<T>> make_ptr(Args&&... args)
|
||||
static inline std::enable_if_t<std::is_constructible<Make, Args...>::value, std::shared_ptr<Make>> make_ptr(Args&&... args)
|
||||
{
|
||||
if (auto pair = create_id<T>(WRAP_EXPR(std::make_shared<Make>(std::forward<Args>(args)...))))
|
||||
if (auto pair = create_id<T, Make>(WRAP_EXPR(std::make_shared<Make>(std::forward<Args>(args)...))))
|
||||
{
|
||||
id_manager::on_init<T>::func(static_cast<T*>(pair->second.get()), pair->second);
|
||||
id_manager::on_stop<T>::func(nullptr);
|
||||
return{ pair->second, static_cast<T*>(pair->second.get()) };
|
||||
return{ pair->second, static_cast<Make*>(pair->second.get()) };
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -295,7 +295,7 @@ public:
|
||||
template<typename T, typename Make = T, typename... Args>
|
||||
static inline std::enable_if_t<std::is_constructible<Make, Args...>::value, u32> make(Args&&... args)
|
||||
{
|
||||
if (auto pair = create_id<T>(WRAP_EXPR(std::make_shared<Make>(std::forward<Args>(args)...))))
|
||||
if (auto pair = create_id<T, Make>(WRAP_EXPR(std::make_shared<Make>(std::forward<Args>(args)...))))
|
||||
{
|
||||
id_manager::on_init<T>::func(static_cast<T*>(pair->second.get()), pair->second);
|
||||
id_manager::on_stop<T>::func(nullptr);
|
||||
@ -306,10 +306,10 @@ public:
|
||||
}
|
||||
|
||||
// Add a new ID for an existing object provided (returns new id)
|
||||
template<typename T>
|
||||
template<typename T, typename Made = T>
|
||||
static inline u32 import_existing(const std::shared_ptr<T>& ptr)
|
||||
{
|
||||
if (auto pair = create_id<T>(WRAP_EXPR(ptr)))
|
||||
if (auto pair = create_id<T, Made>(WRAP_EXPR(ptr)))
|
||||
{
|
||||
id_manager::on_init<T>::func(static_cast<T*>(pair->second.get()), pair->second);
|
||||
id_manager::on_stop<T>::func(nullptr);
|
||||
@ -320,53 +320,53 @@ public:
|
||||
}
|
||||
|
||||
// Add a new ID for an object returned by provider()
|
||||
template<typename T, typename F, typename = std::result_of_t<F()>>
|
||||
static inline std::shared_ptr<T> import(F&& provider)
|
||||
template<typename T, typename Made = T, typename F, typename = std::result_of_t<F()>>
|
||||
static inline std::shared_ptr<Made> import(F&& provider)
|
||||
{
|
||||
if (auto pair = create_id<T>(std::forward<F>(provider)))
|
||||
if (auto pair = create_id<T, Made>(std::forward<F>(provider)))
|
||||
{
|
||||
id_manager::on_init<T>::func(static_cast<T*>(pair->second.get()), pair->second);
|
||||
id_manager::on_stop<T>::func(nullptr);
|
||||
return { pair->second, static_cast<T*>(pair->second.get()) };
|
||||
return { pair->second, static_cast<Made*>(pair->second.get()) };
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check whether the ID exists
|
||||
template<typename T>
|
||||
template<typename T, typename Get = void>
|
||||
static inline bool check(u32 id)
|
||||
{
|
||||
reader_lock lock(g_mutex);
|
||||
|
||||
return find_id(get_type<T>(), id) != nullptr;
|
||||
return find_id(get_type<T>(), get_type<Get>(), id) != nullptr;
|
||||
}
|
||||
|
||||
// Get the ID
|
||||
template<typename T>
|
||||
static inline std::shared_ptr<T> get(u32 id)
|
||||
template<typename T, typename Get = void, typename Made = std::conditional_t<std::is_void<Get>::value, T, Get>>
|
||||
static inline std::shared_ptr<Made> get(u32 id)
|
||||
{
|
||||
reader_lock lock(g_mutex);
|
||||
|
||||
const auto found = find_id(get_type<T>(), id);
|
||||
const auto found = find_id(get_type<T>(), get_type<Get>(), id);
|
||||
|
||||
if (UNLIKELY(found == nullptr))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return{ found->second, static_cast<T*>(found->second.get()) };
|
||||
return{ found->second, static_cast<Made*>(found->second.get()) };
|
||||
}
|
||||
|
||||
// Conditionally get the ID, almost similar to select() but for the single object only.
|
||||
template<typename T, typename F, typename FT = decltype(&F::operator()), typename A2 = typename function_traits<FT>::second_type>
|
||||
template<typename T, typename Get = void, typename F, typename FT = decltype(&F::operator()), typename A2 = typename function_traits<FT>::second_type>
|
||||
static inline auto get(u32 id, F&& pred)
|
||||
{
|
||||
using result_type = std::conditional_t<std::is_void<typename function_traits<FT>::return_type>::value, void, std::shared_ptr<A2>>;
|
||||
|
||||
reader_lock lock(g_mutex);
|
||||
|
||||
const auto found = find_id(get_type<T>(), id);
|
||||
const auto found = find_id(get_type<T>(), get_type<Get>(), id);
|
||||
|
||||
if (UNLIKELY(found == nullptr))
|
||||
{
|
||||
@ -404,19 +404,34 @@ public:
|
||||
}
|
||||
|
||||
// Get count of objects
|
||||
template<typename T>
|
||||
template<typename T, typename Get = void>
|
||||
static inline u32 get_count()
|
||||
{
|
||||
reader_lock lock(g_mutex);
|
||||
|
||||
return ::size32(g_map[get_type<T>()]);
|
||||
if (std::is_void<Get>::value)
|
||||
{
|
||||
return ::size32(g_map[get_type<T>()]);
|
||||
}
|
||||
|
||||
u32 result = 0;
|
||||
|
||||
for (auto& id : g_map[get_type<T>()])
|
||||
{
|
||||
if (id.first.type() == get_type<Get>())
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Remove the ID
|
||||
template<typename T>
|
||||
template<typename T, typename Get = void>
|
||||
static inline bool remove(u32 id)
|
||||
{
|
||||
auto&& ptr = delete_id(get_type<T>(), get_tag<T>(), id);
|
||||
auto&& ptr = delete_id(get_type<T>(), get_type<Get>(), get_tag<T>(), id);
|
||||
|
||||
if (LIKELY(ptr))
|
||||
{
|
||||
@ -427,28 +442,28 @@ public:
|
||||
}
|
||||
|
||||
// Remove the ID and return it
|
||||
template<typename T>
|
||||
static inline std::shared_ptr<T> withdraw(u32 id)
|
||||
template<typename T, typename Get = void, typename Made = std::conditional_t<std::is_void<Get>::value, T, Get>>
|
||||
static inline std::shared_ptr<Made> withdraw(u32 id)
|
||||
{
|
||||
auto&& ptr = delete_id(get_type<T>(), get_tag<T>(), id);
|
||||
auto&& ptr = delete_id(get_type<T>(), get_type<Get>(), get_tag<T>(), id);
|
||||
|
||||
if (LIKELY(ptr))
|
||||
{
|
||||
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get()));
|
||||
}
|
||||
|
||||
return{ ptr, static_cast<T*>(ptr.get()) };
|
||||
return{ ptr, static_cast<Made*>(ptr.get()) };
|
||||
}
|
||||
|
||||
// Conditionally remove the ID and return it.
|
||||
template<typename T, typename F>
|
||||
static inline std::shared_ptr<T> withdraw(u32 id, F&& pred)
|
||||
template<typename T, typename Get = void, typename Made = std::conditional_t<std::is_void<Get>::value, T, Get>, typename F>
|
||||
static inline std::shared_ptr<Made> withdraw(u32 id, F&& pred)
|
||||
{
|
||||
std::shared_ptr<void> ptr;
|
||||
{
|
||||
writer_lock lock(g_mutex);
|
||||
|
||||
const auto found = find_id(get_type<T>(), id);
|
||||
const auto found = find_id(get_type<T>(), get_type<Get>(), id);
|
||||
|
||||
if (UNLIKELY(found == nullptr || !pred(id, *static_cast<T*>(found->second.get()))))
|
||||
{
|
||||
@ -462,7 +477,7 @@ public:
|
||||
|
||||
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get()));
|
||||
|
||||
return{ ptr, static_cast<T*>(ptr.get()) };
|
||||
return{ ptr, static_cast<Made*>(ptr.get()) };
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user