#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 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= 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; } };