rpcs3/Utilities/IdManager.h
Bigpet eea3aa9729 This is squashed commit from the follwing commits:
* various changes to make it compile with clang

* don't compile recompiler on linux yet but make the CMake build include asmjit already

* add experimental travis bot

* modify yml to match

* try to build and install wxWidgets, since it's not in the travis repo

* use newer cmake version for travis

* add keys with sudo

* use sudo for all apt- commands

* Add additional dependencies

* use version approriate gcc flags for c++11

* try clang, gcc too old

* set c++0x flag for clang

* use gcc 4.8

* use gcc 4.8 and add the repo for it

* use gcc 4.8 even for clang to get newer headers

* fix ambiguous conversions

* add lz from hykem and more explicit conversions from be for x86

* more switch disambiguation

* more switch disambiguation

* add additional unigned int casts to deal with be_t conversion ambiguity

* remove unnecessary clang flag

* add lz.cpp to vcxproj and cast to u32 instead of unsigned int

* correct temporaray #ifdefs
2014-04-27 00:41:46 +02:00

178 lines
2.6 KiB
C++

#pragma once
#include <unordered_map>
typedef u32 ID_TYPE;
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;
}
};
struct ID
{
std::string m_name;
u32 m_attr;
IDData* m_data;
template<typename T>
ID(const std::string& name, T* data, const u32 attr)
: m_name(name)
, m_attr(attr)
{
m_data = new IDData(data, [](void *ptr) -> void { delete (T*)ptr; });
}
ID() : m_data(nullptr)
{
}
ID(ID&& other)
{
m_name = other.m_name;
m_attr = other.m_attr;
m_data = other.m_data;
other.m_data = nullptr;
}
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;
}
void Kill()
{
delete m_data;
}
};
class IdManager
{
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;
public:
IdManager() : m_cur_id(s_first_id)
{
}
~IdManager()
{
Clear();
}
bool CheckID(const ID_TYPE id)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
return m_id_map.find(id) != m_id_map.end();
}
void Clear()
{
std::lock_guard<std::mutex> lock(m_mtx_main);
for(auto& i : m_id_map)
{
i.second.Kill();
}
m_id_map.clear();
m_cur_id = s_first_id;
}
template<typename T
#ifdef __GNUG__
= char
#endif
>
ID_TYPE GetNewID(const std::string& name = "", T* data = nullptr, const u32 attr = 0)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
m_id_map[m_cur_id] = ID(name, data, attr);
return m_cur_id++;
}
ID& GetID(const ID_TYPE id)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
return m_id_map[id];
}
template<typename T>
bool GetIDData(const ID_TYPE id, T*& result)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
auto f = m_id_map.find(id);
if(f == m_id_map.end())
{
return false;
}
result = f->second.m_data->get<T>();
return true;
}
bool HasID(const s64 id)
{
{
std::lock_guard<std::mutex> lock(m_mtx_main);
if(id == wxID_ANY)
return m_id_map.begin() != m_id_map.end();
}
return CheckID(id);
}
bool RemoveID(const ID_TYPE id)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
auto item = m_id_map.find(id);
if(item == m_id_map.end()) return false;
item->second.Kill();
m_id_map.erase(item);
return true;
}
};