2015-01-28 01:24:36 -05:00
|
|
|
#pragma once
|
2023-11-17 08:04:02 -05:00
|
|
|
|
2018-04-30 21:20:26 +01:00
|
|
|
#include "Types.h"
|
2017-02-18 13:53:31 +00:00
|
|
|
#include <cassert>
|
2018-04-30 21:20:26 +01:00
|
|
|
#include <exception>
|
2009-01-28 23:06:08 +00:00
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
template <typename StructType>
|
2009-01-28 23:06:08 +00:00
|
|
|
class COsStructManager
|
|
|
|
{
|
|
|
|
public:
|
2015-08-05 23:38:40 -04:00
|
|
|
class iterator
|
|
|
|
{
|
|
|
|
public:
|
2018-04-30 21:01:23 +01:00
|
|
|
iterator(const COsStructManager& container, uint32 id)
|
|
|
|
: m_container(container)
|
|
|
|
, m_id(id)
|
|
|
|
{
|
|
|
|
}
|
2015-08-05 23:38:40 -04:00
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
iterator& operator++()
|
2015-08-05 23:38:40 -04:00
|
|
|
{
|
|
|
|
m_id++;
|
|
|
|
return (*this);
|
|
|
|
}
|
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
iterator operator++(int)
|
2015-08-05 23:38:40 -04:00
|
|
|
{
|
|
|
|
iterator copy(*this);
|
|
|
|
m_id++;
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
bool operator!=(const iterator& rhs) const
|
2015-08-05 23:38:40 -04:00
|
|
|
{
|
|
|
|
return m_id != rhs.m_id;
|
|
|
|
}
|
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
StructType* operator*() const
|
2015-08-05 23:38:40 -04:00
|
|
|
{
|
|
|
|
return m_container[m_id];
|
|
|
|
}
|
|
|
|
|
|
|
|
operator uint32() const
|
|
|
|
{
|
|
|
|
return m_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const COsStructManager& m_container;
|
|
|
|
uint32 m_id = 0;
|
|
|
|
};
|
2009-01-28 23:06:08 +00:00
|
|
|
|
2016-02-28 00:55:20 -05:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
INVALID_ID = -1
|
|
|
|
};
|
|
|
|
|
2015-01-28 01:24:36 -05:00
|
|
|
COsStructManager(StructType* structBase, uint32 idBase, uint32 structMax)
|
2018-04-30 21:01:23 +01:00
|
|
|
: m_structBase(structBase)
|
|
|
|
, m_structMax(structMax)
|
|
|
|
, m_idBase(idBase)
|
2009-01-28 23:06:08 +00:00
|
|
|
{
|
2024-06-03 16:55:50 -04:00
|
|
|
assert(m_idBase != INVALID_ID);
|
2009-01-28 23:06:08 +00:00
|
|
|
}
|
|
|
|
|
2015-08-08 18:14:56 -04:00
|
|
|
COsStructManager(const COsStructManager&) = delete;
|
2018-04-30 21:01:23 +01:00
|
|
|
COsStructManager& operator=(const COsStructManager) = delete;
|
2015-08-08 18:14:56 -04:00
|
|
|
|
2009-01-28 23:06:08 +00:00
|
|
|
StructType* GetBase() const
|
|
|
|
{
|
|
|
|
return m_structBase;
|
|
|
|
}
|
|
|
|
|
2023-11-16 17:58:37 -05:00
|
|
|
uint32 GetIdBase() const
|
|
|
|
{
|
|
|
|
return m_idBase;
|
|
|
|
}
|
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
StructType* operator[](uint32 index) const
|
2009-01-28 23:06:08 +00:00
|
|
|
{
|
|
|
|
index -= m_idBase;
|
|
|
|
if(index >= m_structMax)
|
|
|
|
{
|
2014-11-30 18:31:10 -05:00
|
|
|
return nullptr;
|
2009-01-28 23:06:08 +00:00
|
|
|
}
|
2015-01-28 01:24:36 -05:00
|
|
|
auto structPtr = m_structBase + index;
|
2009-01-28 23:06:08 +00:00
|
|
|
if(!structPtr->isValid)
|
|
|
|
{
|
2014-11-30 18:31:10 -05:00
|
|
|
return nullptr;
|
2009-01-28 23:06:08 +00:00
|
|
|
}
|
|
|
|
return structPtr;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 Allocate() const
|
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i < m_structMax; i++)
|
|
|
|
{
|
2018-04-11 12:33:25 -04:00
|
|
|
if(!m_structBase[i].isValid)
|
2009-01-28 23:06:08 +00:00
|
|
|
{
|
|
|
|
m_structBase[i].isValid = true;
|
|
|
|
return (i + m_idBase);
|
|
|
|
}
|
|
|
|
}
|
2016-02-28 00:55:20 -05:00
|
|
|
return INVALID_ID;
|
2009-01-28 23:06:08 +00:00
|
|
|
}
|
|
|
|
|
2023-11-16 17:58:37 -05:00
|
|
|
uint32 AllocateAt(uint32& nextId)
|
2023-11-10 16:52:50 -05:00
|
|
|
{
|
2023-11-16 17:58:37 -05:00
|
|
|
assert(nextId >= m_idBase);
|
|
|
|
uint32 nextIndex = nextId - m_idBase;
|
2023-11-10 16:52:50 -05:00
|
|
|
for(unsigned int i = 0; i < m_structMax; i++)
|
|
|
|
{
|
2023-11-16 17:58:37 -05:00
|
|
|
uint32 index = (i + nextIndex) % m_structMax;
|
2023-11-10 16:52:50 -05:00
|
|
|
if(!m_structBase[index].isValid)
|
|
|
|
{
|
|
|
|
m_structBase[index].isValid = true;
|
2023-11-16 17:58:37 -05:00
|
|
|
nextIndex = (index + 1) % m_structMax;
|
|
|
|
nextId = nextIndex + m_idBase;
|
|
|
|
return index + m_idBase;
|
2023-11-10 16:52:50 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return INVALID_ID;
|
|
|
|
}
|
|
|
|
|
2009-01-28 23:06:08 +00:00
|
|
|
void Free(uint32 id)
|
|
|
|
{
|
|
|
|
StructType* structPtr = (*this)[id];
|
|
|
|
if(!structPtr->isValid)
|
|
|
|
{
|
|
|
|
throw std::exception();
|
|
|
|
}
|
|
|
|
structPtr->isValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FreeAll()
|
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i < m_structMax; i++)
|
|
|
|
{
|
|
|
|
m_structBase[i].isValid = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-05 23:38:40 -04:00
|
|
|
iterator begin() const
|
2009-01-28 23:06:08 +00:00
|
|
|
{
|
2015-08-05 23:38:40 -04:00
|
|
|
return iterator(*this, m_idBase);
|
2009-01-28 23:06:08 +00:00
|
|
|
}
|
|
|
|
|
2015-08-05 23:38:40 -04:00
|
|
|
iterator end() const
|
2009-01-28 23:06:08 +00:00
|
|
|
{
|
2015-08-05 23:38:40 -04:00
|
|
|
return iterator(*this, m_idBase + m_structMax);
|
2009-01-28 23:06:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-04-30 21:01:23 +01:00
|
|
|
StructType* m_structBase = nullptr;
|
|
|
|
uint32 m_structMax = 0;
|
|
|
|
uint32 m_idBase = 0;
|
2009-01-28 23:06:08 +00:00
|
|
|
};
|