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
|
|
|
|
|
2012-11-15 00:39:56 +01:00
|
|
|
typedef u32 ID_TYPE;
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> T* get()
|
|
|
|
{
|
|
|
|
return (T*)m_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> const T* get() const
|
|
|
|
{
|
|
|
|
return (const T*)m_ptr;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-11-15 00:39:56 +01:00
|
|
|
struct ID
|
|
|
|
{
|
2014-02-02 20:42:32 +01:00
|
|
|
std::string m_name;
|
2014-02-22 03:53:06 +01:00
|
|
|
u32 m_attr;
|
2014-01-19 04:14:11 +01:00
|
|
|
IDData* m_data;
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-19 04:14:11 +01:00
|
|
|
template<typename T>
|
2014-02-22 03:53:06 +01:00
|
|
|
ID(const std::string& name, T* data, const u32 attr)
|
2014-01-19 04:14:11 +01:00
|
|
|
: m_name(name)
|
2012-11-15 00:39:56 +01:00
|
|
|
, m_attr(attr)
|
|
|
|
{
|
2014-01-19 04:14:11 +01:00
|
|
|
m_data = new IDData(data, [](void *ptr) -> void { delete (T*)ptr; });
|
|
|
|
}
|
|
|
|
|
|
|
|
ID() : m_data(nullptr)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-04-15 16:12:15 +02:00
|
|
|
ID(ID&& other)
|
|
|
|
{
|
|
|
|
m_name = other.m_name;
|
|
|
|
m_attr = other.m_attr;
|
|
|
|
m_data = other.m_data;
|
|
|
|
other.m_data = nullptr;
|
|
|
|
}
|
2014-04-25 18:57:00 +02:00
|
|
|
ID& operator=(ID&& other)
|
|
|
|
{
|
|
|
|
std::swap(m_name,other.m_name);
|
|
|
|
std::swap(m_attr,other.m_attr);
|
|
|
|
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
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class IdManager
|
|
|
|
{
|
2014-01-19 04:14:11 +01:00
|
|
|
static const ID_TYPE s_first_id = 1;
|
|
|
|
static const ID_TYPE s_max_id = -1;
|
|
|
|
|
|
|
|
std::unordered_map<ID_TYPE, ID> m_id_map;
|
|
|
|
std::mutex m_mtx_main;
|
|
|
|
|
|
|
|
ID_TYPE 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
|
|
|
|
|
|
|
bool CheckID(const ID_TYPE 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);
|
|
|
|
|
|
|
|
for(auto& i : m_id_map)
|
|
|
|
{
|
|
|
|
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-02-22 03:53:06 +01:00
|
|
|
ID_TYPE GetNewID(const std::string& name = "", T* data = nullptr, const u32 attr = 0)
|
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-04-25 18:57:00 +02:00
|
|
|
m_id_map[m_cur_id] = ID(name, data, attr);
|
2014-01-19 04:14:11 +01:00
|
|
|
|
|
|
|
return m_cur_id++;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
2014-01-19 04:14:11 +01:00
|
|
|
ID& GetID(const ID_TYPE 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>
|
|
|
|
bool GetIDData(const ID_TYPE id, 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);
|
|
|
|
|
|
|
|
if(f == m_id_map.end())
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-19 04:14:11 +01:00
|
|
|
return false;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
2014-01-19 04:14:11 +01:00
|
|
|
result = f->second.m_data->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
|
|
|
}
|
|
|
|
|
|
|
|
bool HasID(const s64 id)
|
|
|
|
{
|
2014-02-13 12:13:05 +01:00
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(m_mtx_main);
|
2014-01-19 04:14:11 +01:00
|
|
|
|
2014-05-02 08:30:32 +02:00
|
|
|
if(id == rID_ANY)
|
2014-02-13 12:13:05 +01:00
|
|
|
return m_id_map.begin() != m_id_map.end();
|
|
|
|
}
|
2014-01-19 04:14:11 +01:00
|
|
|
|
2012-11-15 00:39:56 +01:00
|
|
|
return CheckID(id);
|
|
|
|
}
|
|
|
|
|
2014-01-19 04:14:11 +01:00
|
|
|
bool RemoveID(const ID_TYPE 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);
|
|
|
|
|
|
|
|
if(item == m_id_map.end()) return false;
|
|
|
|
|
|
|
|
item->second.Kill();
|
|
|
|
m_id_map.erase(item);
|
2012-11-15 00:39:56 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2014-02-23 17:52:52 +01:00
|
|
|
};
|