openmohaa/code/qcommon/class.h

320 lines
12 KiB
C
Raw Normal View History

2016-03-27 11:49:47 +02:00
/*
===========================================================================
2023-08-12 03:10:10 +02:00
Copyright (C) 2023 the OpenMoHAA team
2016-03-27 11:49:47 +02:00
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
===========================================================================
*/
// class.h: General class
2023-08-12 03:10:10 +02:00
#pragma once
2016-03-27 11:49:47 +02:00
2023-01-29 20:59:31 +01:00
#include "con_set.h"
2023-02-04 19:56:06 +01:00
#include "container.h"
#include "q_shared.h"
2023-01-29 20:59:31 +01:00
#include "str.h"
2023-07-30 14:26:52 +02:00
#include "lightclass.h"
2016-03-27 11:49:47 +02:00
2023-01-29 20:59:31 +01:00
#include "const_str.h"
2016-03-27 11:49:47 +02:00
class Class;
class Event;
2023-02-04 19:56:06 +01:00
#define isSubclassOf(classname) inheritsFrom(&classname::ClassInfo)
#define isSuperclassOf(classname) isInheritedBy(&classname::ClassInfo)
2016-03-27 11:49:47 +02:00
#ifdef WITH_SCRIPT_ENGINE
2016-03-27 11:49:47 +02:00
2023-08-12 03:10:10 +02:00
# define CLASS_DECLARATION(parentclass, classname, classid) \
ClassDef classname::ClassInfo( \
#classname, \
classid, \
#parentclass, \
(ResponseDef<Class> *)classname::Responses, \
classname::_newInstance, \
sizeof(classname) \
); \
void *classname::_newInstance(void) \
{ \
return new classname; \
} \
ClassDef *classname::classinfo(void) const \
{ \
return &(classname::ClassInfo); \
} \
ClassDef *classname::classinfostatic(void) \
{ \
return &(classname::ClassInfo); \
} \
void classname::AddWaitTill(str s) \
{ \
classname::ClassInfo.AddWaitTill(s); \
} \
void classname::AddWaitTill(const_str s) \
{ \
classname::ClassInfo.AddWaitTill(s); \
} \
void classname::RemoveWaitTill(str s) \
{ \
classname::ClassInfo.RemoveWaitTill(s); \
} \
void classname::RemoveWaitTill(const_str s) \
{ \
classname::ClassInfo.RemoveWaitTill(s); \
} \
bool classname::WaitTillDefined(str s) \
{ \
return classname::ClassInfo.WaitTillDefined(s); \
} \
bool classname::WaitTillDefined(const_str s) \
{ \
return classname::ClassInfo.WaitTillDefined(s); \
} \
bool classname::WaitTillAllowed(str s) \
{ \
for(ClassDef* c = classinfo(); c; c = c->super) { \
if (c->WaitTillDefined(s)) { return true; } \
} \
return false; \
} \
bool classname::WaitTillAllowed(const_str s) \
{ \
for(ClassDef* c = classinfo(); c; c = c->super) { \
if (c->WaitTillDefined(s)) { return true; } \
} \
return false; \
} \
2023-08-12 03:10:10 +02:00
ResponseDef<classname> classname::Responses[] =
# define CLASS_PROTOTYPE(classname) \
\
public: \
static ClassDef ClassInfo; \
static ClassDefHook _ClassInfo_; \
static void *_newInstance(void); \
static ClassDef *classinfostatic(void); \
ClassDef *classinfo(void) const override; \
static void AddWaitTill(str s); \
static void AddWaitTill(const_str s); \
static void RemoveWaitTill(str s); \
static void RemoveWaitTill(const_str s); \
static bool WaitTillDefined(str s); \
static bool WaitTillDefined(const_str s); \
bool WaitTillAllowed(str s); \
bool WaitTillAllowed(const_str s); \
2023-08-12 03:10:10 +02:00
static ResponseDef<classname> Responses[]
2016-03-27 11:49:47 +02:00
#else
2023-08-12 03:10:10 +02:00
# define CLASS_DECLARATION(parentclass, classname, classid) \
ClassDef classname::ClassInfo( \
#classname, \
classid, \
#parentclass, \
(ResponseDef<Class> *)classname::Responses, \
classname::_newInstance, \
sizeof(classname) \
); \
void *classname::_newInstance(void) \
{ \
return new classname; \
} \
ClassDef *classname::classinfo(void) const \
{ \
return &(classname::ClassInfo); \
} \
ClassDef *classname::classinfostatic(void) \
{ \
return &(classname::ClassInfo); \
} \
ResponseDef<classname> classname::Responses[] =
# define CLASS_PROTOTYPE(classname) \
\
public: \
static ClassDef ClassInfo; \
static ClassDefHook _ClassInfo_; \
static void *_newInstance(void); \
static ClassDef *classinfostatic(void); \
ClassDef *classinfo(void) const override; \
static ResponseDef<classname> Responses[]
2016-03-27 11:49:47 +02:00
#endif
2023-08-12 03:10:10 +02:00
typedef void (Class::*Response)(Event *ev);
2016-03-27 11:49:47 +02:00
class EventDef;
2023-02-04 19:56:06 +01:00
template<class Type>
2023-08-12 03:10:10 +02:00
struct ResponseDef {
Event *event;
void (Type::*response)(Event *ev);
EventDef *def;
2016-03-27 11:49:47 +02:00
};
class ClassDef
{
public:
2023-08-12 03:10:10 +02:00
const char *classname;
const char *classID;
const char *superclass;
void *(*newInstance)(void);
int classSize;
ResponseDef<Class> *responses;
ResponseDef<Class> **responseLookup;
ClassDef *super;
ClassDef *next;
ClassDef *prev;
2016-03-27 11:49:47 +02:00
#ifdef WITH_SCRIPT_ENGINE
2023-08-12 03:10:10 +02:00
con_set<const_str, const_str> *waitTillSet;
2016-03-27 11:49:47 +02:00
#endif
2023-02-04 19:56:06 +01:00
int numEvents;
2016-03-27 11:49:47 +02:00
2023-08-12 03:10:10 +02:00
static ClassDef *classlist;
static int numclasses;
2016-03-27 11:49:47 +02:00
2023-02-04 19:56:06 +01:00
static void BuildEventResponses();
2016-03-27 11:49:47 +02:00
2023-02-04 19:56:06 +01:00
void BuildResponseList();
2016-03-27 11:49:47 +02:00
2023-08-12 03:10:10 +02:00
static int dump_numclasses;
static int dump_numevents;
static Container<int> sortedList;
static Container<ClassDef *> sortedClassList;
2016-03-27 11:49:47 +02:00
2023-02-04 19:56:06 +01:00
ClassDef();
~ClassDef();
2016-03-27 11:49:47 +02:00
2023-08-12 03:10:10 +02:00
static int compareClasses(const void *arg1, const void *arg2);
static void SortClassList(Container<ClassDef *> *sortedList);
2016-03-27 11:49:47 +02:00
#ifdef WITH_SCRIPT_ENGINE
2023-02-04 19:56:06 +01:00
void AddWaitTill(str s);
void AddWaitTill(const_str s);
void RemoveWaitTill(str s);
void RemoveWaitTill(const_str s);
bool WaitTillDefined(str s);
bool WaitTillDefined(const_str s);
2016-03-27 11:49:47 +02:00
#endif
2023-02-04 19:56:06 +01:00
/* Create-a-class function */
2023-08-12 03:10:10 +02:00
ClassDef(
const char *classname,
const char *classID,
const char *superclass,
ResponseDef<Class> *responses,
void *(*newInstance)(void),
int classSize
);
void CreateInternal(
const char *classname,
const char *classID,
const char *superclass,
ResponseDef<Class> *responses,
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);
int GetFlags(Event *event);
2023-02-04 19:56:06 +01:00
void Destroy();
2016-03-27 11:49:47 +02:00
};
2023-08-12 03:10:10 +02:00
ClassDef *getClassList(void);
qboolean checkInheritance(const ClassDef *superclass, const ClassDef *subclass);
qboolean checkInheritance(ClassDef *superclass, const char *subclass);
qboolean checkInheritance(const char *superclass, const char *subclass);
void CLASS_Print(FILE *class_file, const char *fmt, ...);
void ClassEvents(const char *classname, qboolean print_to_disk);
void DumpClass(FILE *class_file, const char *className);
void DumpAllClasses(void);
2016-03-27 11:49:47 +02:00
class ClassDefHook
{
private:
2023-08-12 03:10:10 +02:00
ClassDef *classdef;
2016-03-27 11:49:47 +02:00
public:
2023-02-04 19:56:06 +01:00
// void * operator new( size_t );
// void operator delete( void * );
2016-03-27 11:49:47 +02:00
2023-02-04 19:56:06 +01:00
ClassDefHook();
~ClassDefHook();
2016-03-27 11:49:47 +02:00
2023-02-04 19:56:06 +01:00
/* Hook-a-class function */
2023-08-12 03:10:10 +02:00
ClassDefHook(ClassDef *classdef, ResponseDef<Class> *responses);
2016-03-27 11:49:47 +02:00
};
2023-08-12 03:10:10 +02:00
ClassDef *getClassForID(const char *name);
ClassDef *getClass(const char *name);
ClassDef *getClassList(void);
void listAllClasses(void);
void listInheritanceOrder(const char *classname);
2016-03-27 11:49:47 +02:00
class SafePtrBase;
class Archiver;
2023-07-30 14:26:52 +02:00
class Class : public LightClass
2016-03-27 11:49:47 +02:00
{
2023-08-12 03:10:10 +02:00
private:
friend class SafePtrBase;
SafePtrBase *SafePtrList;
2016-03-27 11:49:47 +02:00
public:
2023-08-12 03:10:10 +02:00
static ClassDef ClassInfo;
static ClassDefHook _ClassInfo_; // Openmohaa addition
static ResponseDef<Class> Responses[];
2016-03-27 11:49:47 +02:00
2023-08-12 03:10:10 +02:00
protected:
2023-02-04 19:56:06 +01:00
void ClearSafePointers();
2016-03-27 11:49:47 +02:00
public:
2023-02-04 19:56:06 +01:00
Class();
virtual ~Class();
2023-08-12 03:10:10 +02:00
virtual ClassDef *classinfo(void) const;
2016-03-27 11:49:47 +02:00
2023-08-12 03:10:10 +02:00
static void *_newInstance(void);
static ClassDef *classinfostatic(void);
2023-08-12 03:10:10 +02:00
void warning(const char *function, const char *format, ...) const;
void error(const char *function, const char *format, ...) const;
2016-03-27 11:49:47 +02:00
2023-08-12 03:10:10 +02:00
qboolean inheritsFrom(ClassDef *c) const;
qboolean inheritsFrom(const char *name) const;
qboolean isInheritedBy(const char *name) const;
qboolean isInheritedBy(ClassDef *c) const;
const char *getClassname(void) const;
const char *getClassID(void) const;
const char *getSuperclass(void) const;
2016-03-27 11:49:47 +02:00
2023-08-12 03:10:10 +02:00
virtual void Archive(Archiver& arc);
2016-03-27 11:49:47 +02:00
};
#include "safeptr.h"