//////////////////////////////////////////////////////////////////////////// // // Crytek Engine Source File. // Copyright (C), Crytek Studios, 2002. // ------------------------------------------------------------------------- // File name: list2.h // Version: v1.00 // Created: 28/5/2002 by Vladimir Kajalin // Compilers: Visual Studio.NET // Description: simple container, supports serialization // ------------------------------------------------------------------------- // History: // //////////////////////////////////////////////////////////////////////////// #ifndef LIST_3DENGINE_H #define LIST_3DENGINE_H #include "platform.h" #if defined(LINUX) #include "ILog.h" #include "ICryPak.h" #else #include #endif template class list2 { T * m_pElements; int m_nCount; int m_nAllocatedCount; public: typedef T value_type; int GetAllocatedMB() { return (m_nAllocatedCount*sizeof(T))/(1024*1024); } int GetMemoryUsage() { return m_nAllocatedCount*sizeof(T);} list2() { m_nCount=0; m_pElements=0; Reset(); } ~list2() { Reset(); } void Free() { Reset(); } void Reset() { if(m_pElements) free (m_pElements); m_pElements=0; m_nCount=0; m_nAllocatedCount= 0; } void Clear() { m_nCount=0; } int Find(const T & p) { for(int i=0; i & lstAnother) { PreAllocate(m_nCount + lstAnother.Count()); memcpy(&m_pElements[m_nCount],&lstAnother.m_pElements[0],sizeof(m_pElements[0])*lstAnother.Count()); m_nCount += lstAnother.Count(); } inline void AddList(T * pAnotherArray, int nAnotherCount) { PreAllocate(m_nCount + nAnotherCount); memcpy(&m_pElements[m_nCount],pAnotherArray,sizeof(m_pElements[0])*nAnotherCount); m_nCount += nAnotherCount; } inline void AddDebug(const char *p__FILE__, long n__LINE__, const T & p) { #ifdef _DEBUG if( m_nCount >= m_nAllocatedCount ) { assert(&p=(m_pElements+m_nAllocatedCount)); m_nAllocatedCount = m_nCount*2 + 8; m_pElements = (T*)_realloc_dbg(m_pElements,m_nAllocatedCount*sizeof(T), _NORMAL_BLOCK, p__FILE__, n__LINE__); assert(m_pElements); } memcpy(&m_pElements[m_nCount],&p,sizeof(m_pElements[m_nCount])); m_nCount++; #else Add(p); #endif } inline void Add(const T & p) { if( m_nCount >= m_nAllocatedCount ) { assert(&p=(m_pElements+m_nAllocatedCount)); m_nAllocatedCount = m_nCount*2 + 8; m_pElements = (T*)realloc(m_pElements,m_nAllocatedCount*sizeof(T)); assert(m_pElements); } memcpy(&m_pElements[m_nCount],&p,sizeof(m_pElements[m_nCount])); m_nCount++; } void InsertBefore(const T & p, const unsigned int nBefore) { assert( nBefore>=0 && nBefore<=(unsigned int)m_nCount ); T tmp; Add(tmp); // add empty object to increase memory buffer memmove(&(m_pElements[nBefore+1]), &(m_pElements[nBefore]), sizeof(T)*(m_nCount-nBefore-1)); m_pElements[nBefore] = p; } void PreAllocate(int elem_count, int nNewCount = 0) { if( elem_count > m_nAllocatedCount ) { m_nAllocatedCount = elem_count; T * new_elements = (T*)malloc(m_nAllocatedCount*sizeof(T)); assert(new_elements); memset(new_elements, 0, sizeof(T)*m_nAllocatedCount); memcpy(new_elements, m_pElements, sizeof(T)*m_nCount); if(m_pElements) free (m_pElements); m_pElements = new_elements; } if(nNewCount) m_nCount = nNewCount; } inline void Delete(const int nElemId, const int nElemCount = 1) { assert( nElemId >= 0 && nElemId+nElemCount <= m_nCount ); memcpy(&(m_pElements[nElemId]), &(m_pElements[nElemId+nElemCount]), sizeof(T)*(m_nCount-nElemId-nElemCount)); m_nCount-=nElemCount; } inline void DeleteFastUnsorted(const int nElemId, const int nElemCount = 1) { assert( nElemId >= 0 && nElemId+nElemCount <= m_nCount ); memcpy(&(m_pElements[nElemId]), &(m_pElements[m_nCount-nElemCount]), sizeof(T)*nElemCount); m_nCount-=nElemCount; } inline bool Delete(const T & del) { bool bFound = false; for( int i=0; i=0 && i=0 && i=0 && i& operator = (list2 & source_list) { Reset(); PreAllocate(source_list.Count()+2); for(int i=0; i & l) { if(Count() != l.Count()) return 0; if(memcmp(m_pElements, l.m_pElements, m_nCount*sizeof(T))!=0) return 0; return 1; } bool operator != (const list2 & l) { return !(*this == l); } // Save/Load void Save(const char * file_name) { FILE * f = fxopen(file_name, "wb"); if(f) { int size = sizeof(T); fwrite(&size, 4, 1, f); if(m_nCount) fwrite(m_pElements, sizeof(T), m_nCount, f); fclose(f); } } void Load(const char * file_name, struct ICryPak *pPak) { Clear(); FILE * f; f = pPak->FOpen(file_name, "rb"); if(!f) return; int size = 0; pPak->FRead(&size, 4, 1, f); while(!pPak->FEof(f) && sizeof(T)==size) { T tmp; if(pPak->FRead(&tmp, 1, sizeof(T), f) == sizeof(T)) Add(tmp); } pPak->FClose(f); } // Save/Load void SaveToBuffer(const unsigned char * pBuffer, int & nPos) { // copy size of element int nSize = sizeof(T); if(pBuffer) memcpy((void*)&pBuffer[nPos],&nSize,4); nPos+=4; // copy count if(pBuffer) memcpy((void*)&pBuffer[nPos],&m_nCount,4); nPos+=4; // copy data if(m_nCount) { if(pBuffer) memcpy((void*)&pBuffer[nPos], m_pElements, sizeof(T)*m_nCount); nPos += sizeof(T)*m_nCount; } } void LoadFromBuffer(const unsigned char * pBuffer, int & nPos) { Reset(); // copy size of element int nElemSize = 0; memcpy(&nElemSize,(void*)&pBuffer[nPos],4); assert(nElemSize == sizeof(T)); nPos+=4; // copy count int nNewCount=0; memcpy((void*)&nNewCount,&pBuffer[nPos],4); assert(nNewCount>=0 && nNewCount<1000000); nPos+=4; // copy data if(nNewCount) { PreAllocate(nNewCount,nNewCount); memcpy((void*)m_pElements, &pBuffer[nPos], sizeof(T)*nNewCount); nPos += sizeof(T)*nNewCount; } } // Sorting of objects static int __cdecl Cmp_Ptrs1(const void* v1, const void* v2) { T* p1 = (T*)v1; T* p2 = (T*)v2; if(p1->m_fDistance > p2->m_fDistance) return 1; else if(p1->m_fDistance < p2->m_fDistance) return -1; return 0; } static int __cdecl Cmp_Ptrs2(const void* v1, const void* v2) { T* p1 = (T*)v1; T* p2 = (T*)v2; if(p1->m_fDistance > p2->m_fDistance) return -1; else if(p1->m_fDistance < p2->m_fDistance) return 1; return 0; } void SortByDistanceMember(bool front_to_back = true, int nSortOffSet = 0) { if(m_nCount-nSortOffSet > 1) { if(front_to_back) qsort(&m_pElements[nSortOffSet], m_nCount-nSortOffSet, sizeof(T), Cmp_Ptrs1); else qsort(&m_pElements[nSortOffSet], m_nCount-nSortOffSet, sizeof(T), Cmp_Ptrs2); } } // Sorting of pointers to objects static int Cmp_Ptrs1_(const void* v1, const void* v2) { T p1 = *((T*)v1); T p2 = *((T*)v2); if(p1->m_fDistance > p2->m_fDistance) return 1; else if(p1->m_fDistance < p2->m_fDistance) return -1; return 0; } static int Cmp_Ptrs2_(const void* v1, const void* v2) { T p1 = *((T*)v1); T p2 = *((T*)v2); if(p1->m_fDistance > p2->m_fDistance) return -1; else if(p1->m_fDistance < p2->m_fDistance) return 1; return 0; } void SortByDistanceMember_(bool front_to_back = true) { if(front_to_back) qsort(&m_pElements[0], m_nCount, sizeof(T), Cmp_Ptrs1_); else qsort(&m_pElements[0], m_nCount, sizeof(T), Cmp_Ptrs2_); } // STL convention driver routines to facilitate conversion from this class to optimized // containers with standard, well-known and thus more convenient for some other (except // the author) people naming conventions. // All the routines mean the same as their counterparts in std::vector. bool empty() const { return IsEmpty() != 0; } void reserve (unsigned numElements) { PreAllocate ((int)numElements); } // C++ Standard Library makes new[] call instead of old-fashioned *alloc() // this ensures the objects are constructed properly. void resize (size_t numElements) { int nOldCount = m_nCount; PreAllocate ((int)numElements, (int)numElements); assert (numElements == size()); for (int nElement = nOldCount; nElement < m_nCount; ++nElement) (*this)[nElement] = T(); } void push_back (const T& rElement) { Add (rElement); } unsigned size ()const { return (unsigned)m_nCount; } unsigned capacity() const { return (unsigned)m_nAllocatedCount; } T* begin() {return m_pElements;} T* end() {return m_pElements+m_nCount;} const T* begin()const {return m_pElements;} const T* end()const {return m_pElements+m_nCount;} }; #endif // LIST_3DENGINE_H