mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
137 lines
2.2 KiB
C++
137 lines
2.2 KiB
C++
#pragma once
|
|
#include "Array.h"
|
|
|
|
typedef u32 ID_TYPE;
|
|
|
|
struct ID
|
|
{
|
|
bool m_used;
|
|
wxString m_name;
|
|
u8 m_attr;
|
|
void* m_data;
|
|
|
|
ID(bool used = false, const wxString& name = wxEmptyString, void* data = NULL, const u8 attr = 0)
|
|
: m_used(used)
|
|
, m_name(name)
|
|
, m_data(data)
|
|
, m_attr(attr)
|
|
{
|
|
}
|
|
};
|
|
|
|
class IdManager
|
|
{
|
|
ArrayF<ID> IDs;
|
|
|
|
static const u64 first_id = 1;
|
|
|
|
void Cleanup()
|
|
{
|
|
while(IDs.GetCount())
|
|
{
|
|
const u32 num = IDs.GetCount()-1;
|
|
ID& id = IDs[num];
|
|
if(id.m_used) break;
|
|
IDs.RemoveAt(num);
|
|
}
|
|
}
|
|
|
|
public:
|
|
IdManager()
|
|
{
|
|
}
|
|
|
|
~IdManager()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
static ID_TYPE GetMaxID()
|
|
{
|
|
return (ID_TYPE)-1;
|
|
}
|
|
|
|
bool CheckID(const u64 id)
|
|
{
|
|
if(id == 0 || id > (u64)NumToID(IDs.GetCount()-1) || id >= GetMaxID()) return false;
|
|
|
|
return IDs[IDToNum(id)].m_used;
|
|
}
|
|
|
|
__forceinline const ID_TYPE NumToID(const ID_TYPE num) const
|
|
{
|
|
return num + first_id;
|
|
}
|
|
|
|
__forceinline const ID_TYPE IDToNum(const ID_TYPE id) const
|
|
{
|
|
return id - first_id;
|
|
}
|
|
|
|
void Clear()
|
|
{
|
|
IDs.Clear();
|
|
}
|
|
|
|
virtual ID_TYPE GetNewID(const wxString& name = wxEmptyString, void* data = NULL, const u8 attr = 0)
|
|
{
|
|
for(uint i=0; i<IDs.GetCount(); ++i)
|
|
{
|
|
if(IDs[i].m_used) continue;
|
|
return NumToID(i);
|
|
}
|
|
|
|
const ID_TYPE pos = IDs.GetCount();
|
|
if(NumToID(pos) >= GetMaxID()) return 0;
|
|
IDs.Add(new ID(true, name, data, attr));
|
|
return NumToID(pos);
|
|
}
|
|
|
|
ID& GetIDData(const ID_TYPE _id)
|
|
{
|
|
//if(!CheckID(_id)) return IDs.Get(0); //TODO
|
|
return IDs[IDToNum(_id)];
|
|
}
|
|
|
|
|
|
bool GetFirst(ID& dst, ID_TYPE* _id = NULL)
|
|
{
|
|
u32 pos = 0;
|
|
return GetNext(pos, dst, _id);
|
|
}
|
|
|
|
bool HasID(const s64 id)
|
|
{
|
|
if(id == wxID_ANY) return IDs.GetCount() != 0;
|
|
return CheckID(id);
|
|
}
|
|
|
|
bool GetNext(u32& pos, ID& dst, ID_TYPE* _id = NULL)
|
|
{
|
|
while(pos < IDs.GetCount())
|
|
{
|
|
ID& id = IDs[pos++];
|
|
if(!id.m_used) continue;
|
|
dst = id;
|
|
if(_id) *_id = NumToID(pos - 1);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
virtual bool RemoveID(const ID_TYPE _id, bool free_data = true)
|
|
{
|
|
if(!CheckID(_id)) return false;
|
|
ID& id = IDs[IDToNum(_id)];
|
|
if(!id.m_used) return false;
|
|
id.m_used = false;
|
|
id.m_attr = 0;
|
|
id.m_name.Clear();
|
|
if(free_data) delete id.m_data;
|
|
id.m_data = NULL;
|
|
if(IDToNum(_id) == IDs.GetCount()-1) Cleanup();
|
|
return true;
|
|
}
|
|
};
|