2012-11-15 00:39:56 +01:00
|
|
|
#pragma once
|
2014-01-19 04:14:11 +01:00
|
|
|
#include <unordered_map>
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-05-02 08:30:32 +02:00
|
|
|
#define rID_ANY -1 // was wxID_ANY
|
|
|
|
|
|
2014-07-26 05:31:46 +02:00
|
|
|
enum IDType
|
|
|
|
|
{
|
|
|
|
|
// Special objects
|
|
|
|
|
TYPE_MEM,
|
|
|
|
|
TYPE_MUTEX,
|
|
|
|
|
TYPE_COND,
|
|
|
|
|
TYPE_RWLOCK,
|
|
|
|
|
TYPE_INTR_TAG,
|
|
|
|
|
TYPE_INTR_SERVICE_HANDLE,
|
|
|
|
|
TYPE_EVENT_QUEUE,
|
|
|
|
|
TYPE_EVENT_PORT,
|
|
|
|
|
TYPE_TRACE,
|
|
|
|
|
TYPE_SPUIMAGE,
|
|
|
|
|
TYPE_PRX,
|
|
|
|
|
TYPE_SPUPORT,
|
|
|
|
|
TYPE_LWMUTEX,
|
|
|
|
|
TYPE_TIMER,
|
|
|
|
|
TYPE_SEMAPHORE,
|
|
|
|
|
TYPE_FS_FILE,
|
|
|
|
|
TYPE_FS_DIR,
|
|
|
|
|
TYPE_LWCOND,
|
|
|
|
|
TYPE_EVENT_FLAG,
|
|
|
|
|
|
2014-07-26 07:51:45 +02:00
|
|
|
// Any other objects
|
2014-07-26 05:31:46 +02:00
|
|
|
TYPE_OTHER,
|
|
|
|
|
};
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-19 04:14:11 +01:00
|
|
|
class IDData
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
void* m_ptr;
|
|
|
|
|
std::function<void(void*)> m_destr;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
IDData(void* ptr, std::function<void(void*)> destr)
|
|
|
|
|
: m_ptr(ptr)
|
|
|
|
|
, m_destr(destr)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~IDData()
|
|
|
|
|
{
|
|
|
|
|
m_destr(m_ptr);
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
template<typename T> std::shared_ptr<T> get()
|
2014-01-19 04:14:11 +01:00
|
|
|
{
|
2014-12-24 00:38:13 +01:00
|
|
|
return *(std::shared_ptr<T>*)m_ptr;
|
2014-01-19 04:14:11 +01:00
|
|
|
}
|
|
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
template<typename T> std::shared_ptr<const T> get() const
|
2014-01-19 04:14:11 +01:00
|
|
|
{
|
2014-12-24 00:38:13 +01:00
|
|
|
return *(std::shared_ptr<const T>*)m_ptr;
|
2014-01-19 04:14:11 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-10-01 11:45:43 +02:00
|
|
|
class ID
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-02-02 20:42:32 +01:00
|
|
|
std::string m_name;
|
2014-01-19 04:14:11 +01:00
|
|
|
IDData* m_data;
|
2014-07-26 05:31:46 +02:00
|
|
|
IDType m_type;
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-10-01 11:45:43 +02:00
|
|
|
public:
|
2014-01-19 04:14:11 +01:00
|
|
|
template<typename T>
|
2014-12-24 00:38:13 +01:00
|
|
|
ID(const std::string& name, std::shared_ptr<T>& data, const IDType type)
|
2014-01-19 04:14:11 +01:00
|
|
|
: m_name(name)
|
2014-07-26 05:31:46 +02:00
|
|
|
, m_type(type)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-12-24 00:38:13 +01:00
|
|
|
m_data = new IDData(new std::shared_ptr<T>(data), [](void *ptr) -> void { delete (std::shared_ptr<T>*)ptr; });
|
2014-01-19 04:14:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID() : m_data(nullptr)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-15 16:12:15 +02:00
|
|
|
ID(ID&& other)
|
|
|
|
|
{
|
|
|
|
|
m_name = other.m_name;
|
2014-07-26 05:31:46 +02:00
|
|
|
m_type = other.m_type;
|
2014-04-15 16:12:15 +02:00
|
|
|
m_data = other.m_data;
|
|
|
|
|
other.m_data = nullptr;
|
|
|
|
|
}
|
2014-12-24 00:38:13 +01:00
|
|
|
|
2014-04-25 18:57:00 +02:00
|
|
|
ID& operator=(ID&& other)
|
|
|
|
|
{
|
|
|
|
|
std::swap(m_name,other.m_name);
|
2014-07-26 05:31:46 +02:00
|
|
|
std::swap(m_type,other.m_type);
|
2014-04-25 18:57:00 +02:00
|
|
|
std::swap(m_data,other.m_data);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
2014-04-15 16:12:15 +02:00
|
|
|
|
2014-01-19 04:14:11 +01:00
|
|
|
void Kill()
|
|
|
|
|
{
|
|
|
|
|
delete m_data;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
2014-10-01 11:45:43 +02:00
|
|
|
|
|
|
|
|
const std::string& GetName() const
|
|
|
|
|
{
|
|
|
|
|
return m_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDData* GetData() const
|
|
|
|
|
{
|
|
|
|
|
return m_data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDType GetType() const
|
|
|
|
|
{
|
|
|
|
|
return m_type;
|
|
|
|
|
}
|
2012-11-15 00:39:56 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class IdManager
|
|
|
|
|
{
|
2014-07-26 05:31:46 +02:00
|
|
|
static const u32 s_first_id = 1;
|
|
|
|
|
static const u32 s_max_id = -1;
|
2014-01-19 04:14:11 +01:00
|
|
|
|
2014-07-26 05:31:46 +02:00
|
|
|
std::unordered_map<u32, ID> m_id_map;
|
2014-07-26 07:51:45 +02:00
|
|
|
std::set<u32> m_types[TYPE_OTHER];
|
2014-01-19 04:14:11 +01:00
|
|
|
std::mutex m_mtx_main;
|
|
|
|
|
|
2014-07-26 05:31:46 +02:00
|
|
|
u32 m_cur_id;
|
2012-11-15 00:39:56 +01:00
|
|
|
|
|
|
|
|
public:
|
2014-01-19 04:14:11 +01:00
|
|
|
IdManager() : m_cur_id(s_first_id)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~IdManager()
|
|
|
|
|
{
|
|
|
|
|
Clear();
|
|
|
|
|
}
|
2014-01-19 04:14:11 +01:00
|
|
|
|
2014-07-26 05:31:46 +02:00
|
|
|
bool CheckID(const u32 id)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-19 04:14:11 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_mtx_main);
|
|
|
|
|
|
|
|
|
|
return m_id_map.find(id) != m_id_map.end();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
2014-01-19 04:14:11 +01:00
|
|
|
|
|
|
|
|
void Clear()
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-19 04:14:11 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_mtx_main);
|
|
|
|
|
|
2014-07-26 05:31:46 +02:00
|
|
|
for(auto& i : m_id_map) {
|
2014-01-19 04:14:11 +01:00
|
|
|
i.second.Kill();
|
|
|
|
|
}
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-19 04:14:11 +01:00
|
|
|
m_id_map.clear();
|
|
|
|
|
m_cur_id = s_first_id;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-02-24 00:40:03 +01:00
|
|
|
template<typename T
|
|
|
|
|
#ifdef __GNUG__
|
|
|
|
|
= char
|
|
|
|
|
#endif
|
|
|
|
|
>
|
2014-12-24 00:38:13 +01:00
|
|
|
u32 GetNewID(const std::string& name = "", std::shared_ptr<T>& data = nullptr, const IDType type = TYPE_OTHER)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-19 04:14:11 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_mtx_main);
|
|
|
|
|
|
2014-07-26 05:31:46 +02:00
|
|
|
m_id_map[m_cur_id] = ID(name, data, type);
|
|
|
|
|
if (type < TYPE_OTHER) {
|
|
|
|
|
m_types[type].insert(m_cur_id);
|
|
|
|
|
}
|
2014-01-19 04:14:11 +01:00
|
|
|
|
|
|
|
|
return m_cur_id++;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-26 05:31:46 +02:00
|
|
|
ID& GetID(const u32 id)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-19 04:14:11 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_mtx_main);
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-19 04:14:11 +01:00
|
|
|
return m_id_map[id];
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
2014-01-19 04:14:11 +01:00
|
|
|
|
|
|
|
|
template<typename T>
|
2014-12-24 00:38:13 +01:00
|
|
|
bool GetIDData(const u32 id, std::shared_ptr<T>& result)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-19 04:14:11 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_mtx_main);
|
|
|
|
|
|
|
|
|
|
auto f = m_id_map.find(id);
|
2014-07-26 05:31:46 +02:00
|
|
|
if (f == m_id_map.end()) {
|
2014-01-19 04:14:11 +01:00
|
|
|
return false;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-10-01 11:45:43 +02:00
|
|
|
result = f->second.GetData()->get<T>();
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-19 04:14:11 +01:00
|
|
|
return true;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-30 19:51:00 +02:00
|
|
|
bool HasID(const u32 id)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-07-26 07:51:45 +02:00
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_mtx_main);
|
2014-01-19 04:14:11 +01:00
|
|
|
|
2014-07-26 07:51:45 +02:00
|
|
|
if(id == rID_ANY) {
|
|
|
|
|
return m_id_map.begin() != m_id_map.end();
|
|
|
|
|
}
|
2014-02-13 12:13:05 +01:00
|
|
|
}
|
2012-11-15 00:39:56 +01:00
|
|
|
return CheckID(id);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-26 05:31:46 +02:00
|
|
|
bool RemoveID(const u32 id)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-19 04:14:11 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_mtx_main);
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-19 04:14:11 +01:00
|
|
|
auto item = m_id_map.find(id);
|
|
|
|
|
|
2014-07-26 05:31:46 +02:00
|
|
|
if (item == m_id_map.end()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2014-10-01 11:45:43 +02:00
|
|
|
if (item->second.GetType() < TYPE_OTHER) {
|
|
|
|
|
m_types[item->second.GetType()].erase(id);
|
2014-07-26 05:31:46 +02:00
|
|
|
}
|
2014-01-19 04:14:11 +01:00
|
|
|
|
|
|
|
|
item->second.Kill();
|
|
|
|
|
m_id_map.erase(item);
|
2012-11-15 00:39:56 +01:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2014-07-26 05:31:46 +02:00
|
|
|
|
2014-12-24 17:09:32 +01:00
|
|
|
u32 GetTypeCount(IDType type)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_mtx_main);
|
|
|
|
|
|
|
|
|
|
if (type < TYPE_OTHER)
|
|
|
|
|
{
|
|
|
|
|
return (u32)m_types[type].size();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
assert(!"Invalid ID type");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::set<u32> GetTypeIDs(IDType type)
|
|
|
|
|
{
|
|
|
|
|
// you cannot simply return reference to existing set
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_mtx_main);
|
|
|
|
|
|
|
|
|
|
if (type < TYPE_OTHER)
|
|
|
|
|
{
|
|
|
|
|
return m_types[type];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
assert(!"Invalid ID type");
|
|
|
|
|
return{};
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-02-23 17:52:52 +01:00
|
|
|
};
|