mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Fix memory leaks (#668)
This commit is contained in:
commit
ad1748b8be
11 changed files with 142 additions and 67 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
Copyright (C) 2025 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -26,9 +26,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "playerbot.h"
|
||||
#include "g_bot.h"
|
||||
|
||||
static saved_bot_t *saved_bots = NULL;
|
||||
static unsigned int num_saved_bots = 0;
|
||||
static unsigned int botId = 0;
|
||||
static saved_bot_t *saved_bots = NULL;
|
||||
static unsigned int num_saved_bots = 0;
|
||||
static unsigned int botId = 0;
|
||||
|
||||
Container<str> alliedModelList;
|
||||
Container<str> germanModelList;
|
||||
|
@ -387,7 +387,7 @@ bool G_IsPlayer(gentity_t *ent)
|
|||
G_GetRandomAlliedPlayerModel
|
||||
============
|
||||
*/
|
||||
const char* G_GetRandomAlliedPlayerModel()
|
||||
const char *G_GetRandomAlliedPlayerModel()
|
||||
{
|
||||
if (!alliedModelList.NumObjects()) {
|
||||
return "";
|
||||
|
@ -402,7 +402,7 @@ const char* G_GetRandomAlliedPlayerModel()
|
|||
G_GetRandomGermanPlayerModel
|
||||
============
|
||||
*/
|
||||
const char* G_GetRandomGermanPlayerModel()
|
||||
const char *G_GetRandomGermanPlayerModel()
|
||||
{
|
||||
if (!germanModelList.NumObjects()) {
|
||||
return "";
|
||||
|
@ -580,8 +580,8 @@ void G_SaveBots()
|
|||
saved_bots = NULL;
|
||||
}
|
||||
|
||||
const BotControllerManager& manager = botManager.getControllerManager();
|
||||
unsigned int numSpawnedBots = manager.getControllers().NumObjects();
|
||||
const BotControllerManager& manager = botManager.getControllerManager();
|
||||
unsigned int numSpawnedBots = manager.getControllers().NumObjects();
|
||||
|
||||
if (!numSpawnedBots) {
|
||||
return;
|
||||
|
@ -590,7 +590,6 @@ void G_SaveBots()
|
|||
saved_bots = new saved_bot_t[numSpawnedBots];
|
||||
num_saved_bots = 0;
|
||||
|
||||
|
||||
count = manager.getControllers().NumObjects();
|
||||
assert(count <= numSpawnedBots);
|
||||
|
||||
|
@ -686,6 +685,18 @@ int G_CountClients()
|
|||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
G_RestartBots
|
||||
|
||||
Save bots
|
||||
============
|
||||
*/
|
||||
void G_RestartBots()
|
||||
{
|
||||
G_SaveBots();
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
G_ResetBots
|
||||
|
@ -695,8 +706,6 @@ Save and reset the bot count
|
|||
*/
|
||||
void G_ResetBots()
|
||||
{
|
||||
G_SaveBots();
|
||||
|
||||
botManager.Cleanup();
|
||||
|
||||
botId = 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
Copyright (C) 2025 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -26,20 +26,21 @@ struct saved_bot_t {
|
|||
char userinfo[MAX_INFO_STRING];
|
||||
};
|
||||
|
||||
void G_BotBegin(gentity_t *ent);
|
||||
void G_BotThink(gentity_t *ent, int msec);
|
||||
void G_BotShift(int clientNum);
|
||||
gentity_t *G_GetFirstBot();
|
||||
void G_AddBot(const saved_bot_t *saved = NULL);
|
||||
void G_AddBots(unsigned int num);
|
||||
void G_RemoveBot(gentity_t *ent);
|
||||
void G_RemoveBots(unsigned int num);
|
||||
bool G_IsBot(gentity_t *ent);
|
||||
bool G_IsPlayer(gentity_t *ent);
|
||||
void G_ResetBots();
|
||||
void G_BotInit();
|
||||
void G_BotFrame();
|
||||
void G_BotPostInit();
|
||||
void G_SpawnBots();
|
||||
const char* G_GetRandomAlliedPlayerModel();
|
||||
const char* G_GetRandomGermanPlayerModel();
|
||||
void G_BotBegin(gentity_t *ent);
|
||||
void G_BotThink(gentity_t *ent, int msec);
|
||||
void G_BotShift(int clientNum);
|
||||
gentity_t *G_GetFirstBot();
|
||||
void G_AddBot(const saved_bot_t *saved = NULL);
|
||||
void G_AddBots(unsigned int num);
|
||||
void G_RemoveBot(gentity_t *ent);
|
||||
void G_RemoveBots(unsigned int num);
|
||||
bool G_IsBot(gentity_t *ent);
|
||||
bool G_IsPlayer(gentity_t *ent);
|
||||
void G_ResetBots();
|
||||
void G_RestartBots();
|
||||
void G_BotInit();
|
||||
void G_BotFrame();
|
||||
void G_BotPostInit();
|
||||
void G_SpawnBots();
|
||||
const char *G_GetRandomAlliedPlayerModel();
|
||||
const char *G_GetRandomGermanPlayerModel();
|
|
@ -227,9 +227,13 @@ void G_AllocGameData(void)
|
|||
|
||||
void G_DeAllocGameData(void)
|
||||
{
|
||||
// Initialize debug lines
|
||||
// Free up debug lines
|
||||
G_DeAllocDebugLines();
|
||||
|
||||
// Added in OPM
|
||||
// Free up debug strings
|
||||
G_DeAllocDebugStrings();
|
||||
|
||||
// free up the entities
|
||||
if (g_entities) {
|
||||
gi.Free(g_entities);
|
||||
|
@ -914,6 +918,9 @@ void G_Restart(void)
|
|||
|
||||
// Added in 2.0
|
||||
G_ResetSmokeSprites();
|
||||
|
||||
// Added in OPM
|
||||
G_RestartBots();
|
||||
}
|
||||
|
||||
void G_SetFrameNumber(int framenum)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
Copyright (C) 2025 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -686,10 +686,17 @@ void GameScript::ArchiveCodePos(Archiver& arc, unsigned char **codePos)
|
|||
|
||||
void GameScript::Close(void)
|
||||
{
|
||||
// Free up catch blocks
|
||||
for (int i = m_CatchBlocks.NumObjects(); i > 0; i--) {
|
||||
delete m_CatchBlocks.ObjectAt(i);
|
||||
}
|
||||
|
||||
// Added in OPM
|
||||
// Free up allocated state scripts
|
||||
for (int i = m_StateScripts.NumObjects(); i > 0; i--) {
|
||||
delete m_StateScripts.ObjectAt(i);
|
||||
}
|
||||
|
||||
m_CatchBlocks.FreeObjectList();
|
||||
|
||||
if (m_ProgToSource) {
|
||||
|
@ -814,7 +821,11 @@ StateScript *GameScript::CreateCatchStateScript(unsigned char *try_begin_code_po
|
|||
|
||||
StateScript *GameScript::CreateSwitchStateScript(void)
|
||||
{
|
||||
return new StateScript;
|
||||
StateScript *stateScript = new StateScript;
|
||||
|
||||
m_StateScripts.AddObject(stateScript);
|
||||
|
||||
return stateScript;
|
||||
}
|
||||
|
||||
StateScript *GameScript::GetCatchStateScript(unsigned char *in, unsigned char *& out)
|
||||
|
@ -927,7 +938,8 @@ void ScriptThreadLabel::Execute(Listener *listener, Event *ev) const
|
|||
Execute(listener, *ev);
|
||||
}
|
||||
|
||||
void ScriptThreadLabel::Execute(Listener *pSelf, const SafePtr<Listener>& listener, const SafePtr<Listener>& param) const
|
||||
void ScriptThreadLabel::Execute(Listener *pSelf, const SafePtr<Listener>& listener, const SafePtr<Listener>& param)
|
||||
const
|
||||
{
|
||||
if (!m_Script) {
|
||||
return;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
Copyright (C) 2025 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -118,7 +118,8 @@ class GameScript : public AbstractScript
|
|||
{
|
||||
protected:
|
||||
// try/throw variable
|
||||
Container<CatchBlock *> m_CatchBlocks;
|
||||
Container<CatchBlock *> m_CatchBlocks;
|
||||
Container<StateScript *> m_StateScripts;
|
||||
|
||||
public:
|
||||
// program variables
|
||||
|
|
|
@ -70,6 +70,11 @@ void Alias_ListClear(AliasList_t *list)
|
|||
}
|
||||
|
||||
for (node = list->data_list; node != NULL; node = next) {
|
||||
if (node->subtitle) {
|
||||
// Added in OPM
|
||||
Z_Free(node->subtitle);
|
||||
}
|
||||
|
||||
next = node->next;
|
||||
Z_Free(node);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2025 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -57,6 +57,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#endif
|
||||
|
||||
ClassDef *ClassDef::classlist;
|
||||
ClassDef *ClassDef::classroot;
|
||||
int ClassDef::numclasses;
|
||||
|
||||
int ClassDef::dump_numclasses;
|
||||
|
@ -78,7 +79,7 @@ void ClassDef::SortClassList(Container<ClassDef *> *sortedList)
|
|||
|
||||
sortedList->Resize(numclasses);
|
||||
|
||||
for (c = classlist->next; c != classlist; c = c->next) {
|
||||
for (c = classlist; c; c = c->next) {
|
||||
sortedList->AddObject(c);
|
||||
}
|
||||
|
||||
|
@ -92,7 +93,7 @@ ClassDef *getClassForID(const char *name)
|
|||
ClassDef *classlist = ClassDef::classlist;
|
||||
ClassDef *c;
|
||||
|
||||
for (c = classlist->next; c != classlist; c = c->next) {
|
||||
for (c = classlist; c; c = c->next) {
|
||||
if (c->classID && !Q_stricmp(c->classID, name)) {
|
||||
return c;
|
||||
}
|
||||
|
@ -110,7 +111,7 @@ ClassDef *getClass(const char *name)
|
|||
ClassDef *list = ClassDef::classlist;
|
||||
ClassDef *c;
|
||||
|
||||
for (c = list->next; c != list; c = c->next) {
|
||||
for (c = list; c; c = c->next) {
|
||||
if (Q_stricmp(c->classname, name) == 0) {
|
||||
return c;
|
||||
}
|
||||
|
@ -129,7 +130,7 @@ void listAllClasses(void)
|
|||
ClassDef *c;
|
||||
ClassDef *list = ClassDef::classlist;
|
||||
|
||||
for (c = list->next; c != list; c = c->next) {
|
||||
for (c = list; c; c = c->next) {
|
||||
CLASS_DPrintf("%s\n", c->classname);
|
||||
}
|
||||
}
|
||||
|
@ -353,7 +354,7 @@ ClassDef::ClassDef(
|
|||
ClassDef *node;
|
||||
|
||||
if (classlist == NULL) {
|
||||
classlist = new ClassDef;
|
||||
classlist = this;
|
||||
}
|
||||
|
||||
this->classname = classname;
|
||||
|
@ -374,7 +375,7 @@ ClassDef::ClassDef(
|
|||
this->classID = "";
|
||||
}
|
||||
|
||||
for (node = classlist->next; node != classlist; node = node->next) {
|
||||
for (node = classlist; node; node = node->next) {
|
||||
if ((node->super == NULL) && (!Q_stricmp(node->superclass, this->classname))
|
||||
&& (Q_stricmp(node->classname, "Class"))) {
|
||||
node->super = this;
|
||||
|
@ -382,7 +383,7 @@ ClassDef::ClassDef(
|
|||
}
|
||||
|
||||
// Add to front of list
|
||||
LL_AddFirst(classlist, this, prev, next);
|
||||
LL_SafeAdd(classroot, this, next, prev);
|
||||
|
||||
numclasses++;
|
||||
}
|
||||
|
@ -391,24 +392,24 @@ ClassDef::~ClassDef()
|
|||
{
|
||||
ClassDef *node;
|
||||
|
||||
if (classlist != this) {
|
||||
LL_Remove(this, prev, next);
|
||||
LL_SafeRemoveRoot(classlist, this, next, prev);
|
||||
|
||||
// Check if any subclasses were initialized before their superclass
|
||||
for (node = classlist->next; node != classlist; node = node->next) {
|
||||
if (node->super == this) {
|
||||
node->super = NULL;
|
||||
}
|
||||
// Check if any subclasses were initialized before their superclass
|
||||
for (node = classlist; node; node = node->next) {
|
||||
if (node->super == this) {
|
||||
node->super = NULL;
|
||||
}
|
||||
} else {
|
||||
// If the head of the list is deleted before the list is cleared, then we may have problems
|
||||
assert(this->next == this->prev);
|
||||
}
|
||||
|
||||
if (responseLookup) {
|
||||
delete[] responseLookup;
|
||||
responseLookup = NULL;
|
||||
}
|
||||
#ifdef WITH_SCRIPT_ENGINE
|
||||
if (waitTillSet) {
|
||||
delete waitTillSet;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WITH_SCRIPT_ENGINE
|
||||
|
@ -497,7 +498,7 @@ void ClassDef::BuildResponseList(void)
|
|||
}
|
||||
//size will be total event count, because it WAS faster to look for an event via eventnum
|
||||
//nowadays there's not much overhead in performance, TODO: change size to appropriate.
|
||||
num = Event::NumEventCommands();
|
||||
num = Event::NumEventCommands();
|
||||
responseLookup = (ResponseDef<Class> **)new char[sizeof(ResponseDef<Class> *) * num];
|
||||
memset(responseLookup, 0, sizeof(ResponseDef<Class> *) * num);
|
||||
|
||||
|
@ -539,7 +540,7 @@ void ClassDef::BuildEventResponses(void)
|
|||
amount = 0;
|
||||
numclasses = 0;
|
||||
|
||||
for (c = classlist->next; c != classlist; c = c->next) {
|
||||
for (c = classlist; c; c = c->next) {
|
||||
c->BuildResponseList();
|
||||
|
||||
amount += c->numEvents * sizeof(Response *);
|
||||
|
@ -692,7 +693,13 @@ void DumpClass(FILE *class_file, const char *className)
|
|||
|
||||
CLASS_Print(class_file, "\n");
|
||||
if (classDef->classID[0]) {
|
||||
CLASS_Print(class_file, "<h2> <a name=\"%s\">%s (<i>%s</i>)</a>", classDef->classname, classDef->classname, classDef->classID);
|
||||
CLASS_Print(
|
||||
class_file,
|
||||
"<h2> <a name=\"%s\">%s (<i>%s</i>)</a>",
|
||||
classDef->classname,
|
||||
classDef->classname,
|
||||
classDef->classID
|
||||
);
|
||||
} else {
|
||||
CLASS_Print(class_file, "<h2> <a name=\"%s\">%s</a>", classDef->classname, classDef->classname);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2025 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -87,15 +87,19 @@ class Event;
|
|||
} \
|
||||
bool classname::WaitTillAllowed(str s) \
|
||||
{ \
|
||||
for(ClassDef* c = classinfo(); c; c = c->super) { \
|
||||
if (c->WaitTillDefined(s)) { return true; } \
|
||||
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; } \
|
||||
for (ClassDef *c = classinfo(); c; c = c->super) { \
|
||||
if (c->WaitTillDefined(s)) { \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
return false; \
|
||||
} \
|
||||
|
@ -188,6 +192,7 @@ public:
|
|||
int numEvents;
|
||||
|
||||
static ClassDef *classlist;
|
||||
static ClassDef *classroot;
|
||||
static int numclasses;
|
||||
|
||||
static int dump_numclasses;
|
||||
|
|
|
@ -526,3 +526,18 @@ void Container<Type>::Copy(const Container<Type>& container)
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void *operator new(size_t count, Container<T>& container)
|
||||
{
|
||||
(void)count;
|
||||
|
||||
assert(count == sizeof(T));
|
||||
return &container.ObjectAt(container.AddObject());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void operator delete(void *ptr, Container<T>& container)
|
||||
{
|
||||
container.RemoveObject((T *)ptr);
|
||||
}
|
||||
|
|
|
@ -26,14 +26,27 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "q_shared.h"
|
||||
|
||||
class LightClass {
|
||||
class LightClass
|
||||
{
|
||||
public:
|
||||
#ifndef _DEBUG_MEM
|
||||
void* operator new(size_t);
|
||||
void operator delete(void*);
|
||||
void *operator new(size_t);
|
||||
void operator delete(void *);
|
||||
|
||||
void* operator new(size_t size, void* placement);
|
||||
void operator delete(void* ptr, void* placement);
|
||||
void *operator new(size_t size, void *placement);
|
||||
void operator delete(void *ptr, void *placement);
|
||||
|
||||
template<typename T>
|
||||
void *operator new(size_t size, T& placement)
|
||||
{
|
||||
return operator new(size, (void *)&placement);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void operator delete(void *ptr, T& placement)
|
||||
{
|
||||
return operator delete(ptr, (void *)&placement);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -408,7 +408,7 @@ public:
|
|||
#define NODE_CANCEL 1
|
||||
#define NODE_FIXED_EVENT 2
|
||||
|
||||
class EventQueueNode
|
||||
class EventQueueNode : public LightClass
|
||||
{
|
||||
public:
|
||||
Event *event;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue