#pragma once template class CStore { public: int allocPtr; T store[n]; T *alloc(void){ if(this->allocPtr >= n){ printf("Size of this thing:%d needs increasing\n", n); assert(0); } return &this->store[this->allocPtr++]; } void clear(void){ this->allocPtr = 0; } int getIndex(T *item){ assert(item >= &this->store[0]); assert(item < &this->store[n]); return item - this->store; } T *getItem(int index){ assert(index >= 0); assert(index < n); return &this->store[index]; } }; template class CPool { U *m_entries; union Flags { struct { uint8 id : 7; uint8 free : 1; }; uint8 u; } *m_flags; int m_size; int m_allocPtr; public: CPool(int size){ // TODO: use new here m_entries = (U*)malloc(sizeof(U)*size); m_flags = (Flags*)malloc(sizeof(Flags)*size); m_size = size; m_allocPtr = 0; for(int i = 0; i < size; i++){ m_flags[i].id = 0; m_flags[i].free = 1; } } ~CPool() { Flush(); } void Flush() { if (m_size > 0) { free(m_entries); free(m_flags); m_entries = nil; m_flags = nil; m_size = 0; m_allocPtr = 0; } } int GetSize(void) const { return m_size; } T *New(void){ bool wrapped = false; do #ifdef FIX_BUGS if (++m_allocPtr >= m_size) { m_allocPtr = 0; if (wrapped) return nil; wrapped = true; } #else if(++m_allocPtr == m_size){ if(wrapped) return nil; wrapped = true; m_allocPtr = 0; } #endif while(!m_flags[m_allocPtr].free); m_flags[m_allocPtr].free = 0; m_flags[m_allocPtr].id++; return (T*)&m_entries[m_allocPtr]; } T *New(int handle){ T *entry = (T*)&m_entries[handle>>8]; SetNotFreeAt(handle); return entry; } void SetNotFreeAt(int handle){ int idx = handle>>8; m_flags[idx].free = 0; m_flags[idx].id = handle & 0x7F; for(m_allocPtr = 0; m_allocPtr < m_size; m_allocPtr++) if(m_flags[m_allocPtr].free) return; } void Delete(T *entry){ int i = GetJustIndex(entry); m_flags[i].free = 1; if(i < m_allocPtr) m_allocPtr = i; } T *GetSlot(int i){ return m_flags[i].free ? nil : (T*)&m_entries[i]; } T *GetAt(int handle){ #ifdef FIX_BUGS if (handle == -1) return nil; #endif return m_flags[handle>>8].u == (handle & 0xFF) ? (T*)&m_entries[handle >> 8] : nil; } int GetIndex(T *entry){ int i = GetJustIndex(entry); return m_flags[i].u + (i<<8); } int GetJustIndex(T *entry){ // TODO: the cast is unsafe return (int)((U*)entry - m_entries); } int GetNoOfUsedSpaces(void) const{ int i; int n = 0; for(i = 0; i < m_size; i++) if(!m_flags[i].free) n++; return n; } bool IsFreeSlot(int i) { return !!m_flags[i].free; } void ClearStorage(uint8 *&flags, U *&entries){ free(flags); free(entries); flags = nil; entries = nil; } uint32 GetMaxEntrySize() const { return sizeof(U); } void CopyBack(uint8 *&flags, U *&entries){ memcpy(m_flags, flags, sizeof(uint8)*m_size); memcpy(m_entries, entries, sizeof(U)*m_size); debug("Size copied:%d (%d)\n", sizeof(U)*m_size, sizeof(Flags)*m_size); m_allocPtr = 0; ClearStorage(flags, entries); debug("CopyBack:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ } void Store(uint8 *&flags, U *&entries){ flags = (uint8*)malloc(sizeof(uint8)*m_size); entries = (U*)malloc(sizeof(U)*m_size); memcpy(flags, m_flags, sizeof(uint8)*m_size); memcpy(entries, m_entries, sizeof(U)*m_size); debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ } }; template class CLink { public: T item; CLink *prev; CLink *next; void Insert(CLink *link){ link->next = this->next; this->next->prev = link; link->prev = this; this->next = link; } void Remove(void){ this->prev->next = this->next; this->next->prev = this->prev; } }; template class CLinkList { public: CLink head, tail; CLink freeHead, freeTail; CLink *links; void Init(int n){ links = new CLink[n]; head.next = &tail; tail.prev = &head; freeHead.next = &freeTail; freeTail.prev = &freeHead; while(n--) freeHead.Insert(&links[n]); } void Shutdown(void){ delete[] links; links = nil; } void Clear(void){ while(head.next != &tail) Remove(head.next); } CLink *Insert(T const &item){ CLink *node = freeHead.next; if(node == &freeTail) return nil; node->item = item; node->Remove(); // remove from free list head.Insert(node); return node; } CLink *InsertSorted(T const &item){ CLink *sort; for(sort = head.next; sort != &tail; sort = sort->next) if(sort->item.sort >= item.sort) break; CLink *node = freeHead.next; if(node == &freeTail) return nil; node->item = item; node->Remove(); // remove from free list sort->prev->Insert(node); return node; } void Remove(CLink *link){ link->Remove(); // remove from list freeHead.Insert(link); // insert into free list } int Count(void){ int n = 0; CLink *lnk; for(lnk = head.next; lnk != &tail; lnk = lnk->next) n++; return n; } };