2016-03-27 11:49:47 +02:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
Copyright (C) 2008 the OpenMoHAA team
|
|
|
|
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
|
|
or (at your option) any later version.
|
|
|
|
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
===========================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
// container.h: C++ Container
|
|
|
|
|
2023-04-29 21:56:38 +02:00
|
|
|
#pragma once
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-04-29 21:56:38 +02:00
|
|
|
#if defined(GAME_DLL)
|
|
|
|
//
|
|
|
|
// game dll specific defines
|
|
|
|
//
|
2023-07-05 21:23:39 +02:00
|
|
|
# include "../fgame/g_local.h"
|
2023-04-29 21:56:38 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
# define CONTAINER_Error gi.Error
|
|
|
|
# define CONTAINER_DPrintf gi.DPrintf
|
|
|
|
# define CONTAINER_WDPrintf(text) gi.DPrintf(text)
|
2025-01-31 22:26:36 +01:00
|
|
|
# define CONTAINER_Alloc gi.Malloc
|
|
|
|
# define CONTAINER_Free gi.Free
|
2023-04-29 21:56:38 +02:00
|
|
|
|
|
|
|
#elif defined(CGAME_DLL)
|
|
|
|
//
|
|
|
|
// cgame dll specific defines
|
|
|
|
//
|
2023-07-05 21:23:39 +02:00
|
|
|
# include "../cgame/cg_local.h"
|
2023-04-29 21:56:38 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
# define CONTAINER_Error cgi.Error
|
|
|
|
# define CONTAINER_DPrintf cgi.DPrintf
|
|
|
|
# define CONTAINER_WDPrintf(text) cgi.DPrintf(text)
|
2025-01-31 22:26:36 +01:00
|
|
|
# define CONTAINER_Alloc cgi.Malloc
|
|
|
|
# define CONTAINER_Free cgi.Free
|
|
|
|
|
|
|
|
#elif defined(REF_DLL)
|
|
|
|
|
|
|
|
# include "../renderercommon/tr_common.h"
|
|
|
|
|
|
|
|
//
|
|
|
|
// client specific defines
|
|
|
|
//
|
|
|
|
# define CONTAINER_Error Com_Error
|
|
|
|
# define CONTAINER_DPrintf Com_DPrintf
|
|
|
|
# define CONTAINER_WDPrintf(text) Com_DPrintf(text)
|
|
|
|
# define CONTAINER_Alloc ri.Malloc
|
|
|
|
# define CONTAINER_Free ri.Free
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
#else
|
2023-04-29 21:56:38 +02:00
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
# include "qcommon.h"
|
|
|
|
|
2023-04-29 21:56:38 +02:00
|
|
|
//
|
|
|
|
// client specific defines
|
|
|
|
//
|
2023-07-05 21:23:39 +02:00
|
|
|
# define CONTAINER_Error Com_Error
|
|
|
|
# define CONTAINER_DPrintf Com_DPrintf
|
|
|
|
# define CONTAINER_WDPrintf(text) Com_DPrintf(text)
|
2025-01-31 22:26:36 +01:00
|
|
|
# define CONTAINER_Alloc Z_Malloc
|
|
|
|
# define CONTAINER_Free Z_Free
|
2016-03-27 11:49:47 +02:00
|
|
|
#endif
|
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
#include <utility>
|
|
|
|
#include <new>
|
|
|
|
|
2016-03-27 11:49:47 +02:00
|
|
|
class Archiver;
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
2016-03-27 11:49:47 +02:00
|
|
|
class Container
|
|
|
|
{
|
|
|
|
private:
|
2023-07-05 21:23:39 +02:00
|
|
|
Type *objlist;
|
|
|
|
int numobjects;
|
|
|
|
int maxobjects;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
private:
|
2023-02-04 19:56:06 +01:00
|
|
|
void Copy(const Container<Type>& container);
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
public:
|
2023-02-04 19:56:06 +01:00
|
|
|
Container();
|
2025-01-31 22:26:36 +01:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
Container(const Container<Type>& container);
|
2025-01-31 22:26:36 +01:00
|
|
|
Container<Type>& operator=(const Container<Type>& container);
|
|
|
|
|
|
|
|
Container(Container<Type>&& container);
|
|
|
|
Container<Type>& operator=(Container<Type>&& container);
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
~Container();
|
|
|
|
|
|
|
|
void Archive(Archiver& arc);
|
2023-07-05 21:23:39 +02:00
|
|
|
void Archive(Archiver& arc, void (*ArchiveFunc)(Archiver& arc, Type *obj));
|
2023-02-04 19:56:06 +01:00
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
int AddObject(const Type& obj);
|
|
|
|
int AddUniqueObject(const Type& obj);
|
|
|
|
void AddObjectAt(int index, const Type& obj);
|
2023-07-05 21:23:39 +02:00
|
|
|
Type *AddressOfObjectAt(int index);
|
2025-01-31 22:26:36 +01:00
|
|
|
void ClearObjectList(void);
|
|
|
|
void FreeObjectList(void);
|
|
|
|
int IndexOfObject(const Type& obj);
|
|
|
|
void InsertObjectAt(int index, const Type& obj);
|
|
|
|
int MaxObjects(void) const;
|
|
|
|
int NumObjects(void) const;
|
|
|
|
Type& ObjectAt(const size_t index) const;
|
|
|
|
bool ObjectInList(const Type& obj);
|
|
|
|
void RemoveObjectAt(int index);
|
|
|
|
void RemoveObject(const Type& obj);
|
|
|
|
void Reset(void);
|
|
|
|
void Resize(int maxelements);
|
|
|
|
void SetObjectAt(int index, const Type& obj);
|
|
|
|
void Sort(int (*compare)(const void *elem1, const void *elem2));
|
|
|
|
Type& operator[](const uintptr_t index) const;
|
2016-03-27 11:49:47 +02:00
|
|
|
};
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
2016-03-27 11:49:47 +02:00
|
|
|
Container<Type>::Container()
|
|
|
|
{
|
2023-07-05 21:23:39 +02:00
|
|
|
objlist = NULL;
|
2023-02-04 19:56:06 +01:00
|
|
|
numobjects = 0;
|
|
|
|
maxobjects = 0;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
Container<Type>::Container(const Container<Type>& container)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
objlist = NULL;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
Copy(container);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
template<class Type>
|
|
|
|
Container<Type>& Container<Type>::operator=(const Container<Type>& container)
|
|
|
|
{
|
|
|
|
Copy(container);
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class Type>
|
|
|
|
Container<Type>::Container(Container<Type>&& container)
|
|
|
|
{
|
|
|
|
objlist = container.objlist;
|
|
|
|
numobjects = container.numobjects;
|
|
|
|
maxobjects = container.maxobjects;
|
|
|
|
container.objlist = NULL;
|
|
|
|
container.numobjects = 0;
|
|
|
|
container.maxobjects = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class Type>
|
|
|
|
Container<Type>& Container<Type>::operator=(Container<Type>&& container)
|
|
|
|
{
|
|
|
|
objlist = container.objlist;
|
|
|
|
numobjects = container.numobjects;
|
|
|
|
maxobjects = container.maxobjects;
|
|
|
|
container.objlist = NULL;
|
|
|
|
container.numobjects = 0;
|
|
|
|
container.maxobjects = 0;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
2016-03-27 11:49:47 +02:00
|
|
|
Container<Type>::~Container()
|
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
FreeObjectList();
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
int Container<Type>::AddObject(const Type& obj)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
if (!objlist) {
|
|
|
|
Resize(10);
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if (numobjects >= maxobjects) {
|
|
|
|
Resize(numobjects * 2);
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
new (objlist + numobjects) Type(obj);
|
2023-02-04 19:56:06 +01:00
|
|
|
numobjects++;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
return numobjects;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
int Container<Type>::AddUniqueObject(const Type& obj)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
int index;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
index = IndexOfObject(obj);
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if (!index) {
|
|
|
|
index = AddObject(obj);
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
return index;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
void Container<Type>::AddObjectAt(int index, const Type& obj)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
if (index > maxobjects) {
|
|
|
|
Resize(index);
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if (index > numobjects) {
|
|
|
|
numobjects = index;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
SetObjectAt(index, obj);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
2023-07-05 21:23:39 +02:00
|
|
|
Type *Container<Type>::AddressOfObjectAt(int index)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
if (index > maxobjects) {
|
2023-07-05 21:23:39 +02:00
|
|
|
CONTAINER_Error(ERR_DROP, "Container::AddressOfObjectAt : index is greater than maxobjects");
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if (index > numobjects) {
|
|
|
|
numobjects = index;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
return &objlist[index - 1];
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
void Container<Type>::ClearObjectList(void)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-31 22:26:36 +01:00
|
|
|
size_t i;
|
2023-02-04 19:56:06 +01:00
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
if (objlist && numobjects) {
|
|
|
|
for (i = 0; i < numobjects; ++i) {
|
|
|
|
objlist[i].~Type();
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
// don't free the object list, it can be reused later
|
2023-02-04 19:56:06 +01:00
|
|
|
numobjects = 0;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
2025-01-31 22:26:36 +01:00
|
|
|
void Container<Type>::FreeObjectList(void)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-31 22:26:36 +01:00
|
|
|
size_t i;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
if (objlist) {
|
|
|
|
for (i = 0; i < numobjects; ++i) {
|
|
|
|
objlist[i].~Type();
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
CONTAINER_Free(objlist);
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
objlist = NULL;
|
2023-02-04 19:56:06 +01:00
|
|
|
numobjects = 0;
|
|
|
|
maxobjects = 0;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
int Container<Type>::IndexOfObject(const Type& obj)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
int i;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if (!objlist) {
|
|
|
|
return 0;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
for (i = 0; i < numobjects; i++) {
|
|
|
|
if (objlist[i] == obj) {
|
|
|
|
return i + 1;
|
|
|
|
}
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
return 0;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
void Container<Type>::InsertObjectAt(int index, const Type& obj)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-31 22:26:36 +01:00
|
|
|
size_t i;
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if ((index <= 0) || (index > numobjects + 1)) {
|
2023-07-05 21:23:39 +02:00
|
|
|
CONTAINER_Error(ERR_DROP, "Container::InsertObjectAt : index out of range");
|
2023-02-04 19:56:06 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
numobjects++;
|
2025-01-31 22:26:36 +01:00
|
|
|
intptr_t arrayIndex = index - 1;
|
2023-02-04 19:56:06 +01:00
|
|
|
|
|
|
|
if (numobjects > maxobjects) {
|
|
|
|
maxobjects = numobjects;
|
|
|
|
if (!objlist) {
|
2025-01-31 22:26:36 +01:00
|
|
|
objlist = (Type *)CONTAINER_Alloc(sizeof(Type) * maxobjects);
|
|
|
|
|
|
|
|
for (i = 0; i < arrayIndex; ++i) {
|
|
|
|
new (objlist + i) Type();
|
|
|
|
}
|
|
|
|
|
|
|
|
new (objlist + arrayIndex) Type(obj);
|
2023-02-04 19:56:06 +01:00
|
|
|
} else {
|
2023-07-05 21:23:39 +02:00
|
|
|
Type *temp = objlist;
|
2023-02-04 19:56:06 +01:00
|
|
|
if (maxobjects < numobjects) {
|
|
|
|
maxobjects = numobjects;
|
|
|
|
}
|
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
objlist = (Type *)CONTAINER_Alloc(sizeof(Type) * maxobjects);
|
2023-02-04 19:56:06 +01:00
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
for (i = 0; i < arrayIndex; ++i) {
|
|
|
|
new (objlist + i) Type(std::move(temp[i]));
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
new (objlist + arrayIndex) Type(obj);
|
|
|
|
for (i = arrayIndex + 1; i < numobjects; ++i) {
|
|
|
|
new (objlist + i) Type(std::move(temp[i]));
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
CONTAINER_Free(temp);
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
|
|
|
} else {
|
2025-01-31 22:26:36 +01:00
|
|
|
for (i = numobjects - 1; i > arrayIndex; i--) {
|
|
|
|
objlist[i] = std::move(objlist[i - 1]);
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
|
|
|
objlist[arrayIndex] = obj;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
int Container<Type>::MaxObjects(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
return maxobjects;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
int Container<Type>::NumObjects(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
return numobjects;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
Type& Container<Type>::ObjectAt(const size_t index) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
if ((index <= 0) || (index > numobjects)) {
|
|
|
|
CONTAINER_Error(ERR_DROP, "Container::ObjectAt : index out of range");
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
return objlist[index - 1];
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
bool Container<Type>::ObjectInList(const Type& obj)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
if (!IndexOfObject(obj)) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
return true;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
void Container<Type>::RemoveObjectAt(int index)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
int i;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if (!objlist) {
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if ((index <= 0) || (index > numobjects)) {
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
i = index - 1;
|
|
|
|
numobjects--;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
for (i = index - 1; i < numobjects; i++) {
|
2025-01-31 22:26:36 +01:00
|
|
|
objlist[i] = std::move(objlist[i + 1]);
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
2025-01-31 22:26:36 +01:00
|
|
|
|
|
|
|
// Destroy the last object as it's now useless
|
|
|
|
objlist[numobjects].~Type();
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
void Container<Type>::RemoveObject(const Type& obj)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
int index;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
index = IndexOfObject(obj);
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
assert(index);
|
|
|
|
if (!index) {
|
|
|
|
CONTAINER_WDPrintf("Container::RemoveObject : Object not in list\n");
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
RemoveObjectAt(index);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
2016-03-27 11:49:47 +02:00
|
|
|
void Container<Type>::Reset()
|
|
|
|
{
|
2023-07-05 21:23:39 +02:00
|
|
|
objlist = NULL;
|
2023-02-04 19:56:06 +01:00
|
|
|
numobjects = 0;
|
|
|
|
maxobjects = 0;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
void Container<Type>::Resize(int maxelements)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-31 22:26:36 +01:00
|
|
|
Type *temp;
|
|
|
|
size_t i;
|
2023-02-04 19:56:06 +01:00
|
|
|
|
|
|
|
if (maxelements <= 0) {
|
|
|
|
FreeObjectList();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!objlist) {
|
|
|
|
maxobjects = maxelements;
|
2025-01-31 22:26:36 +01:00
|
|
|
objlist = (Type *)CONTAINER_Alloc(sizeof(Type) * maxobjects);
|
2023-02-04 19:56:06 +01:00
|
|
|
} else {
|
|
|
|
temp = objlist;
|
|
|
|
|
|
|
|
maxobjects = maxelements;
|
|
|
|
|
|
|
|
if (maxobjects < numobjects) {
|
|
|
|
maxobjects = numobjects;
|
|
|
|
}
|
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
objlist = (Type *)CONTAINER_Alloc(sizeof(Type) * maxobjects);
|
2023-02-04 19:56:06 +01:00
|
|
|
|
|
|
|
for (i = 0; i < numobjects; i++) {
|
2025-01-31 22:26:36 +01:00
|
|
|
// move the older type
|
|
|
|
new (objlist + i) Type(std::move(temp[i]));
|
|
|
|
|
|
|
|
// destruct the older type
|
|
|
|
temp[i].~Type();
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
|
|
|
|
2025-01-31 22:26:36 +01:00
|
|
|
CONTAINER_Free(temp);
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
void Container<Type>::SetObjectAt(int index, const Type& obj)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
if (!objlist) {
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if ((index <= 0) || (index > numobjects)) {
|
2023-07-05 21:23:39 +02:00
|
|
|
CONTAINER_Error(ERR_DROP, "Container::SetObjectAt : index out of range");
|
2023-02-04 19:56:06 +01:00
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
objlist[index - 1] = obj;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
2023-07-05 21:23:39 +02:00
|
|
|
void Container<Type>::Sort(int (*compare)(const void *elem1, const void *elem2))
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
if (!objlist) {
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-07-05 21:23:39 +02:00
|
|
|
qsort((void *)objlist, (size_t)numobjects, sizeof(Type), compare);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
2025-01-31 22:26:36 +01:00
|
|
|
Type& Container<Type>::operator[](const uintptr_t index) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
return ObjectAt(index + 1);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
template<class Type>
|
|
|
|
void Container<Type>::Copy(const Container<Type>& container)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-02-04 19:56:06 +01:00
|
|
|
int i;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if (&container == this) {
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
FreeObjectList();
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
numobjects = container.numobjects;
|
|
|
|
maxobjects = container.maxobjects;
|
2023-07-05 21:23:39 +02:00
|
|
|
objlist = NULL;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if (container.objlist == NULL || !container.maxobjects) {
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
Resize(maxobjects);
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
if (!container.numobjects) {
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
for (i = 0; i < container.numobjects; i++) {
|
|
|
|
objlist[i] = container.objlist[i];
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-02-04 19:56:06 +01:00
|
|
|
return;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|