- The game is now free of leaks up to the point just after the wads are loaded.
- Fixed: Although TypeInfos are now deleted at exit, their FlatPointers or ActorInfo data was not freed. I chose not to use a destructor to handle this, because then it would no longer be a POD type that can be statically initialized. - Fixed: Aliases were not deleted at exit. - Fixed: FWadCollection did not free its hash tables, lump info, full names, or the list of open files when destroyed. SVN r85 (trunk)
This commit is contained in:
parent
d4160f7211
commit
748d7bf4b1
9 changed files with 151 additions and 50 deletions
|
|
@ -64,8 +64,6 @@ static const char *KeyConfCommands[] =
|
|||
"setslot"
|
||||
};
|
||||
|
||||
|
||||
|
||||
static long ParseCommandLine (const char *args, int *argc, char **argv);
|
||||
|
||||
CVAR (Bool, lookspring, true, CVAR_ARCHIVE); // Generate centerview when -mlook encountered?
|
||||
|
|
@ -149,7 +147,32 @@ FActionMap ActionMaps[] =
|
|||
{ 0xf01cb105, &Button_LookUp, "lookup" },
|
||||
};
|
||||
|
||||
#define NUM_ACTIONS (sizeof(ActionMaps)/sizeof(FActionMap))
|
||||
#define NUM_ACTIONS countof(ActionMaps)
|
||||
|
||||
static struct AliasKiller
|
||||
{
|
||||
~AliasKiller()
|
||||
{
|
||||
// Scan the hash table for all aliases and delete them.
|
||||
// Regular commands will be destroyed automatically.
|
||||
for (size_t i = 0; i < countof(Commands); ++i)
|
||||
{
|
||||
FConsoleCommand *cmd = Commands[i];
|
||||
|
||||
while (cmd != NULL)
|
||||
{
|
||||
FConsoleCommand *next = cmd->m_Next;
|
||||
if (cmd->IsAlias())
|
||||
{
|
||||
delete cmd;
|
||||
}
|
||||
cmd = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
} KillTheAliases;
|
||||
|
||||
|
||||
|
||||
IMPLEMENT_CLASS (DWaitingCommand)
|
||||
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@
|
|||
#include "r_state.h"
|
||||
#include "stats.h"
|
||||
|
||||
TypeInfo::DeletingArray TypeInfo::m_RuntimeActors;
|
||||
TArray<TypeInfo *> TypeInfo::m_RuntimeActors;
|
||||
TArray<TypeInfo *> TypeInfo::m_Types (256);
|
||||
unsigned int TypeInfo::TypeHash[256]; // Why can't I use TypeInfo::HASH_SIZE?
|
||||
unsigned int TypeInfo::TypeHash[TypeInfo::HASH_SIZE]; // Why can't I use TypeInfo::HASH_SIZE?
|
||||
|
||||
#if defined(_MSC_VER) || defined(__GNUC__)
|
||||
#include "autosegs.h"
|
||||
|
|
@ -77,15 +77,60 @@ TypeInfo DObject::_StaticType(NULL, "DObject", NULL, sizeof(DObject));
|
|||
static cycle_t StaleCycles;
|
||||
static int StaleCount;
|
||||
|
||||
TypeInfo::DeletingArray::~DeletingArray()
|
||||
// A harmless non_NULL FlatPointer for classes without pointers.
|
||||
static const size_t TheEnd = ~0;
|
||||
|
||||
static struct TypeInfoDataFreeer
|
||||
{
|
||||
for (unsigned int i = 0; i < Size(); ++i)
|
||||
~TypeInfoDataFreeer()
|
||||
{
|
||||
if ((*this)[i] != NULL)
|
||||
TArray<size_t *> uniqueFPs(64);
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0; i < TypeInfo::m_Types.Size(); ++i)
|
||||
{
|
||||
delete (*this)[i];
|
||||
(*this)[i] = NULL;
|
||||
TypeInfo *type = TypeInfo::m_Types[i];
|
||||
if (type->FlatPointers != &TheEnd && type->FlatPointers != type->Pointers)
|
||||
{
|
||||
// FlatPointers are shared by many classes, so we must check for
|
||||
// duplicates and only delete those that are unique.
|
||||
for (j = 0; j < uniqueFPs.Size(); ++j)
|
||||
{
|
||||
if (type->FlatPointers == uniqueFPs[j])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == uniqueFPs.Size())
|
||||
{
|
||||
uniqueFPs.Push(const_cast<size_t *>(type->FlatPointers));
|
||||
}
|
||||
}
|
||||
// For runtime classes, this call will also delete the TypeInfo.
|
||||
TypeInfo::StaticFreeData (type);
|
||||
}
|
||||
for (i = 0; i < uniqueFPs.Size(); ++i)
|
||||
{
|
||||
delete[] uniqueFPs[i];
|
||||
}
|
||||
}
|
||||
} FreeTypeInfoData;
|
||||
|
||||
void TypeInfo::StaticFreeData (TypeInfo *type)
|
||||
{
|
||||
if (type->ActorInfo != NULL)
|
||||
{
|
||||
delete type->ActorInfo;
|
||||
type->ActorInfo = NULL;
|
||||
}
|
||||
if (type->bRuntimeClass)
|
||||
{
|
||||
if (type->Name != NULL)
|
||||
{
|
||||
delete[] type->Name;
|
||||
}
|
||||
type->Name = NULL;
|
||||
delete type;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,6 +244,7 @@ TypeInfo *TypeInfo::CreateDerivedClass (char *name, unsigned int size)
|
|||
type->RegisterType();
|
||||
type->Meta = Meta;
|
||||
type->FlatPointers = NULL;
|
||||
type->bRuntimeClass = true;
|
||||
|
||||
// If this class has an actor info, then any classes derived from it
|
||||
// also need an actor info.
|
||||
|
|
@ -233,8 +279,6 @@ TypeInfo *TypeInfo::CreateDerivedClass (char *name, unsigned int size)
|
|||
// to the same array as the super class's.
|
||||
void TypeInfo::BuildFlatPointers ()
|
||||
{
|
||||
static const size_t TheEnd = ~0;
|
||||
|
||||
if (FlatPointers != NULL)
|
||||
{ // Already built: Do nothing.
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ private:
|
|||
struct TypeInfo
|
||||
{
|
||||
static void StaticInit ();
|
||||
static void StaticFreeData (TypeInfo *type);
|
||||
|
||||
const char *Name;
|
||||
TypeInfo *ParentType;
|
||||
|
|
@ -142,6 +143,7 @@ struct TypeInfo
|
|||
FActorInfo *ActorInfo;
|
||||
unsigned int HashNext;
|
||||
unsigned short TypeIndex;
|
||||
bool bRuntimeClass; // class was defined at run-time, not compile-time
|
||||
FMetaTable Meta;
|
||||
const size_t *FlatPointers; // object pointers defined by this class and all its superclasses; not initialized by default
|
||||
|
||||
|
|
@ -169,16 +171,8 @@ struct TypeInfo
|
|||
static const TypeInfo *FindType (const char *name);
|
||||
static const TypeInfo *IFindType (const char *name);
|
||||
|
||||
// The DeletingArray deletes all the TypeInfos it points to
|
||||
// when it gets destroyed.
|
||||
class DeletingArray : public TArray<TypeInfo *>
|
||||
{
|
||||
public:
|
||||
~DeletingArray();
|
||||
};
|
||||
|
||||
static TArray<TypeInfo *> m_Types;
|
||||
static DeletingArray m_RuntimeActors;
|
||||
static TArray<TypeInfo *> m_RuntimeActors;
|
||||
|
||||
enum { HASH_SIZE = 256 };
|
||||
static unsigned int TypeHash[HASH_SIZE];
|
||||
|
|
|
|||
|
|
@ -166,6 +166,47 @@ FWadCollection::FWadCollection ()
|
|||
|
||||
FWadCollection::~FWadCollection ()
|
||||
{
|
||||
if (FirstLumpIndex != NULL)
|
||||
{
|
||||
delete[] FirstLumpIndex;
|
||||
FirstLumpIndex = NULL;
|
||||
}
|
||||
if (NextLumpIndex != NULL)
|
||||
{
|
||||
delete[] NextLumpIndex;
|
||||
NextLumpIndex = NULL;
|
||||
}
|
||||
if (FirstLumpIndex_FullName != NULL)
|
||||
{
|
||||
delete[] FirstLumpIndex_FullName;
|
||||
FirstLumpIndex_FullName = NULL;
|
||||
}
|
||||
if (NextLumpIndex_FullName != NULL)
|
||||
{
|
||||
delete[] NextLumpIndex_FullName;
|
||||
NextLumpIndex_FullName = NULL;
|
||||
}
|
||||
if (LumpInfo != NULL)
|
||||
{
|
||||
for (DWORD i = 0; i < NumLumps; ++i)
|
||||
{
|
||||
if (LumpInfo[i].fullname != NULL)
|
||||
{
|
||||
delete[] LumpInfo[i].fullname;
|
||||
}
|
||||
}
|
||||
delete[] LumpInfo;
|
||||
LumpInfo = NULL;
|
||||
}
|
||||
if (Wads != NULL)
|
||||
{
|
||||
for (DWORD i = 0; i < NumWads; ++i)
|
||||
{
|
||||
delete Wads[i];
|
||||
}
|
||||
delete[] Wads;
|
||||
Wads = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue