This commit is contained in:
L 2023-02-04 19:56:06 +01:00
parent 2763cfbd46
commit 294ca5ffd2
10 changed files with 1776 additions and 1840 deletions

View file

@ -25,9 +25,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef __CLASS_H__ #ifndef __CLASS_H__
#define __CLASS_H__ #define __CLASS_H__
#include "q_shared.h"
#include "container.h"
#include "con_set.h" #include "con_set.h"
#include "container.h"
#include "q_shared.h"
#include "str.h" #include "str.h"
#include "const_str.h" #include "const_str.h"
@ -35,208 +35,206 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class Class; class Class;
class Event; class Event;
#define isSubclassOf( classname )inheritsFrom( &classname::ClassInfo ) #define isSubclassOf(classname) inheritsFrom(&classname::ClassInfo)
#define isSuperclassOf( classname )isInheritedBy( &classname::ClassInfo ) #define isSuperclassOf(classname) isInheritedBy(&classname::ClassInfo)
#ifndef NO_SCRIPTENGINE #ifndef NO_SCRIPTENGINE
#define CLASS_DECLARATION( parentclass, classname, classid ) \ #define CLASS_DECLARATION(parentclass, classname, classid) \
ClassDef classname::ClassInfo \ ClassDef classname::ClassInfo(#classname, classid, #parentclass, \
( \ (ResponseDef<Class>*)classname::Responses, \
#classname, classid, #parentclass, \ classname::_newInstance, sizeof(classname)); \
(ResponseDef<Class> *)classname::Responses, \ void* classname::_newInstance(void) \
classname::_newInstance, sizeof( classname ) \ { \
); \ return new classname; \
void *classname::_newInstance( void ) \ } \
{ \ ClassDef* classname::classinfo(void) const \
return new classname; \ { \
} \ return &(classname::ClassInfo); \
ClassDef *classname::classinfo( void ) const \ } \
{ \ ClassDef* classname::classinfostatic(void) \
return &(classname::ClassInfo); \ { \
} \ return &(classname::ClassInfo); \
ClassDef *classname::classinfostatic( void ) \ } \
{ \ void classname::AddWaitTill(str s) \
return &(classname::ClassInfo); \ { \
} \ classname::ClassInfo.AddWaitTill(s); \
void classname::AddWaitTill( str s ) \ } \
{ \ void classname::AddWaitTill(const_str s) \
classname::ClassInfo.AddWaitTill( s ); \ { \
} \ classname::ClassInfo.AddWaitTill(s); \
void classname::AddWaitTill( const_str s ) \ } \
{ \ void classname::RemoveWaitTill(str s) \
classname::ClassInfo.AddWaitTill( s ); \ { \
} \ classname::ClassInfo.RemoveWaitTill(s); \
void classname::RemoveWaitTill( str s ) \ } \
{ \ void classname::RemoveWaitTill(const_str s) \
classname::ClassInfo.RemoveWaitTill( s ); \ { \
} \ classname::ClassInfo.RemoveWaitTill(s); \
void classname::RemoveWaitTill( const_str s ) \ } \
{ \ bool classname::WaitTillDefined(str s) \
classname::ClassInfo.RemoveWaitTill( s ); \ { \
} \ return classname::ClassInfo.WaitTillDefined(s); \
bool classname::WaitTillDefined( str s ) \ } \
{ \ bool classname::WaitTillDefined(const_str s) \
return classname::ClassInfo.WaitTillDefined( s ); \ { \
} \ return classname::ClassInfo.WaitTillDefined(s); \
bool classname::WaitTillDefined( const_str s ) \ } \
{ \ ResponseDef<classname> classname::Responses[] =
return classname::ClassInfo.WaitTillDefined( s ); \
} \
ResponseDef<classname> classname::Responses[] =
#define CLASS_PROTOTYPE( classname ) \ #define CLASS_PROTOTYPE(classname) \
public: \ public: \
static ClassDef ClassInfo; \ static ClassDef ClassInfo; \
static ClassDefHook _ClassInfo_; \ static ClassDefHook _ClassInfo_; \
static void *_newInstance( void ); \ static void* _newInstance(void); \
static ClassDef *classinfostatic(void); \ static ClassDef* classinfostatic(void); \
ClassDef *classinfo(void) const override; \ ClassDef* classinfo(void) const override; \
static void AddWaitTill( str s ); \ static void AddWaitTill(str s); \
static void AddWaitTill( const_str s ); \ static void AddWaitTill(const_str s); \
static void RemoveWaitTill( str s ); \ static void RemoveWaitTill(str s); \
static void RemoveWaitTill( const_str s ); \ static void RemoveWaitTill(const_str s); \
static bool WaitTillDefined( str s ); \ static bool WaitTillDefined(str s); \
static bool WaitTillDefined( const_str s ); \ static bool WaitTillDefined(const_str s); \
static ResponseDef<classname> Responses[] static ResponseDef<classname> Responses[]
#else #else
#define CLASS_DECLARATION( parentclass, classname, classid ) \ #define CLASS_DECLARATION(parentclass, classname, classid) \
ClassDef classname::ClassInfo \ ClassDef classname::ClassInfo(#classname, classid, #parentclass, \
( \ (ResponseDef<Class>*)classname::Responses, \
#classname, classid, #parentclass, \ classname::_newInstance, sizeof(classname)); \
(ResponseDef<Class> *)classname::Responses, \ void* classname::_newInstance(void) \
classname::_newInstance, sizeof( classname ) \ { \
); \ return new classname; \
void *classname::_newInstance( void ) \ } \
{ \ ClassDef* classname::classinfo(void) const \
return new classname; \ { \
} \ return &(classname::ClassInfo); \
ClassDef *classname::classinfo( void ) const \ } \
{ \ ClassDef* classname::classinfostatic(void) \
return &(classname::ClassInfo); \ { \
} \ return &(classname::ClassInfo); \
ClassDef *classname::classinfostatic( void ) \ } \
{ \ ResponseDef<classname> classname::Responses[] =
return &(classname::ClassInfo); \
} \
ResponseDef<classname> classname::Responses[] =
#define CLASS_PROTOTYPE( classname ) \ #define CLASS_PROTOTYPE(classname) \
public: \ public: \
static ClassDef ClassInfo; \ static ClassDef ClassInfo; \
static ClassDefHook _ClassInfo_; \ static ClassDefHook _ClassInfo_; \
static void *_newInstance( void ); \ static void* _newInstance(void); \
static ClassDef *classinfostatic(void); \ static ClassDef* classinfostatic(void); \
ClassDef *classinfo(void) const override; \ ClassDef* classinfo(void) const override; \
static ResponseDef<classname> Responses[] static ResponseDef<classname> Responses[]
#endif #endif
typedef void ( Class::*Response )( Event *ev ); typedef void (Class::*Response)(Event* ev);
class EventDef; class EventDef;
template< class Type > template<class Type>
struct ResponseDef struct ResponseDef
{ {
Event *event; Event* event;
void ( Type::*response )( Event *ev ); void (Type::*response)(Event* ev);
EventDef *def; EventDef* def;
}; };
class ClassDef class ClassDef
{ {
public: public:
const char *classname; const char* classname;
const char *classID; const char* classID;
const char *superclass; const char* superclass;
void *(*newInstance)(void); void* (*newInstance)(void);
int classSize; int classSize;
ResponseDef<Class> *responses; ResponseDef<Class>* responses;
ResponseDef<Class> **responseLookup; ResponseDef<Class>** responseLookup;
ClassDef *super; ClassDef* super;
ClassDef *next; ClassDef* next;
ClassDef *prev; ClassDef* prev;
#ifndef NO_SCRIPTENGINE #ifndef NO_SCRIPTENGINE
con_set<const_str, const_str> *waitTillSet; con_set<const_str, const_str>* waitTillSet;
#endif #endif
int numEvents; int numEvents;
static ClassDef *classlist; static ClassDef* classlist;
static int numclasses; static int numclasses;
static void BuildEventResponses(); static void BuildEventResponses();
void BuildResponseList(); void BuildResponseList();
static int dump_numclasses; static int dump_numclasses;
static int dump_numevents; static int dump_numevents;
static Container< int > sortedList; static Container<int> sortedList;
static Container< ClassDef * > sortedClassList; static Container<ClassDef*> sortedClassList;
ClassDef(); ClassDef();
~ClassDef(); ~ClassDef();
static int compareClasses( const void *arg1, const void *arg2 ); static int compareClasses(const void* arg1, const void* arg2);
static void SortClassList( Container< ClassDef * > *sortedList ); static void SortClassList(Container<ClassDef*>* sortedList);
#ifndef NO_SCRIPTENGINE #ifndef NO_SCRIPTENGINE
void AddWaitTill( str s ); void AddWaitTill(str s);
void AddWaitTill( const_str s ); void AddWaitTill(const_str s);
void RemoveWaitTill( str s ); void RemoveWaitTill(str s);
void RemoveWaitTill( const_str s ); void RemoveWaitTill(const_str s);
bool WaitTillDefined( str s ); bool WaitTillDefined(str s);
bool WaitTillDefined( const_str s ); bool WaitTillDefined(const_str s);
#endif #endif
/* Create-a-class function */ /* Create-a-class function */
ClassDef( const char *classname, const char *classID, const char *superclass, ResponseDef<Class> *responses, ClassDef(const char* classname, const char* classID, const char* superclass,
void *( *newInstance )( void ), int classSize ); ResponseDef<Class>* responses, void* (*newInstance)(void),
void CreateInternal( const char *classname, const char *classID, const char *superclass, ResponseDef<Class> *responses, int classSize);
void *( *newInstance )( void ), int classSize ); void CreateInternal(const char* classname, const char* classID,
void CreateInternalWin( const char *classname, const char *classID, const char *superclass, ResponseDef<Class> *responses, const char* superclass, ResponseDef<Class>* responses,
void *( *newInstance )( void ), int classSize ); void* (*newInstance)(void), int classSize);
void CreateInternalWin(const char* classname, const char* classID,
const char* superclass,
ResponseDef<Class>* responses,
void* (*newInstance)(void), int classSize);
EventDef *GetDef( int eventnum ); EventDef* GetDef(int eventnum);
int GetFlags( Event *event ); int GetFlags(Event* event);
void Destroy(); void Destroy();
}; };
ClassDef *getClassList( void ); ClassDef* getClassList(void);
qboolean checkInheritance( const ClassDef *superclass, const ClassDef *subclass ); qboolean checkInheritance(const ClassDef* superclass, const ClassDef* subclass);
qboolean checkInheritance( ClassDef *superclass, const char *subclass ); qboolean checkInheritance(ClassDef* superclass, const char* subclass);
qboolean checkInheritance( const char *superclass, const char *subclass ); qboolean checkInheritance(const char* superclass, const char* subclass);
void CLASS_Print( FILE *class_file, const char *fmt, ... ); void CLASS_Print(FILE* class_file, const char* fmt, ...);
void ClassEvents( const char *classname, qboolean print_to_disk ); void ClassEvents(const char* classname, qboolean print_to_disk);
void DumpClass( FILE * class_file, const char * className ); void DumpClass(FILE* class_file, const char* className);
void DumpAllClasses( void ); void DumpAllClasses(void);
class ClassDefHook class ClassDefHook
{ {
private: private:
ClassDef *classdef; ClassDef* classdef;
public: public:
//void * operator new( size_t ); // void * operator new( size_t );
//void operator delete( void * ); // void operator delete( void * );
ClassDefHook(); ClassDefHook();
~ClassDefHook(); ~ClassDefHook();
/* Hook-a-class function */ /* Hook-a-class function */
ClassDefHook( ClassDef * classdef, ResponseDef<Class> *responses ); ClassDefHook(ClassDef* classdef, ResponseDef<Class>* responses);
}; };
ClassDef *getClassForID( const char *name ); ClassDef* getClassForID(const char* name);
ClassDef *getClass( const char * name ); ClassDef* getClass(const char* name);
ClassDef *getClassList( void ); ClassDef* getClassList(void);
void listAllClasses( void ); void listAllClasses(void);
void listInheritanceOrder( const char *classname ); void listInheritanceOrder(const char* classname);
class SafePtrBase; class SafePtrBase;
class Archiver; class Archiver;
@ -244,40 +242,40 @@ class Archiver;
class Class class Class
{ {
public: public:
SafePtrBase *SafePtrList; SafePtrBase* SafePtrList;
private: private:
void ClearSafePointers(); void ClearSafePointers();
public: public:
#ifndef _DEBUG_MEM #ifndef _DEBUG_MEM
void * operator new( size_t ); void* operator new(size_t);
void operator delete( void * ); void operator delete(void*);
#endif #endif
Class(); Class();
virtual ~Class(); virtual ~Class();
virtual void Archive( Archiver& arc ); virtual void Archive(Archiver& arc);
static ClassDef ClassInfo; static ClassDef ClassInfo;
static ClassDefHook _ClassInfo_; static ClassDefHook _ClassInfo_;
static void *_newInstance( void ); static void* _newInstance(void);
static ClassDef *classinfostatic(void); static ClassDef* classinfostatic(void);
virtual ClassDef *classinfo(void) const; virtual ClassDef* classinfo(void) const;
static ResponseDef<Class> Responses[]; static ResponseDef<Class> Responses[];
const char *getClassID( void ) const; const char* getClassID(void) const;
const char *getClassname( void ) const; const char* getClassname(void) const;
const char *getSuperclass( void ) const; const char* getSuperclass(void) const;
qboolean inheritsFrom( ClassDef *c ) const; qboolean inheritsFrom(ClassDef* c) const;
qboolean inheritsFrom( const char * name ) const; qboolean inheritsFrom(const char* name) const;
qboolean isInheritedBy( const char * name ) const; qboolean isInheritedBy(const char* name) const;
qboolean isInheritedBy( ClassDef *c ) const; qboolean isInheritedBy(ClassDef* c) const;
void warning( const char *function, const char *format, ... ); void warning(const char* function, const char* format, ...);
void error( const char *function, const char *format, ... ); void error(const char* function, const char* format, ...);
}; };
#include "safeptr.h" #include "safeptr.h"

View file

@ -27,84 +27,88 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <listener.h> #include <listener.h>
#define MAX_CONFIGURATOR_ARRAY_SIZE 2048 #define MAX_CONFIGURATOR_ARRAY_SIZE 2048
typedef struct configValue_s { typedef struct configValue_s {
bool m_bNeedWrite; bool m_bNeedWrite;
str value; str value;
} configValue_t; } configValue_t;
typedef struct configKey_s { typedef struct configKey_s {
bool m_bNeedWrite; bool m_bNeedWrite;
str name; str name;
Container< configValue_t > value; Container<configValue_t> value;
bool m_bArray; bool m_bArray;
} configKey_t; } configKey_t;
typedef struct configSection_s { typedef struct configSection_s {
bool m_bNeedWrite; bool m_bNeedWrite;
str name; str name;
Container< configKey_t * > key; Container<configKey_t*> key;
} configSection_t; } configSection_t;
enum { enum { LINE_EMPTY, LINE_COMMENT, LINE_SECTION, LINE_VALUE, LINE_ERROR };
LINE_EMPTY,
LINE_COMMENT,
LINE_SECTION,
LINE_VALUE,
LINE_ERROR
};
class Configurator : public Class { class Configurator : public Class
{
private: private:
str m_filename; str m_filename;
bool m_bNoWrite; bool m_bNoWrite;
bool m_bNeedWrite; bool m_bNeedWrite;
con_set< str, configSection_t > m_sections; con_set<str, configSection_t> m_sections;
Container< configSection_t * > m_reverseSections; Container<configSection_t*> m_reverseSections;
private: private:
size_t GetLine( char *dest, const char *data, size_t size ); size_t GetLine(char* dest, const char* data, size_t size);
str GetValue( const char *section, const char *key, str defaultValue, int index = -1 ); str GetValue(const char* section, const char* key, str defaultValue,
configKey_t *GetKey( const char *section, const char *key, int index = -1 ); int index = -1);
configKey_t* GetKey(const char* section, const char* key, int index = -1);
int CutLine( char *data ); int CutLine(char* data);
bool SetupLine( char *line, int& lineno, size_t& len, size_t& last ); bool SetupLine(char* line, int& lineno, size_t& len, size_t& last);
bool FindData( int type, const char *section, const char *key, size_t *offset, const char *data, size_t size ); bool FindData(int type, const char* section, const char* key,
void ParseData( const char *data, size_t size ); size_t* offset, const char* data, size_t size);
void WriteData( char **data, size_t *size ); void ParseData(const char* data, size_t size);
void WriteData2( char **data, size_t *size ); void WriteData(char** data, size_t* size);
int ParseLine( char *line, char *section, char *key, char *value ); void WriteData2(char** data, size_t* size);
int ParseLine(char* line, char* section, char* key, char* value);
configSection_t *CreateSection( const char *section ); configSection_t* CreateSection(const char* section);
configSection_t *FindSection( const char *section ); configSection_t* FindSection(const char* section);
int GetKeyArray( char *key ); int GetKeyArray(char* key);
int GetKeyArray( str& key ); int GetKeyArray(str& key);
configKey_t *CreateKey( configSection_t *section, const char *key, unsigned int *index ); configKey_t* CreateKey(configSection_t* section, const char* key,
configKey_t *FindKey( configSection_t *section, const char *key ); unsigned int* index);
void RemoveSection( configSection_t *section ); configKey_t* FindKey(configSection_t* section, const char* key);
void RemoveKey( configSection_t *section, configKey_t *key ); void RemoveSection(configSection_t* section);
void RemoveKey(configSection_t* section, configKey_t* key);
public: public:
CLASS_PROTOTYPE( Configurator ); CLASS_PROTOTYPE(Configurator);
Configurator( const char *filename ); Configurator(const char* filename);
Configurator(); Configurator();
~Configurator(); ~Configurator();
void Parse( const char *filename ); void Parse(const char* filename);
void Close(); void Close();
void SetWrite( bool bWrite ); void SetWrite(bool bWrite);
str GetString( const char *section, const char *key, str defaultValue, int index = -1 ); str GetString(const char* section, const char* key, str defaultValue,
int GetInteger( const char *section, const char *key, int defaultValue, int index = -1 ); int index = -1);
float GetFloat( const char *section, const char *key, float defaultValue, int index = -1 ); int GetInteger(const char* section, const char* key, int defaultValue,
void SetString( const char *section, const char *key, str value, int index = -1 ); int index = -1);
void SetInteger( const char *section, const char *key, int value, int index = -1 ); float GetFloat(const char* section, const char* key, float defaultValue,
void SetFloat( const char *section, const char *key, float value, int index = -1 ); int index = -1);
void SetString(const char* section, const char* key, str value,
int index = -1);
void SetInteger(const char* section, const char* key, int value,
int index = -1);
void SetFloat(const char* section, const char* key, float value,
int index = -1);
}; };
void test_config( void ); void test_config(void);
#endif /* __CONFIGURATOR_H__ */ #endif /* __CONFIGURATOR_H__ */

View file

@ -27,145 +27,152 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifdef GAME_DLL #ifdef GAME_DLL
#ifdef WIN32 #ifdef WIN32
#define glbprintf( text ) gi.Printf( text ) #define glbprintf(text) gi.Printf(text)
#else #else
#define glbprintf( text ) #define glbprintf(text)
#endif #endif
#elif defined CGAME_DLL #elif defined CGAME_DLL
#define glbprintf( text ) cgi.Printf( text ) #define glbprintf(text) cgi.Printf(text)
#else #else
#define glbprintf( text ) printf( text ) #define glbprintf(text) printf(text)
#endif #endif
#ifdef _DEBUG #ifdef _DEBUG
#define CONTAINER_Error( id, text ) glbprintf( text ); assert( 0 ); #define CONTAINER_Error(id, text) \
glbprintf(text); \
assert(0);
#else #else
#define CONTAINER_Error( id, text ) throw( text ) //gi.Error #define CONTAINER_Error(id, text) throw(text) // gi.Error
#endif #endif
#define CONTAINER_DPrintf( text ) glbprintf( text ) #define CONTAINER_DPrintf(text) glbprintf(text)
#define CONTAINER_WDPrintf( text ) glbprintf( text ) #define CONTAINER_WDPrintf(text) glbprintf(text)
class Archiver; class Archiver;
template< class Type > template<class Type>
class Container class Container
{ {
private: private:
Type *objlist; Type* objlist;
int numobjects; int numobjects;
int maxobjects; int maxobjects;
private: private:
void Copy( const Container<Type>& container ); void Copy(const Container<Type>& container);
public: public:
Container(); Container();
Container( const Container<Type>& container ); Container(const Container<Type>& container);
~Container(); ~Container();
void Archive( Archiver& arc ); void Archive(Archiver& arc);
void Archive( Archiver& arc, void( *ArchiveFunc )( Archiver &arc, Type *obj ) ); void Archive(Archiver& arc, void (*ArchiveFunc)(Archiver& arc, Type* obj));
int AddObject( const Type& obj ); int AddObject(const Type& obj);
int AddUniqueObject( const Type& obj ); int AddUniqueObject(const Type& obj);
void AddObjectAt( int index, const Type& obj ); void AddObjectAt(int index, const Type& obj);
Type *AddressOfObjectAt( int index ); Type* AddressOfObjectAt(int index);
// void Archive( Archiver &arc ); // void Archive( Archiver &arc );
void ClearObjectList( void ); void ClearObjectList(void);
void Fix( void ); void Fix(void);
void FreeObjectList( void ); void FreeObjectList(void);
int IndexOfObject( const Type& obj ); int IndexOfObject(const Type& obj);
void InsertObjectAt( int index, const Type& obj ); void InsertObjectAt(int index, const Type& obj);
int MaxObjects( void ) const; int MaxObjects(void) const;
int NumObjects( void ) const; int NumObjects(void) const;
Type& ObjectAt( const size_t index ) const; Type& ObjectAt(const size_t index) const;
bool ObjectInList( const Type& obj ); bool ObjectInList(const Type& obj);
void RemoveObjectAt( int index ); void RemoveObjectAt(int index);
void RemoveObject( const Type& obj ); void RemoveObject(const Type& obj);
void Reset( void ); void Reset(void);
void Resize( int maxelements ); void Resize(int maxelements);
void SetObjectAt( int index, const Type& obj ); void SetObjectAt(int index, const Type& obj);
void Sort( int( *compare )( const void *elem1, const void *elem2 ) ); void Sort(int (*compare)(const void* elem1, const void* elem2));
Type& operator[]( const int index ) const; Type& operator[](const int index) const;
Container<Type>& operator=( const Container<Type>& container ); Container<Type>& operator=(const Container<Type>& container);
}; };
template< class Type > template<class Type>
Container<Type>::Container() Container<Type>::Container()
{ {
objlist = NULL; objlist = NULL;
numobjects = 0; numobjects = 0;
maxobjects = 0; maxobjects = 0;
} }
template< class Type > template<class Type>
Container<Type>::Container( const Container<Type>& container ) Container<Type>::Container(const Container<Type>& container)
{ {
objlist = NULL; objlist = NULL;
Copy( container ); Copy(container);
} }
template< class Type > template<class Type>
Container<Type>::~Container() Container<Type>::~Container()
{ {
FreeObjectList(); FreeObjectList();
} }
template< class Type > template<class Type>
int Container<Type>::AddObject( const Type& obj ) int Container<Type>::AddObject(const Type& obj)
{ {
if ( !objlist ) if (!objlist) {
Resize( 10 ); Resize(10);
}
if ( numobjects >= maxobjects ) { if (numobjects >= maxobjects) {
Resize( numobjects * 2 ); Resize(numobjects * 2);
} }
objlist[numobjects] = obj; objlist[numobjects] = obj;
numobjects++; numobjects++;
return numobjects; return numobjects;
} }
template< class Type > template<class Type>
int Container<Type>::AddUniqueObject( const Type& obj ) int Container<Type>::AddUniqueObject(const Type& obj)
{ {
int index; int index;
index = IndexOfObject( obj ); index = IndexOfObject(obj);
if ( !index ) { if (!index) {
index = AddObject( obj ); index = AddObject(obj);
} }
return index; return index;
} }
template< class Type > template<class Type>
void Container<Type>::AddObjectAt( int index, const Type& obj ) void Container<Type>::AddObjectAt(int index, const Type& obj)
{ {
if ( index > maxobjects ) if (index > maxobjects) {
Resize( index ); Resize(index);
}
if ( index > numobjects ) if (index > numobjects) {
numobjects = index; numobjects = index;
}
SetObjectAt( index, obj ); SetObjectAt(index, obj);
} }
template< class Type > template<class Type>
Type *Container<Type>::AddressOfObjectAt( int index ) Type* Container<Type>::AddressOfObjectAt(int index)
{ {
if ( index > maxobjects ) { if (index > maxobjects) {
CONTAINER_Error( ERR_DROP, "Container::AddressOfObjectAt : index is greater than maxobjects" ); CONTAINER_Error(
} ERR_DROP,
"Container::AddressOfObjectAt : index is greater than maxobjects");
}
if ( index > numobjects ) { if (index > numobjects) {
numobjects = index; numobjects = index;
} }
return &objlist[index - 1]; return &objlist[index - 1];
} }
/*template< class Type > /*template< class Type >
@ -174,318 +181,307 @@ void Container<Type>::Archive( Archiver &arc )
}*/ }*/
template< class Type > template<class Type>
void Container<Type>::ClearObjectList( void ) void Container<Type>::ClearObjectList(void)
{ {
if ( objlist && numobjects ) if (objlist && numobjects) {
{ delete[] objlist;
delete[] objlist;
if ( maxobjects == 0 ) if (maxobjects == 0) {
{ objlist = NULL;
objlist = NULL; return;
return; }
}
objlist = new Type[maxobjects]; objlist = new Type[maxobjects];
numobjects = 0; numobjects = 0;
} }
} }
template< class Type > template<class Type>
void Container<Type>::Fix( void ) void Container<Type>::Fix(void)
{ {
if( !objlist || !numobjects ) { if (!objlist || !numobjects) {
return; return;
} }
Type *newlist = new Type[ numobjects ]; Type* newlist = new Type[numobjects];
int j = 0; int j = 0;
for( int i = 0; i < numobjects; i++ ) for (int i = 0; i < numobjects; i++) {
{ if (objlist[i] == NULL) {
if( objlist[ i ] == NULL ) { continue;
continue; }
}
newlist[ j ] = objlist[ i ]; newlist[j] = objlist[i];
j++; j++;
} }
numobjects = j; numobjects = j;
delete[] objlist; delete[] objlist;
objlist = newlist; objlist = newlist;
if( !numobjects ) { if (!numobjects) {
ClearObjectList(); ClearObjectList();
} }
} }
template< class Type > template<class Type>
void Container<Type>::FreeObjectList( void ) void Container<Type>::FreeObjectList(void)
{ {
if( objlist ) { if (objlist) {
delete[] objlist; delete[] objlist;
} }
objlist = NULL; objlist = NULL;
numobjects = 0; numobjects = 0;
maxobjects = 0; maxobjects = 0;
} }
template< class Type > template<class Type>
int Container<Type>::IndexOfObject( const Type& obj ) int Container<Type>::IndexOfObject(const Type& obj)
{ {
int i; int i;
if ( !objlist ) { if (!objlist) {
return 0; return 0;
} }
for ( i = 0; i < numobjects; i++ ) for (i = 0; i < numobjects; i++) {
{ if (objlist[i] == obj) {
if ( objlist[i] == obj ) return i + 1;
{ }
return i + 1; }
}
}
return 0; return 0;
} }
template< class Type > template<class Type>
void Container<Type>::InsertObjectAt( int index, const Type& obj ) void Container<Type>::InsertObjectAt(int index, const Type& obj)
{ {
if ( ( index <= 0 ) || ( index > numobjects + 1 ) ) if ((index <= 0) || (index > numobjects + 1)) {
{ CONTAINER_Error(ERR_DROP,
CONTAINER_Error( ERR_DROP, "Container::InsertObjectAt : index out of range" ); "Container::InsertObjectAt : index out of range");
return; return;
} }
numobjects++; numobjects++;
int arrayIndex = index - 1; int arrayIndex = index - 1;
if ( numobjects > maxobjects ) if (numobjects > maxobjects) {
{ maxobjects = numobjects;
maxobjects = numobjects; if (!objlist) {
if ( !objlist ) { objlist = new Type[maxobjects];
objlist = new Type[maxobjects]; objlist[arrayIndex] = obj;
objlist[arrayIndex] = obj; return;
return; } else {
} Type* temp = objlist;
else if (maxobjects < numobjects) {
{ maxobjects = numobjects;
Type *temp = objlist; }
if ( maxobjects < numobjects )
{
maxobjects = numobjects;
}
objlist = new Type[maxobjects]; objlist = new Type[maxobjects];
int i; int i;
for ( i = arrayIndex - 1; i >= 0; i-- ) { for (i = arrayIndex - 1; i >= 0; i--) {
objlist[i] = temp[i]; objlist[i] = temp[i];
} }
objlist[arrayIndex] = obj; objlist[arrayIndex] = obj;
for ( i = numobjects - 1; i > arrayIndex; i-- ) { for (i = numobjects - 1; i > arrayIndex; i--) {
objlist[i] = temp[i - 1]; objlist[i] = temp[i - 1];
} }
delete[] temp; delete[] temp;
} }
} } else {
else for (int i = numobjects - 1; i > arrayIndex; i--) {
{ objlist[i] = objlist[i - 1];
for ( int i = numobjects - 1; i > arrayIndex; i-- ) { }
objlist[i] = objlist[i - 1]; objlist[arrayIndex] = obj;
} }
objlist[arrayIndex] = obj;
}
} }
template< class Type > template<class Type>
int Container<Type>::MaxObjects( void ) const int Container<Type>::MaxObjects(void) const
{ {
return maxobjects; return maxobjects;
} }
template< class Type > template<class Type>
int Container<Type>::NumObjects( void ) const int Container<Type>::NumObjects(void) const
{ {
return numobjects; return numobjects;
} }
template< class Type > template<class Type>
Type& Container<Type>::ObjectAt( const size_t index ) const Type& Container<Type>::ObjectAt(const size_t index) const
{ {
if( ( index <= 0 ) || ( index > numobjects ) ) { if ((index <= 0) || (index > numobjects)) {
CONTAINER_Error( ERR_DROP, "Container::ObjectAt : index out of range" ); CONTAINER_Error(ERR_DROP, "Container::ObjectAt : index out of range");
} }
return objlist[index - 1]; return objlist[index - 1];
} }
template< class Type > template<class Type>
bool Container<Type>::ObjectInList( const Type& obj ) bool Container<Type>::ObjectInList(const Type& obj)
{ {
if ( !IndexOfObject( obj ) ) { if (!IndexOfObject(obj)) {
return false; return false;
} }
return true; return true;
} }
template< class Type > template<class Type>
void Container<Type>::RemoveObjectAt( int index ) void Container<Type>::RemoveObjectAt(int index)
{ {
int i; int i;
if ( !objlist ) if (!objlist) {
return; return;
}
if ( ( index <= 0 ) || ( index > numobjects ) ) if ((index <= 0) || (index > numobjects)) {
return; return;
}
i = index - 1; i = index - 1;
numobjects--; numobjects--;
for ( i = index - 1; i < numobjects; i++ ) for (i = index - 1; i < numobjects; i++) {
objlist[i] = objlist[i + 1]; objlist[i] = objlist[i + 1];
}
} }
template< class Type > template<class Type>
void Container<Type>::RemoveObject( const Type& obj ) void Container<Type>::RemoveObject(const Type& obj)
{ {
int index; int index;
index = IndexOfObject( obj ); index = IndexOfObject(obj);
assert( index ); assert(index);
if ( !index ) if (!index) {
{ CONTAINER_WDPrintf("Container::RemoveObject : Object not in list\n");
CONTAINER_WDPrintf( "Container::RemoveObject : Object not in list\n" ); return;
return; }
}
RemoveObjectAt( index ); RemoveObjectAt(index);
} }
template< class Type > template<class Type>
void Container<Type>::Reset() void Container<Type>::Reset()
{ {
objlist = NULL; objlist = NULL;
numobjects = 0; numobjects = 0;
maxobjects = 0; maxobjects = 0;
} }
template< class Type > template<class Type>
void Container<Type>::Resize( int maxelements ) void Container<Type>::Resize(int maxelements)
{ {
Type* temp; Type* temp;
int i; int i;
if ( maxelements <= 0 ) if (maxelements <= 0) {
{ FreeObjectList();
FreeObjectList(); return;
return; }
}
if ( !objlist ) if (!objlist) {
{ maxobjects = maxelements;
maxobjects = maxelements; objlist = new Type[maxobjects];
objlist = new Type[maxobjects]; } else {
} temp = objlist;
else
{
temp = objlist;
maxobjects = maxelements; maxobjects = maxelements;
if ( maxobjects < numobjects ) { if (maxobjects < numobjects) {
maxobjects = numobjects; maxobjects = numobjects;
} }
objlist = new Type[maxobjects]; objlist = new Type[maxobjects];
for ( i = 0; i < numobjects; i++ ) { for (i = 0; i < numobjects; i++) {
objlist[i] = temp[i]; objlist[i] = temp[i];
} }
delete[] temp; delete[] temp;
} }
} }
template< class Type > template<class Type>
void Container<Type>::SetObjectAt( int index, const Type& obj ) void Container<Type>::SetObjectAt(int index, const Type& obj)
{ {
if ( !objlist ) if (!objlist) {
return; return;
}
if( ( index <= 0 ) || ( index > numobjects ) ) { if ((index <= 0) || (index > numobjects)) {
CONTAINER_Error( ERR_DROP, "Container::SetObjectAt : index out of range" ); CONTAINER_Error(ERR_DROP,
} "Container::SetObjectAt : index out of range");
}
objlist[index - 1] = obj; objlist[index - 1] = obj;
} }
template< class Type > template<class Type>
void Container<Type>::Sort( int( *compare )( const void *elem1, const void *elem2 ) ) void Container<Type>::Sort(int (*compare)(const void* elem1, const void* elem2))
{ {
if ( !objlist ) { if (!objlist) {
return; return;
} }
qsort( ( void * )objlist, ( size_t )numobjects, sizeof( Type ), compare ); qsort((void*)objlist, (size_t)numobjects, sizeof(Type), compare);
} }
template< class Type > template<class Type>
Type& Container<Type>::operator[]( const int index ) const Type& Container<Type>::operator[](const int index) const
{ {
return ObjectAt( index + 1 ); return ObjectAt(index + 1);
} }
template< class Type > template<class Type>
void Container<Type>::Copy( const Container<Type>& container ) void Container<Type>::Copy(const Container<Type>& container)
{ {
int i; int i;
if( &container == this ) { if (&container == this) {
return; return;
} }
FreeObjectList(); FreeObjectList();
numobjects = container.numobjects; numobjects = container.numobjects;
maxobjects = container.maxobjects; maxobjects = container.maxobjects;
objlist = NULL; objlist = NULL;
if( container.objlist == NULL || !container.maxobjects ) { if (container.objlist == NULL || !container.maxobjects) {
return; return;
} }
Resize( maxobjects ); Resize(maxobjects);
if( !container.numobjects ) { if (!container.numobjects) {
return; return;
} }
for( i = 0; i < container.numobjects; i++ ) { for (i = 0; i < container.numobjects; i++) {
objlist[ i ] = container.objlist[ i ]; objlist[i] = container.objlist[i];
} }
return; return;
} }
template< class Type > template<class Type>
Container<Type>& Container<Type>::operator=( const Container<Type>& container ) Container<Type>& Container<Type>::operator=(const Container<Type>& container)
{ {
Copy( container ); Copy(container);
return *this; return *this;
} }
#endif /* __CONTAINER_H__ */ #endif /* __CONTAINER_H__ */

View file

@ -26,34 +26,53 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "container.h" #include "container.h"
template< class Type > template<class Type>
class ContainerClass : public Class { class ContainerClass : public Class
Container< Type > value; {
Container<Type> value;
public: public:
virtual ~ContainerClass() { value.FreeObjectList(); } virtual ~ContainerClass() { value.FreeObjectList(); }
virtual void Archive( Archiver& arc ); virtual void Archive(Archiver& arc);
int AddObject( const Type& obj ) { return value.AddObject( obj ); } int AddObject(const Type& obj) { return value.AddObject(obj); }
int AddUniqueObject( const Type& obj ) { return value.AddUniqueObject( obj ); } int AddUniqueObject(const Type& obj) { return value.AddUniqueObject(obj); }
void AddObjectAt( int index, const Type& obj ) { return value.AddObjectAt( index, obj ); } void AddObjectAt(int index, const Type& obj)
Type *AddressOfObjectAt( int index ) { return value.AddressOfObjectAt( index ); } {
return value.AddObjectAt(index, obj);
}
Type* AddressOfObjectAt(int index)
{
return value.AddressOfObjectAt(index);
}
void ClearObjectList( void ) { return value.ClearObjectList(); } void ClearObjectList(void) { return value.ClearObjectList(); }
void Fix( void ) { return value.Fix(); } void Fix(void) { return value.Fix(); }
void FreeObjectList( void ) { return value.FreeObjectList(); } void FreeObjectList(void) { return value.FreeObjectList(); }
int IndexOfObject( const Type& obj ) { return value.IndexOfObject( obj ); } int IndexOfObject(const Type& obj) { return value.IndexOfObject(obj); }
void InsertObjectAt( int index, const Type& obj ) { return value.InsertObjectAt( index, obj ); } void InsertObjectAt(int index, const Type& obj)
int NumObjects( void ) const { return value.NumObjects(); } {
Type& ObjectAt( const size_t index ) const { return value.ObjectAt( index ); } return value.InsertObjectAt(index, obj);
bool ObjectInList( const Type& obj ) { return value.ObjectInList( obj ); } }
void RemoveObjectAt( int index ) { return value.RemoveObjectAt( index ); } int NumObjects(void) const { return value.NumObjects(); }
void RemoveObject( const Type& obj ) { return value.RemoveObject( obj ); } Type& ObjectAt(const size_t index) const { return value.ObjectAt(index); }
void Reset( void ) { return value.Reset(); } bool ObjectInList(const Type& obj) { return value.ObjectInList(obj); }
void Resize( int maxelements ) { return value.Resize( maxelements ); } void RemoveObjectAt(int index) { return value.RemoveObjectAt(index); }
void SetObjectAt( int index, const Type& obj ) { return value.SetObjectAt( index, obj ); } void RemoveObject(const Type& obj) { return value.RemoveObject(obj); }
void Sort( int( *compare )( const void *elem1, const void *elem2 ) ) { return value.Sort( compare ); } void Reset(void) { return value.Reset(); }
Type& operator[]( const int index ) const { return value[ index ]; } void Resize(int maxelements) { return value.Resize(maxelements); }
Container<Type>& operator=( const Container<Type>& container ) { return value = container; } void SetObjectAt(int index, const Type& obj)
{
return value.SetObjectAt(index, obj);
}
void Sort(int (*compare)(const void* elem1, const void* elem2))
{
return value.Sort(compare);
}
Type& operator[](const int index) const { return value[index]; }
Container<Type>& operator=(const Container<Type>& container)
{
return value = container;
}
}; };

View file

@ -26,28 +26,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h" #include "g_local.h"
void *MEM_Alloc( int size ) void* MEM_Alloc(int size) { return gi.Malloc(size); }
{
return gi.Malloc( size );
}
void MEM_Free( void *ptr ) void MEM_Free(void* ptr) { return gi.Free(ptr); }
{
return gi.Free( ptr );
}
#else #else
#include "qcommon.h" #include "qcommon.h"
void* MEM_Alloc(int size) void* MEM_Alloc(int size) { return Z_Malloc(size); }
{
return Z_Malloc(size);
}
void MEM_Free(void* ptr) void MEM_Free(void* ptr) { return Z_Free(ptr); }
{
return Z_Free(ptr);
}
#endif #endif

View file

@ -31,451 +31,438 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <type_traits> #include <type_traits>
#include <new> #include <new>
void *MEM_Alloc( int size ); void* MEM_Alloc(int size);
void MEM_Free( void *ptr ); void MEM_Free(void* ptr);
static constexpr size_t DefaultBlock = 256; static constexpr size_t DefaultBlock = 256;
enum class alloc_source_e enum class alloc_source_e { SourceBlock = 174, SourceMalloc };
{
SourceBlock = 174,
SourceMalloc
};
template<typename aclass, size_t blocksize> template<typename aclass, size_t blocksize>
class MEM_BlockAlloc_enum; class MEM_BlockAlloc_enum;
template<typename aclass, size_t blocksize> template<typename aclass, size_t blocksize>
class block_s { class block_s
{
private: private:
static constexpr size_t bitsNeeded = static constexpr size_t bitsNeeded = blocksize <= 0x80 ? 8
blocksize <= 0x80 ? 8 : : blocksize <= 0x8000 ? 16
blocksize <= 0x8000 ? 16 : : blocksize <= 0x80000000 ? 32
blocksize <= 0x80000000 ? 32 : : 64;
64;
public: public:
block_s(); block_s();
#if !_DEBUG_MEMBLOCK #if !_DEBUG_MEMBLOCK
bool usedDataAvailable() const; bool usedDataAvailable() const;
bool freeDataAvailable() const; bool freeDataAvailable() const;
#endif #endif
public: public:
template<size_t bits> template<size_t bits>
struct selectType_t; struct selectType_t;
template<> struct selectType_t<8> { using type = uint8_t; }; template<>
template<> struct selectType_t<16> { using type = uint16_t; }; struct selectType_t<8> {
template<> struct selectType_t<32> { using type = uint32_t; }; using type = uint8_t;
template<> struct selectType_t<64> { using type = uint64_t; }; };
template<>
struct selectType_t<16> {
using type = uint16_t;
};
template<>
struct selectType_t<32> {
using type = uint32_t;
};
template<>
struct selectType_t<64> {
using type = uint64_t;
};
using offset_t = typename selectType_t<bitsNeeded>::type; using offset_t = typename selectType_t<bitsNeeded>::type;
struct info_t { struct info_t {
offset_t index; offset_t index;
alloc_source_e source; alloc_source_e source;
static constexpr uint16_t typeSize = sizeof(aclass); static constexpr uint16_t typeSize = sizeof(aclass);
alignas(alignof(aclass)) char data[sizeof(aclass)]; alignas(alignof(aclass)) char data[sizeof(aclass)];
}; };
public: public:
#if !_DEBUG_MEMBLOCK #if !_DEBUG_MEMBLOCK
info_t data[blocksize]; info_t data[blocksize];
offset_t prev_data[blocksize]; offset_t prev_data[blocksize];
offset_t next_data[blocksize]; offset_t next_data[blocksize];
offset_t free_data; offset_t free_data;
offset_t used_data; offset_t used_data;
bool has_free_data : 1; bool has_free_data : 1;
bool has_used_data : 1; bool has_used_data : 1;
#else #else
offset_t data[sizeof(aclass)]; offset_t data[sizeof(aclass)];
#endif #endif
block_s<aclass, blocksize>* prev_block; block_s<aclass, blocksize>* prev_block;
block_s<aclass, blocksize>* next_block; block_s<aclass, blocksize>* next_block;
public: public:
static constexpr size_t headersize = offsetof(info_t, data); static constexpr size_t headersize = offsetof(info_t, data);
static constexpr size_t dataoffset = 0; static constexpr size_t dataoffset = 0;
static constexpr size_t datasize = sizeof(info_t); static constexpr size_t datasize = sizeof(info_t);
}; };
template<typename aclass, size_t blocksize> template<typename aclass, size_t blocksize>
block_s<aclass, blocksize>::block_s() block_s<aclass, blocksize>::block_s()
#if !_DEBUG_MEMBLOCK #if !_DEBUG_MEMBLOCK
{ {
info_t* header; info_t* header;
offset_t curr; offset_t curr;
for (curr = 0; curr < blocksize - 1; ++curr) for (curr = 0; curr < blocksize - 1; ++curr) {
{ offset_t next = curr + 1;
offset_t next = curr + 1; header = &data[curr];
header = &data[curr]; header->source = alloc_source_e::SourceBlock;
header->source = alloc_source_e::SourceBlock; header->index = curr;
header->index = curr; prev_data[next] = curr;
prev_data[next] = curr; next_data[curr] = next;
next_data[curr] = next; }
}
header = &data[curr]; header = &data[curr];
header->source = alloc_source_e::SourceBlock; header->source = alloc_source_e::SourceBlock;
header->index = blocksize - 1; header->index = blocksize - 1;
prev_data[0] = blocksize - 1; prev_data[0] = blocksize - 1;
next_data[blocksize - 1] = 0; next_data[blocksize - 1] = 0;
free_data = 0; free_data = 0;
prev_block = next_block = nullptr; prev_block = next_block = nullptr;
has_free_data = true; has_free_data = true;
has_used_data = false; has_used_data = false;
} }
#else #else
: prev_block(nullptr) : prev_block(nullptr), next_block(nullptr)
, next_block(nullptr) {}
{
}
#endif #endif
#if !_DEBUG_MEMBLOCK #if !_DEBUG_MEMBLOCK
template<typename aclass, size_t blocksize> template<typename aclass, size_t blocksize>
bool block_s<aclass, blocksize>::usedDataAvailable() const { bool block_s<aclass, blocksize>::usedDataAvailable() const
return has_used_data; {
return has_used_data;
} }
template<typename aclass, size_t blocksize> template<typename aclass, size_t blocksize>
bool block_s<aclass, blocksize>::freeDataAvailable() const { bool block_s<aclass, blocksize>::freeDataAvailable() const
return has_free_data; {
return has_free_data;
} }
#endif #endif
template<typename aclass, size_t blocksize = DefaultBlock> template<typename aclass, size_t blocksize = DefaultBlock>
class MEM_BlockAlloc class MEM_BlockAlloc
{ {
static_assert(blocksize >= 2, "Minimum 2x class preallocation required!!"); static_assert(blocksize >= 2, "Minimum 2x class preallocation required!!");
public:
MEM_BlockAlloc();
~MEM_BlockAlloc();
void* Alloc(); public:
void Free(void* ptr) noexcept; MEM_BlockAlloc();
void FreeAll() noexcept; ~MEM_BlockAlloc();
size_t Count();
size_t BlockCount(); void* Alloc();
size_t BlockMemory(); void Free(void* ptr) noexcept;
void FreeAll() noexcept;
size_t Count();
size_t BlockCount();
size_t BlockMemory();
private: private:
friend class MEM_BlockAlloc_enum<aclass, blocksize>; friend class MEM_BlockAlloc_enum<aclass, blocksize>;
using block_t = block_s<aclass, blocksize>; using block_t = block_s<aclass, blocksize>;
using block_offset_t = typename block_t::offset_t; using block_offset_t = typename block_t::offset_t;
#if !_DEBUG_MEMBLOCK #if !_DEBUG_MEMBLOCK
block_t* m_FreeBlock; block_t* m_FreeBlock;
block_t* m_StartUsedBlock; block_t* m_StartUsedBlock;
block_t* m_StartFullBlock; block_t* m_StartFullBlock;
#else #else
block_t* m_Block; block_t* m_Block;
#endif #endif
size_t m_BlockCount; size_t m_BlockCount;
private: private:
void* TakeFree(block_t* block, uintptr_t free_data); void* TakeFree(block_t* block, uintptr_t free_data);
size_t Count(const block_t* block); size_t Count(const block_t* block);
}; };
template<typename aclass, size_t blocksize = DefaultBlock> template<typename aclass, size_t blocksize = DefaultBlock>
class MEM_BlockAlloc_enum class MEM_BlockAlloc_enum
{ {
public: public:
MEM_BlockAlloc_enum(MEM_BlockAlloc<aclass, blocksize>& owner); MEM_BlockAlloc_enum(MEM_BlockAlloc<aclass, blocksize>& owner);
aclass* NextElement(); aclass* NextElement();
aclass* CurrentElement(); aclass* CurrentElement();
enum blockType_e { enum blockType_e { used, full };
used,
full
};
private: private:
using block_t = block_s<aclass, blocksize>; using block_t = block_s<aclass, blocksize>;
using offset_t = typename block_t::offset_t; using offset_t = typename block_t::offset_t;
MEM_BlockAlloc<aclass, blocksize>* m_Owner; MEM_BlockAlloc<aclass, blocksize>* m_Owner;
block_t* m_CurrentBlock; block_t* m_CurrentBlock;
#if !_DEBUG_MEMBLOCK #if !_DEBUG_MEMBLOCK
offset_t m_CurrentData; offset_t m_CurrentData;
blockType_e m_CurrentBlockType; blockType_e m_CurrentBlockType;
#endif #endif
}; };
template<typename a, size_t b> template<typename a, size_t b>
MEM_BlockAlloc<a, b>::MEM_BlockAlloc() MEM_BlockAlloc<a, b>::MEM_BlockAlloc()
#if !_DEBUG_MEMBLOCK #if !_DEBUG_MEMBLOCK
: m_StartUsedBlock() : m_StartUsedBlock(), m_StartFullBlock()
, m_StartFullBlock()
{ {
m_FreeBlock = nullptr; m_FreeBlock = nullptr;
m_BlockCount = 0; m_BlockCount = 0;
} }
#else #else
: m_Block() : m_Block()
{ {
m_BlockCount = 0; m_BlockCount = 0;
} }
#endif #endif
template<typename a, size_t b> template<typename a, size_t b>
MEM_BlockAlloc<a, b>::~MEM_BlockAlloc() MEM_BlockAlloc<a, b>::~MEM_BlockAlloc()
{ {
FreeAll(); FreeAll();
} }
template<typename a, size_t b> template<typename a, size_t b>
void* MEM_BlockAlloc<a, b>::Alloc() void* MEM_BlockAlloc<a, b>::Alloc()
{ {
#if _DEBUG_MEMBLOCK #if _DEBUG_MEMBLOCK
block_t* block = new(MEM_Alloc(sizeof(block_t))) block_t(); block_t* block = new (MEM_Alloc(sizeof(block_t))) block_t();
m_Block.AddFirst(block); m_Block.AddFirst(block);
m_BlockCount++; m_BlockCount++;
return (void*)block->data; return (void*)block->data;
#else #else
block_t* used_block; block_t* used_block;
block_offset_t free_data; block_offset_t free_data;
block_offset_t next_data; block_offset_t next_data;
if (m_StartUsedBlock) if (m_StartUsedBlock) {
{ used_block = m_StartUsedBlock;
used_block = m_StartUsedBlock;
free_data = used_block->free_data; free_data = used_block->free_data;
next_data = used_block->next_data[free_data]; next_data = used_block->next_data[free_data];
if (next_data == free_data) if (next_data == free_data) {
{ // Move the block to the next block list as there is no space
// Move the block to the next block list as there is no space available // available
m_StartUsedBlock = used_block->next_block; m_StartUsedBlock = used_block->next_block;
LL_SafeRemoveRoot(m_StartUsedBlock, used_block, next_block, prev_block); LL_SafeRemoveRoot(m_StartUsedBlock, used_block, next_block,
LL_SafeAddFirst(m_StartFullBlock, used_block, next_block, prev_block); prev_block);
LL_SafeAddFirst(m_StartFullBlock, used_block, next_block,
prev_block);
used_block->has_free_data = false; used_block->has_free_data = false;
return TakeFree(used_block, free_data); return TakeFree(used_block, free_data);
} }
} } else {
else if (m_FreeBlock) {
{ // start from the free block
if (m_FreeBlock) used_block = m_FreeBlock;
{ m_FreeBlock = nullptr;
// start from the free block free_data = used_block->free_data;
used_block = m_FreeBlock; next_data = used_block->next_data[free_data];
m_FreeBlock = nullptr; } else {
free_data = used_block->free_data; m_BlockCount++;
next_data = used_block->next_data[free_data]; // allocate and construct a new block
} used_block = new (MEM_Alloc(sizeof(block_t))) block_t();
else
{
m_BlockCount++;
// allocate and construct a new block
used_block = new(MEM_Alloc(sizeof(block_t))) block_t();
free_data = 0; free_data = 0;
next_data = 1; next_data = 1;
} }
LL_SafeAddFirst(m_StartUsedBlock, used_block, next_block, prev_block); LL_SafeAddFirst(m_StartUsedBlock, used_block, next_block, prev_block);
} }
const block_offset_t prev_data = used_block->prev_data[free_data]; const block_offset_t prev_data = used_block->prev_data[free_data];
used_block->next_data[prev_data] = next_data; used_block->next_data[prev_data] = next_data;
used_block->prev_data[next_data] = prev_data; used_block->prev_data[next_data] = prev_data;
used_block->free_data = next_data; used_block->free_data = next_data;
used_block->has_free_data = true; used_block->has_free_data = true;
if (!used_block->usedDataAvailable()) if (!used_block->usedDataAvailable()) {
{ used_block->used_data = free_data;
used_block->used_data = free_data; used_block->has_used_data = true;
used_block->has_used_data = true; used_block->next_data[free_data] = free_data;
used_block->next_data[free_data] = free_data; used_block->prev_data[free_data] = free_data;
used_block->prev_data[free_data] = free_data; return used_block->data[free_data].data;
return used_block->data[free_data].data; }
}
return TakeFree(used_block, free_data); return TakeFree(used_block, free_data);
#endif #endif
} }
template< typename aclass, size_t blocksize> template<typename aclass, size_t blocksize>
void* MEM_BlockAlloc<aclass, blocksize>::TakeFree(block_t* block, uintptr_t free_data) void* MEM_BlockAlloc<aclass, blocksize>::TakeFree(block_t* block,
uintptr_t free_data)
{ {
const block_offset_t used_data = block->used_data; const block_offset_t used_data = block->used_data;
const block_offset_t prev_data = block->prev_data[used_data]; const block_offset_t prev_data = block->prev_data[used_data];
block->next_data[prev_data] = (block_offset_t)free_data; block->next_data[prev_data] = (block_offset_t)free_data;
block->prev_data[used_data] = (block_offset_t)free_data; block->prev_data[used_data] = (block_offset_t)free_data;
block->next_data[free_data] = used_data; block->next_data[free_data] = used_data;
block->prev_data[free_data] = prev_data; block->prev_data[free_data] = prev_data;
return block->data[free_data].data; return block->data[free_data].data;
} }
template<typename a, size_t b> template<typename a, size_t b>
void MEM_BlockAlloc<a, b>::Free(void* ptr) noexcept void MEM_BlockAlloc<a, b>::Free(void* ptr) noexcept
{ {
#if _DEBUG_MEMBLOCK #if _DEBUG_MEMBLOCK
block_s<a, b>* block = (block_s<a, b> *)ptr; block_s<a, b>* block = (block_s<a, b>*)ptr;
m_Block.Remove(block); m_Block.Remove(block);
m_BlockCount--; m_BlockCount--;
MEM::Free(block); MEM::Free(block);
#else #else
// get the header of the pointer // get the header of the pointer
typename block_t::info_t* header = reinterpret_cast<typename block_t::info_t*>(static_cast<unsigned char*>(ptr) - block_t::headersize); typename block_t::info_t* header =
const block_offset_t used_data = header->index; reinterpret_cast<typename block_t::info_t*>(
// get the block from the header static_cast<unsigned char*>(ptr) - block_t::headersize);
block_t* const block = (block_t*)((uint8_t*)header - used_data * block_t::datasize - block_t::dataoffset); const block_offset_t used_data = header->index;
const block_offset_t next_data = block->next_data[used_data]; // get the block from the header
if (next_data == used_data) block_t* const block =
{ (block_t*)((uint8_t*)header - used_data * block_t::datasize -
LL_SafeRemoveRoot(m_StartUsedBlock, block, next_block, prev_block); block_t::dataoffset);
const block_offset_t next_data = block->next_data[used_data];
if (next_data == used_data) {
LL_SafeRemoveRoot(m_StartUsedBlock, block, next_block, prev_block);
if (m_FreeBlock) if (m_FreeBlock) {
{ // deallocate the free block because of another deallocation
// deallocate the free block because of another deallocation --m_BlockCount;
--m_BlockCount; MEM_Free(m_FreeBlock);
MEM_Free(m_FreeBlock); m_FreeBlock = nullptr;
m_FreeBlock = nullptr; }
}
m_FreeBlock = block; m_FreeBlock = block;
block->has_used_data = false; block->has_used_data = false;
const block_offset_t free_data = block->free_data; const block_offset_t free_data = block->free_data;
const block_offset_t prev_data = block->prev_data[free_data]; const block_offset_t prev_data = block->prev_data[free_data];
block->next_data[prev_data] = used_data; block->next_data[prev_data] = used_data;
block->prev_data[free_data] = used_data; block->prev_data[free_data] = used_data;
block->next_data[used_data] = free_data; block->next_data[used_data] = free_data;
block->prev_data[used_data] = prev_data; block->prev_data[used_data] = prev_data;
} } else {
else const block_offset_t prev_data = block->prev_data[used_data];
{
const block_offset_t prev_data = block->prev_data[used_data];
block->next_data[prev_data] = next_data; block->next_data[prev_data] = next_data;
block->prev_data[next_data] = prev_data; block->prev_data[next_data] = prev_data;
block->used_data = next_data; block->used_data = next_data;
block->has_used_data = true; block->has_used_data = true;
if (block->freeDataAvailable()) if (block->freeDataAvailable()) {
{ const block_offset_t free_data = block->free_data;
const block_offset_t free_data = block->free_data; const block_offset_t prev_data = block->prev_data[free_data];
const block_offset_t prev_data = block->prev_data[free_data];
block->next_data[prev_data] = used_data; block->next_data[prev_data] = used_data;
block->prev_data[free_data] = used_data; block->prev_data[free_data] = used_data;
block->next_data[used_data] = free_data; block->next_data[used_data] = free_data;
block->prev_data[used_data] = prev_data; block->prev_data[used_data] = prev_data;
return; return;
} }
if (m_StartFullBlock == block) if (m_StartFullBlock == block) {
{ m_StartFullBlock = block->next_block;
m_StartFullBlock = block->next_block; }
}
LL_SafeRemoveRoot(m_StartFullBlock, block, next_block, prev_block); LL_SafeRemoveRoot(m_StartFullBlock, block, next_block, prev_block);
LL_SafeAddFirst(m_StartUsedBlock, block, next_block, prev_block); LL_SafeAddFirst(m_StartUsedBlock, block, next_block, prev_block);
block->free_data = used_data; block->free_data = used_data;
block->has_free_data = true; block->has_free_data = true;
block->prev_data[used_data] = used_data; block->prev_data[used_data] = used_data;
block->next_data[used_data] = used_data; block->next_data[used_data] = used_data;
} }
#endif #endif
} }
template<typename a, size_t b> template<typename a, size_t b>
void MEM_BlockAlloc<a, b>::FreeAll() noexcept void MEM_BlockAlloc<a, b>::FreeAll() noexcept
{ {
block_t* block; block_t* block;
#if _DEBUG_MEMBLOCK #if _DEBUG_MEMBLOCK
block_t* next = m_Block.Root(); block_t* next = m_Block.Root();
for (block = next; block; block = next) for (block = next; block; block = next) {
{ next = block->next_block;
next = block->next_block; m_BlockCount--;
m_BlockCount--; a* ptr = (a*)block->data;
a* ptr = (a*)block->data; ptr->~a();
ptr->~a(); MEM::Free(block);
MEM::Free(block); }
} m_Block.Reset();
m_Block.Reset();
#else #else
while((block = m_StartFullBlock) != nullptr) while ((block = m_StartFullBlock) != nullptr) {
{ if (block->usedDataAvailable()) {
if (block->usedDataAvailable()) a* ptr = (a*)block->data[block->used_data].data;
{ ptr->~a();
a* ptr = (a*)block->data[block->used_data].data; Free(ptr);
ptr->~a(); block = m_StartFullBlock;
Free(ptr); }
block = m_StartFullBlock; }
}
}
while ((block = m_StartUsedBlock) != nullptr) while ((block = m_StartUsedBlock) != nullptr) {
{ if (block->usedDataAvailable()) {
if (block->usedDataAvailable()) a* ptr = (a*)block->data[block->used_data].data;
{ ptr->~a();
a* ptr = (a*)block->data[block->used_data].data; Free(ptr);
ptr->~a(); }
Free(ptr); }
}
}
if (m_FreeBlock) if (m_FreeBlock) {
{ m_BlockCount--;
m_BlockCount--; MEM_Free(m_FreeBlock);
MEM_Free(m_FreeBlock); m_FreeBlock = nullptr;
m_FreeBlock = nullptr; }
}
#endif #endif
} }
template<typename a, size_t b> template<typename a, size_t b>
size_t MEM_BlockAlloc<a, b>::Count(const block_t* list) size_t MEM_BlockAlloc<a, b>::Count(const block_t* list)
{ {
int count = 0; int count = 0;
#if _DEBUG_MEMBLOCK #if _DEBUG_MEMBLOCK
for (const block_t* block = list; block; block = block->next_block) for (const block_t* block = list; block; block = block->next_block) {
{ count++;
count++; }
} return count;
return count;
#else #else
for (const block_t* block = list; block; block = block->next_block) for (const block_t* block = list; block; block = block->next_block) {
{ if (!block->usedDataAvailable()) {
if (!block->usedDataAvailable()) continue;
{ }
continue;
}
const block_offset_t used_data = block->used_data; const block_offset_t used_data = block->used_data;
block_offset_t current_used_data = used_data; block_offset_t current_used_data = used_data;
do do {
{ count++;
count++; current_used_data = block->next_data[current_used_data];
current_used_data = block->next_data[current_used_data]; } while (current_used_data != used_data);
} while (current_used_data != used_data); }
}
return count; return count;
#endif #endif
} }
@ -483,32 +470,31 @@ template<typename a, size_t b>
size_t MEM_BlockAlloc<a, b>::Count() size_t MEM_BlockAlloc<a, b>::Count()
{ {
#if _DEBUG_MEMBLOCK #if _DEBUG_MEMBLOCK
return Count(m_Block); return Count(m_Block);
#else #else
return Count(m_StartFullBlock) + Count(m_StartUsedBlock); return Count(m_StartFullBlock) + Count(m_StartUsedBlock);
#endif #endif
} }
template<typename a, size_t b> template<typename a, size_t b>
size_t MEM_BlockAlloc<a, b>::BlockCount() size_t MEM_BlockAlloc<a, b>::BlockCount()
{ {
return m_BlockCount; return m_BlockCount;
} }
template<typename a, size_t b> template<typename a, size_t b>
size_t MEM_BlockAlloc<a, b>::BlockMemory() size_t MEM_BlockAlloc<a, b>::BlockMemory()
{ {
return sizeof(block_s<a, b>); return sizeof(block_s<a, b>);
} }
template<typename a, size_t b> template<typename a, size_t b>
MEM_BlockAlloc_enum<a, b >::MEM_BlockAlloc_enum(MEM_BlockAlloc< a, b>& owner) MEM_BlockAlloc_enum<a, b>::MEM_BlockAlloc_enum(MEM_BlockAlloc<a, b>& owner)
{ {
m_Owner = &owner; m_Owner = &owner;
m_CurrentBlock = nullptr; m_CurrentBlock = nullptr;
#if !_DEBUG_MEMBLOCK #if !_DEBUG_MEMBLOCK
m_CurrentBlockType = MEM_BlockAlloc_enum::used; m_CurrentBlockType = MEM_BlockAlloc_enum::used;
#endif #endif
} }
@ -516,71 +502,64 @@ template<typename a, size_t b>
a* MEM_BlockAlloc_enum<a, b>::NextElement() a* MEM_BlockAlloc_enum<a, b>::NextElement()
{ {
#if _DEBUG_MEMBLOCK #if _DEBUG_MEMBLOCK
if (!m_CurrentBlock) if (!m_CurrentBlock) {
{ m_CurrentBlock = m_Owner->m_Block.Root();
m_CurrentBlock = m_Owner->m_Block.Root(); } else {
} m_CurrentBlock = m_CurrentBlock->next_block;
else }
{ return (a*)m_CurrentBlock;
m_CurrentBlock = m_CurrentBlock->next_block;
}
return (a*)m_CurrentBlock;
#else #else
// search for a valid block type // search for a valid block type
while (!m_CurrentBlock) while (!m_CurrentBlock) {
{ switch (m_CurrentBlockType) {
switch (m_CurrentBlockType) case blockType_e::used:
{ m_CurrentBlock = m_Owner->m_StartUsedBlock;
case blockType_e::used: break;
m_CurrentBlock = m_Owner->m_StartUsedBlock; case blockType_e::full:
break; m_CurrentBlock = m_Owner->m_StartFullBlock;
case blockType_e::full: break;
m_CurrentBlock = m_Owner->m_StartFullBlock; default:
break; return nullptr;
default: }
return nullptr;
}
reinterpret_cast<uint8_t&>(m_CurrentBlockType)++; reinterpret_cast<uint8_t&>(m_CurrentBlockType)++;
_label: _label:
for (; m_CurrentBlock; m_CurrentBlock = m_CurrentBlock->next_block) for (; m_CurrentBlock; m_CurrentBlock = m_CurrentBlock->next_block) {
{ if (m_CurrentBlock->usedDataAvailable()) {
if (m_CurrentBlock->usedDataAvailable()) m_CurrentData = m_CurrentBlock->used_data;
{ return reinterpret_cast<a*>(
m_CurrentData = m_CurrentBlock->used_data; m_CurrentBlock->data[m_CurrentData].data);
return reinterpret_cast<a*>(m_CurrentBlock->data[m_CurrentData].data); }
} }
} }
}
m_CurrentData = m_CurrentBlock->next_data[m_CurrentData]; m_CurrentData = m_CurrentBlock->next_data[m_CurrentData];
if (m_CurrentData == m_CurrentBlock->used_data) if (m_CurrentData == m_CurrentBlock->used_data) {
{ // found an object
// found an object m_CurrentBlock = m_CurrentBlock->next_block;
m_CurrentBlock = m_CurrentBlock->next_block; goto _label;
goto _label; }
}
return reinterpret_cast<a*>(m_CurrentBlock->data[m_CurrentData].data); return reinterpret_cast<a*>(m_CurrentBlock->data[m_CurrentData].data);
#endif #endif
} }
template<typename a, size_t b> template<typename a, size_t b>
a* MEM_BlockAlloc_enum<a, b>::CurrentElement() a* MEM_BlockAlloc_enum<a, b>::CurrentElement()
{ {
return m_CurrentBlock; return m_CurrentBlock;
} }
template<typename a, size_t b> template<typename a, size_t b>
void* operator new(size_t, MEM_BlockAlloc<a, b>& allocator) void* operator new(size_t, MEM_BlockAlloc<a, b>& allocator)
{ {
return allocator.Alloc(); return allocator.Alloc();
} }
template<typename a, size_t b> template<typename a, size_t b>
void operator delete(void* ptr, MEM_BlockAlloc<a, b>& allocator) noexcept void operator delete(void* ptr, MEM_BlockAlloc<a, b>& allocator) noexcept
{ {
return allocator.Free(ptr); return allocator.Free(ptr);
} }

View file

@ -28,94 +28,83 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h" #include "g_local.h"
#define MEM_TempAllocate(x) gi.Malloc(x) #define MEM_TempAllocate(x) gi.Malloc(x)
#define MEM_TempFree(x) gi.Free(x) #define MEM_TempFree(x) gi.Free(x)
#else #else
#include "qcommon.h" #include "qcommon.h"
#define MEM_TempAllocate(x) Z_Malloc(x) #define MEM_TempAllocate(x) Z_Malloc(x)
#define MEM_TempFree(x) Z_Free(x) #define MEM_TempFree(x) Z_Free(x)
#endif #endif
class tempBlock_t class tempBlock_t
{ {
public: public:
void* GetData(); void* GetData();
void* GetData(size_t pos); void* GetData(size_t pos);
public: public:
tempBlock_t* prev; tempBlock_t* prev;
}; };
MEM_TempAlloc::MEM_TempAlloc() MEM_TempAlloc::MEM_TempAlloc()
{ {
m_CurrentMemoryBlock = nullptr; m_CurrentMemoryBlock = nullptr;
m_CurrentMemoryPos = 0; m_CurrentMemoryPos = 0;
m_BlockSize = 0; m_BlockSize = 0;
m_LastPos = 0; m_LastPos = 0;
} }
void* MEM_TempAlloc::Alloc(size_t len) void* MEM_TempAlloc::Alloc(size_t len)
{ {
if (m_CurrentMemoryBlock && m_CurrentMemoryPos + len <= m_BlockSize) if (m_CurrentMemoryBlock && m_CurrentMemoryPos + len <= m_BlockSize) {
{ void* data = m_CurrentMemoryBlock->GetData(m_CurrentMemoryPos);
void* data = m_CurrentMemoryBlock->GetData(m_CurrentMemoryPos); m_LastPos = m_CurrentMemoryPos;
m_LastPos = m_CurrentMemoryPos; m_CurrentMemoryPos += len;
m_CurrentMemoryPos += len; return data;
return data; } else {
} return CreateBlock(len);
else }
{
return CreateBlock(len);
}
} }
void* MEM_TempAlloc::Alloc(size_t len, size_t alignment) void* MEM_TempAlloc::Alloc(size_t len, size_t alignment)
{ {
if (m_CurrentMemoryBlock) if (m_CurrentMemoryBlock) {
{ if (m_CurrentMemoryPos % alignment != 0) {
if (m_CurrentMemoryPos % alignment != 0) { m_CurrentMemoryPos += alignment - m_CurrentMemoryPos % alignment;
m_CurrentMemoryPos += alignment - m_CurrentMemoryPos % alignment; }
}
if (m_CurrentMemoryPos + len <= m_BlockSize) if (m_CurrentMemoryPos + len <= m_BlockSize) {
{ void* data = m_CurrentMemoryBlock->GetData(m_CurrentMemoryPos);
void* data = m_CurrentMemoryBlock->GetData(m_CurrentMemoryPos); m_LastPos = m_CurrentMemoryPos;
m_LastPos = m_CurrentMemoryPos; m_CurrentMemoryPos += len;
m_CurrentMemoryPos += len; return data;
return data; }
} }
}
return CreateBlock(len); return CreateBlock(len);
} }
void MEM_TempAlloc::FreeAll( void ) void MEM_TempAlloc::FreeAll(void)
{ {
while (m_CurrentMemoryBlock) while (m_CurrentMemoryBlock) {
{ tempBlock_t* prev_block = m_CurrentMemoryBlock->prev;
tempBlock_t* prev_block = m_CurrentMemoryBlock->prev; MEM_TempFree(m_CurrentMemoryBlock);
MEM_TempFree(m_CurrentMemoryBlock); m_CurrentMemoryBlock = prev_block;
m_CurrentMemoryBlock = prev_block; }
}
} }
void* MEM_TempAlloc::CreateBlock(size_t len) void* MEM_TempAlloc::CreateBlock(size_t len)
{ {
m_CurrentMemoryPos = len; m_CurrentMemoryPos = len;
// allocate a new block // allocate a new block
tempBlock_t* prev_block = m_CurrentMemoryBlock; tempBlock_t* prev_block = m_CurrentMemoryBlock;
m_CurrentMemoryBlock = (tempBlock_t*)MEM_TempAllocate(sizeof(tempBlock_t) + max(m_BlockSize, len)); m_CurrentMemoryBlock = (tempBlock_t*)MEM_TempAllocate(
m_CurrentMemoryBlock->prev = prev_block; sizeof(tempBlock_t) + max(m_BlockSize, len));
return m_CurrentMemoryBlock->GetData(); m_CurrentMemoryBlock->prev = prev_block;
return m_CurrentMemoryBlock->GetData();
} }
void* tempBlock_t::GetData() void* tempBlock_t::GetData() { return (void*)(this + 1); }
{
return (void*)(this + 1);
}
void* tempBlock_t::GetData(size_t pos) void* tempBlock_t::GetData(size_t pos) { return (uint8_t*)(this + 1) + pos; }
{
return (uint8_t*)(this + 1) + pos;
}

View file

@ -28,19 +28,20 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class tempBlock_t; class tempBlock_t;
class MEM_TempAlloc { class MEM_TempAlloc
{
public: public:
MEM_TempAlloc(); MEM_TempAlloc();
void* Alloc(size_t len); void* Alloc(size_t len);
void* Alloc(size_t len, size_t alignment); void* Alloc(size_t len, size_t alignment);
void FreeAll(void); void FreeAll(void);
// This was added to fix issues with alignment // This was added to fix issues with alignment
void* CreateBlock(size_t len); void* CreateBlock(size_t len);
private: private:
tempBlock_t* m_CurrentMemoryBlock; tempBlock_t* m_CurrentMemoryBlock;
size_t m_CurrentMemoryPos; size_t m_CurrentMemoryPos;
size_t m_BlockSize; size_t m_BlockSize;
size_t m_LastPos; size_t m_LastPos;
}; };

File diff suppressed because it is too large Load diff

View file

@ -33,156 +33,148 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "archive.h" #include "archive.h"
#endif #endif
#define TOKENCOMMENT (';') #define TOKENCOMMENT (';')
#define TOKENCOMMENT2 ('#') #define TOKENCOMMENT2 ('#')
#define TOKENEOL ('\n') #define TOKENEOL ('\n')
//#define TOKENNULL ('\0') // #define TOKENNULL ('\0')
#define TOKENSPACE (' ') #define TOKENSPACE (' ')
#define TOKENSPECIAL ('$') #define TOKENSPECIAL ('$')
#define MAXTOKEN 512 #define MAXTOKEN 512
typedef struct typedef struct {
{ qboolean tokenready;
qboolean tokenready; int offset;
int offset; int line;
int line; char token[MAXTOKEN];
char token[ MAXTOKEN ]; } scriptmarker_t;
} scriptmarker_t;
typedef struct typedef struct {
{ // const char *macroName;
//const char *macroName; // const char *macroText;
//const char *macroText; str macroName;
str macroName; str macroText;
str macroText; } macro;
} macro;
class Script : public Class class Script : public Class
{ {
protected: protected:
qboolean tokenready; qboolean tokenready;
str filename; str filename;
const char *script_p; const char* script_p;
const char *end_p; const char* end_p;
Container<macro *> macrolist; Container<macro*> macrolist;
int line; int line;
char token[ MAXTOKEN ]; char token[MAXTOKEN];
qboolean releaseBuffer; qboolean releaseBuffer;
qboolean hasError; qboolean hasError;
qboolean AtComment( void ); qboolean AtComment(void);
void CheckOverflow( void ); void CheckOverflow(void);
public: public:
const char *buffer; const char* buffer;
size_t length; size_t length;
CLASS_PROTOTYPE( Script ); CLASS_PROTOTYPE(Script);
#if defined(ARCHIVE_SUPPORTED) #if defined(ARCHIVE_SUPPORTED)
void Archive( Archiver &arc ) override; void Archive(Archiver& arc) override;
#endif #endif
~Script(); ~Script();
Script( const char* filename ); Script(const char* filename);
Script(); Script();
void Close( void ); void Close(void);
const char *Filename( void ); const char* Filename(void);
int GetLineNumber( void ); int GetLineNumber(void);
void Reset( void ); void Reset(void);
void MarkPosition( scriptmarker_t *mark ); void MarkPosition(scriptmarker_t* mark);
void RestorePosition( const scriptmarker_t *mark ); void RestorePosition(const scriptmarker_t* mark);
qboolean SkipToEOL( void ); qboolean SkipToEOL(void);
void SkipWhiteSpace( qboolean crossline ); void SkipWhiteSpace(qboolean crossline);
void SkipNonToken( qboolean crossline ); void SkipNonToken(qboolean crossline);
qboolean TokenAvailable( qboolean crossline ); qboolean TokenAvailable(qboolean crossline);
qboolean CommentAvailable( qboolean crossline ); qboolean CommentAvailable(qboolean crossline);
void UnGetToken( void ); void UnGetToken(void);
qboolean AtString( qboolean crossline ); qboolean AtString(qboolean crossline);
qboolean AtOpenParen( qboolean crossline ); qboolean AtOpenParen(qboolean crossline);
qboolean AtCloseParen( qboolean crossline ); qboolean AtCloseParen(qboolean crossline);
qboolean AtComma( qboolean crossline ); qboolean AtComma(qboolean crossline);
qboolean AtDot( qboolean crossline ); qboolean AtDot(qboolean crossline);
qboolean AtAssignment( qboolean crossline ); qboolean AtAssignment(qboolean crossline);
const char *GetToken( qboolean crossline ); const char* GetToken(qboolean crossline);
const char *GetLine( qboolean crossline ); const char* GetLine(qboolean crossline);
const char *GetRaw( void ); const char* GetRaw(void);
const char *GetString( qboolean crossline ); const char* GetString(qboolean crossline);
qboolean GetSpecific( const char *string ); qboolean GetSpecific(const char* string);
qboolean GetBoolean( qboolean crossline ); qboolean GetBoolean(qboolean crossline);
int GetInteger( qboolean crossline ); int GetInteger(qboolean crossline);
double GetDouble( qboolean crossline ); double GetDouble(qboolean crossline);
float GetFloat( qboolean crossline ); float GetFloat(qboolean crossline);
Vector GetVector( qboolean crossline ); Vector GetVector(qboolean crossline);
int LinesInFile( void ); int LinesInFile(void);
void Parse( const char *data, size_t length, const char *name ); void Parse(const char* data, size_t length, const char* name);
void LoadFile( const char *name ); void LoadFile(const char* name);
void LoadFile( const char *name, int length, const char *buf ); void LoadFile(const char* name, int length, const char* buf);
const char *Token( void ); const char* Token(void);
void AddMacroDefinition( qboolean crossline ); void AddMacroDefinition(qboolean crossline);
const char *GetMacroString( const char *theMacroName ); const char* GetMacroString(const char* theMacroName);
char *EvaluateMacroString( const char *theMacroString ); char* EvaluateMacroString(const char* theMacroString);
float EvaluateMacroMath(float value, float newval, char oper); float EvaluateMacroMath(float value, float newval, char oper);
const char *GetExprToken(const char *ptr, char *token); const char* GetExprToken(const char* ptr, char* token);
const char *GrabNextToken( qboolean crossline ); const char* GrabNextToken(qboolean crossline);
qboolean isMacro( void ); qboolean isMacro(void);
qboolean EndOfFile(); qboolean EndOfFile();
qboolean isValid( void ); qboolean isValid(void);
Container<macro *> *GetMacroList() { return &macrolist; } Container<macro*>* GetMacroList() { return &macrolist; }
void AddMacro(const char *name, const char *value); void AddMacro(const char* name, const char* value);
}; };
#if defined(ARCHIVE_SUPPORTED) #if defined(ARCHIVE_SUPPORTED)
inline void Script::Archive inline void Script::Archive(Archiver& arc)
( {
Archiver &arc int pos;
)
{
int pos;
arc.ArchiveBoolean( &tokenready ); arc.ArchiveBoolean(&tokenready);
arc.ArchiveString( &filename ); arc.ArchiveString(&filename);
if ( arc.Loading() ) if (arc.Loading()) {
{ //
// // load the file in
// load the file in //
// LoadFile(filename.c_str());
LoadFile( filename.c_str() ); }
}
if ( !arc.Loading() ) if (!arc.Loading()) {
{ //
// // save out current pointer as an offset
// save out current pointer as an offset //
// pos = script_p - buffer;
pos = script_p - buffer; }
} arc.ArchiveInteger(&pos);
arc.ArchiveInteger( &pos ); if (arc.Loading()) {
if ( arc.Loading() ) //
{ // restore the script pointer
// //
// restore the script pointer script_p = buffer + pos;
// }
script_p = buffer + pos;
}
//const char *end_p; // const char *end_p;
//Container<macro *> macrolist; // Container<macro *> macrolist;
arc.ArchiveInteger( &line ); arc.ArchiveInteger(&line);
arc.ArchiveRaw( &token, sizeof( token ) ); arc.ArchiveRaw(&token, sizeof(token));
//qboolean releaseBuffer; // qboolean releaseBuffer;
} }
#endif #endif
#endif #endif