mirror of
https://github.com/tribes2/engine.git
synced 2026-01-20 03:34:48 +00:00
192 lines
5.6 KiB
C++
192 lines
5.6 KiB
C++
//-----------------------------------------------------------------------------
|
|
// V12 Engine
|
|
//
|
|
// Copyright (c) 2001 GarageGames.Com
|
|
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "platform/platform.h"
|
|
#include "console/consoleObject.h"
|
|
#include "core/stringTable.h"
|
|
#include "console/console.h"
|
|
|
|
static AbstractClassRep::FieldList sg_tempFieldList;
|
|
AbstractClassRep *AbstractClassRep::classLinkList = NULL;
|
|
AbstractClassRep *AbstractClassRep::classTable[MaxClassId+1];
|
|
bool AbstractClassRep::initialized = false;
|
|
|
|
//--------------------------------------
|
|
|
|
const AbstractClassRep::Field *AbstractClassRep::findField(StringTableEntry name) const
|
|
{
|
|
for(U32 i = 0; i < mFieldList.size(); i++)
|
|
if(mFieldList[i].pFieldname == name)
|
|
return &mFieldList[i];
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------
|
|
void AbstractClassRep::registerClassRep(AbstractClassRep* in_pRep)
|
|
{
|
|
AssertFatal(in_pRep != NULL, "Hmph, that's odd...");
|
|
|
|
#ifdef DEBUG // assert if this class is already registered.
|
|
for(AbstractClassRep *walk = classLinkList; walk; walk = walk->nextClass)
|
|
{
|
|
AssertFatal(dStrcmp(in_pRep->mClassName, walk->mClassName),
|
|
"Duplicate Class name registered.");
|
|
}
|
|
#endif
|
|
in_pRep->nextClass = classLinkList;
|
|
classLinkList = in_pRep;
|
|
}
|
|
|
|
//--------------------------------------
|
|
|
|
ConsoleObject* AbstractClassRep::create(const char* in_pClassName)
|
|
{
|
|
AssertFatal(initialized, "creating an object before AbstractClassRep::initialize.");
|
|
|
|
for (AbstractClassRep *walk = classLinkList; walk; walk = walk->nextClass)
|
|
if (!dStrcmp(walk->getClassName(), in_pClassName))
|
|
return walk->create();
|
|
|
|
AssertWarn(0, avar("Couldn't find class rep for dynamic class: %s", in_pClassName));
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------
|
|
ConsoleObject* AbstractClassRep::create(const S32 in_classId)
|
|
{
|
|
AssertFatal(initialized, "creating an object before AbstractClassRep::initialize.");
|
|
AssertFatal(in_classId >= 0 && in_classId <= MaxClassId, "Class id out of range.");
|
|
AssertFatal(classTable[in_classId] != NULL, "No class with declared id type.");
|
|
|
|
if(classTable[in_classId])
|
|
return classTable[in_classId]->create();
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------
|
|
|
|
static S32 QSORT_CALLBACK ACRCompare(const void *aptr, const void *bptr)
|
|
{
|
|
const AbstractClassRep *a = *((const AbstractClassRep **) aptr);
|
|
const AbstractClassRep *b = *((const AbstractClassRep **) bptr);
|
|
|
|
if(a->mClassIdBase != b->mClassIdBase)
|
|
return a->mClassIdBase - b->mClassIdBase;
|
|
if(a->mClassVersion != b->mClassVersion)
|
|
return a->mClassVersion - b->mClassVersion;
|
|
return dStrcmp(a->getClassName(), b->getClassName());
|
|
}
|
|
|
|
void AbstractClassRep::initialize()
|
|
{
|
|
AssertFatal(!initialized, "Duplicate call to AbstractClassRep::initialize()");
|
|
U32 i;
|
|
for(i = 0; i <= MaxClassId; i++)
|
|
classTable[i] = NULL;
|
|
|
|
Vector<AbstractClassRep *> dynamicTable(__FILE__, __LINE__);
|
|
|
|
AbstractClassRep *walk;
|
|
|
|
for (walk = classLinkList; walk; walk = walk->nextClass)
|
|
walk->mNamespace = Con::lookupNamespace(StringTable->insert(walk->getClassName()));
|
|
|
|
for (walk = classLinkList; walk; walk = walk->nextClass)
|
|
{
|
|
sg_tempFieldList.setSize(0);
|
|
walk->init();
|
|
if (sg_tempFieldList.size() != 0)
|
|
walk->mFieldList = sg_tempFieldList;
|
|
|
|
if(walk->mClassIdBase != -1)
|
|
dynamicTable.push_back(walk);
|
|
}
|
|
dQsort((void *) &dynamicTable[0], dynamicTable.size(), sizeof(AbstractClassRep *), ACRCompare);
|
|
|
|
S32 prevClassBase = -1;
|
|
S32 curClassId = 0;
|
|
|
|
for(i = 0; i < dynamicTable.size(); i++)
|
|
{
|
|
AbstractClassRep *cur = dynamicTable[i];
|
|
if(cur->mClassIdBase != prevClassBase)
|
|
{
|
|
AssertFatal(cur->mClassIdBase >= curClassId, avar("Class range too small %d", prevClassBase));
|
|
prevClassBase = cur->mClassIdBase;
|
|
curClassId = cur->mClassIdBase;
|
|
}
|
|
cur->mClassId = curClassId++;
|
|
classTable[cur->mClassId] = cur;
|
|
}
|
|
initialized = true;
|
|
sg_tempFieldList.clear();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//-------------------------------------- ConsoleObject
|
|
void ConsoleObject::addField(const char* in_pFieldname,
|
|
const U32 in_fieldType,
|
|
const U32 in_fieldOffset,
|
|
const U32 in_elementCount,
|
|
EnumTable *in_table)
|
|
{
|
|
AbstractClassRep::Field f;
|
|
f.pFieldname = StringTable->insert(in_pFieldname);
|
|
f.type = in_fieldType;
|
|
f.offset = in_fieldOffset;
|
|
f.elementCount = in_elementCount;
|
|
f.table = in_table;
|
|
|
|
sg_tempFieldList.push_back(f);
|
|
}
|
|
|
|
void ConsoleObject::addDepricatedField(const char *fieldName)
|
|
{
|
|
AbstractClassRep::Field f;
|
|
f.pFieldname = StringTable->insert(fieldName);
|
|
f.type = AbstractClassRep::DepricatedFieldType;
|
|
|
|
sg_tempFieldList.push_back(f);
|
|
}
|
|
|
|
|
|
bool ConsoleObject::removeField(const char* in_pFieldname)
|
|
{
|
|
for (U32 i = 0; i < sg_tempFieldList.size(); i++) {
|
|
if (dStricmp(in_pFieldname, sg_tempFieldList[i].pFieldname) == 0) {
|
|
sg_tempFieldList.erase(i);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------
|
|
void ConsoleObject::initPersistFields()
|
|
{
|
|
}
|
|
|
|
//--------------------------------------
|
|
void ConsoleObject::consoleInit()
|
|
{
|
|
}
|
|
|
|
ConsoleObject::~ConsoleObject()
|
|
{
|
|
}
|
|
|
|
//--------------------------------------
|
|
AbstractClassRep* ConsoleObject::getClassRep() const
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
|