123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
- // Copyright (C) 2015 Faust Logic, Inc.
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- #include "platform/platform.h"
- #include "console/consoleObject.h"
- #include "core/stringTable.h"
- #include "core/crc.h"
- #include "core/dataChunker.h"
- #include "console/console.h"
- #include "console/consoleInternal.h"
- #include "console/typeValidators.h"
- #include "console/simObject.h"
- #include "console/engineTypes.h"
- #include "console/engineAPI.h"
- #include "sim/netObject.h"
- IMPLEMENT_SCOPE( ConsoleAPI, Console,,
- "Functionality related to the legacy TorqueScript console system." );
- IMPLEMENT_NONINSTANTIABLE_CLASS( ConsoleObject,
- "Legacy console system root class. Will disappear." )
- END_IMPLEMENT_CLASS;
- AbstractClassRep * AbstractClassRep::classLinkList = NULL;
- AbstractClassRep::FieldList sg_tempFieldList( __FILE__, __LINE__ );
- U32 AbstractClassRep::NetClassCount [NetClassGroupsCount][NetClassTypesCount] = {{0, },};
- U32 AbstractClassRep::NetClassBitSize[NetClassGroupsCount][NetClassTypesCount] = {{0, },};
- AbstractClassRep ** AbstractClassRep::classTable[NetClassGroupsCount][NetClassTypesCount];
- U32 AbstractClassRep::classCRC[NetClassGroupsCount] = {CRC::INITIAL_CRC_VALUE, };
- bool AbstractClassRep::initialized = false;
- //-----------------------------------------------------------------------------
- AbstractClassRep* AbstractClassRep::findFieldRoot(StringTableEntry fieldName)
- {
- // Find the field.
- const Field* pField = findField(fieldName);
- // Finish if not found.
- if (pField == NULL)
- return NULL;
- // We're the root if we have no parent.
- if (getParentClass() == NULL)
- return this;
- // Find the field root via the parent.
- AbstractClassRep* pFieldRoot = getParentClass()->findFieldRoot(fieldName);
- // We're the root if the parent does not have it else return the field root.
- return pFieldRoot == NULL ? this : pFieldRoot;
- }
- void AbstractClassRep::init()
- {
- // Only add the renderable and selectable globals for
- // classes derived from SceneObject which are the only
- // objects for which these work.
- if ( isSubclassOf( "SceneObject" ) )
- {
- Con::addVariable( avar( "$%s::isRenderable", getClassName() ), TypeBool, &mIsRenderEnabled,
- "@brief Disables rendering of all instances of this type.\n\n" );
- Con::addVariable( avar( "$%s::isSelectable", getClassName() ), TypeBool, &mIsSelectionEnabled,
- "@brief Disables selection of all instances of this type.\n\n" );
- }
- }
- 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;
- }
- AbstractClassRep* AbstractClassRep::findClassRep(const char* in_pClassName)
- {
- AssertFatal(initialized,
- "AbstractClassRep::findClassRep() - Tried to find an AbstractClassRep before AbstractClassRep::initialize().");
- for (AbstractClassRep *walk = classLinkList; walk; walk = walk->nextClass)
- if (!dStricmp(walk->getClassName(), in_pClassName))
- return walk;
- return NULL;
- }
- AbstractClassRep* AbstractClassRep::findClassRep( U32 groupId, U32 typeId, U32 classId )
- {
- AssertFatal(initialized,
- "AbstractClassRep::findClasRep() - Tried to create an object before AbstractClassRep::initialize().");
- AssertFatal(classId < NetClassCount[groupId][typeId],
- "AbstractClassRep::findClassRep() - Class id out of range.");
- AssertFatal(classTable[groupId][typeId][classId] != NULL,
- "AbstractClassRep::findClassRep() - No class with requested ID type.");
- // Look up the specified class and create it.
- if(classTable[groupId][typeId][classId])
- return classTable[groupId][typeId][classId];
-
- return NULL;
- }
- //--------------------------------------
- void AbstractClassRep::registerClassRep(AbstractClassRep* in_pRep)
- {
- AssertFatal(in_pRep != NULL, "AbstractClassRep::registerClassRep was passed a NULL pointer!");
- #ifdef TORQUE_DEBUG // assert if this class is already registered.
- for(AbstractClassRep *walk = classLinkList; walk; walk = walk->nextClass)
- {
- AssertFatal(String::compare(in_pRep->mClassName, walk->mClassName),
- "Duplicate class name registered in AbstractClassRep::registerClassRep()");
- }
- #endif
- in_pRep->nextClass = classLinkList;
- classLinkList = in_pRep;
- }
- //--------------------------------------
- void AbstractClassRep::removeClassRep(AbstractClassRep* in_pRep)
- {
- for( AbstractClassRep *walk = classLinkList; walk; walk = walk->nextClass )
- {
- // This is the case that will most likely get hit.
- if( walk->nextClass == in_pRep )
- walk->nextClass = walk->nextClass->nextClass;
- else if( walk == in_pRep )
- {
- AssertFatal( in_pRep == classLinkList, "Pat failed in his logic for un linking RuntimeClassReps from the class linked list" );
- classLinkList = in_pRep->nextClass;
- }
- }
- }
- //--------------------------------------
- ConsoleObject* AbstractClassRep::create(const char* in_pClassName)
- {
- AssertFatal(initialized,
- "AbstractClassRep::create() - Tried to create an object before AbstractClassRep::initialize().");
- const AbstractClassRep *rep = AbstractClassRep::findClassRep(in_pClassName);
- if(rep)
- return rep->create();
- AssertWarn(0, avar("Couldn't find class rep for dynamic class: %s", in_pClassName));
- return NULL;
- }
- //--------------------------------------
- ConsoleObject* AbstractClassRep::create(const U32 groupId, const U32 typeId, const U32 in_classId)
- {
- AbstractClassRep* classRep = findClassRep( groupId, typeId, in_classId );
- if( !classRep )
- return NULL;
- return classRep->create();
- }
- //--------------------------------------
- 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->mClassType != b->mClassType)
- return a->mClassType - b->mClassType;
- return dStrnatcasecmp(a->getClassName(), b->getClassName());
- }
- void AbstractClassRep::initialize()
- {
- AssertFatal(!initialized, "Duplicate call to AbstractClassRep::initialize()!");
- Vector<AbstractClassRep *> dynamicTable(__FILE__, __LINE__);
- AbstractClassRep *walk;
- // Initialize namespace references...
- for (walk = classLinkList; walk; walk = walk->nextClass)
- {
- walk->mNamespace = Con::lookupNamespace(StringTable->insert(walk->getClassName()));
- walk->mNamespace->mUsage = walk->getDocString();
- walk->mNamespace->mClassRep = walk;
- }
- // Initialize field lists... (and perform other console registration).
- for (walk = classLinkList; walk; walk = walk->nextClass)
- {
- // sg_tempFieldList is used as a staging area for field lists
- // (see addField, addGroup, etc.)
- sg_tempFieldList.setSize(0);
- walk->init();
- // So if we have things in it, copy it over...
- if (sg_tempFieldList.size() != 0)
- walk->mFieldList = sg_tempFieldList;
- // And of course delete it every round.
- sg_tempFieldList.clear();
- }
- // Calculate counts and bit sizes for the various NetClasses.
- for (U32 group = 0; group < NetClassGroupsCount; group++)
- {
- U32 groupMask = 1 << group;
- // Specifically, for each NetClass of each NetGroup...
- for(U32 type = 0; type < NetClassTypesCount; type++)
- {
- // Go through all the classes and find matches...
- for (walk = classLinkList; walk; walk = walk->nextClass)
- {
- if(walk->mClassType == type && walk->mClassGroupMask & groupMask)
- dynamicTable.push_back(walk);
- }
- // Set the count for this NetGroup and NetClass
- NetClassCount[group][type] = dynamicTable.size();
- if(!NetClassCount[group][type])
- continue; // If no classes matched, skip to next.
- // Sort by type and then by name.
- dQsort((void *) &dynamicTable[0], dynamicTable.size(), sizeof(AbstractClassRep *), ACRCompare);
- // Allocate storage in the classTable
- classTable[group][type] = new AbstractClassRep*[NetClassCount[group][type]];
- // Fill this in and assign class ids for this group.
- for(U32 i = 0; i < NetClassCount[group][type];i++)
- {
- classTable[group][type][i] = dynamicTable[i];
- dynamicTable[i]->mClassId[group] = i;
- }
- // And calculate the size of bitfields for this group and type.
- NetClassBitSize[group][type] =
- getBinLog2(getNextPow2(NetClassCount[group][type] + 1));
- AssertFatal(NetClassCount[group][type] < (1 << NetClassBitSize[group][type]), "NetClassBitSize too small!");
- dynamicTable.clear();
- }
- }
- // Ok, we're golden!
- initialized = true;
- }
- void AbstractClassRep::shutdown()
- {
- AssertFatal( initialized, "AbstractClassRep::shutdown - not initialized" );
- // Release storage allocated to the class table.
- for (U32 group = 0; group < NetClassGroupsCount; group++)
- for(U32 type = 0; type < NetClassTypesCount; type++)
- if( classTable[ group ][ type ] )
- SAFE_DELETE_ARRAY( classTable[ group ][ type ] );
- initialized = false;
- }
- AbstractClassRep *AbstractClassRep::getCommonParent( const AbstractClassRep *otherClass ) const
- {
- // CodeReview: This may be a noob way of doing it. There may be some kind of
- // super-spiffy algorithm to do what the code below does, but this appeared
- // to make sense to me, and it is pretty easy to see what it is doing [6/23/2007 Pat]
- static VectorPtr<AbstractClassRep *> thisClassHeirarchy;
- thisClassHeirarchy.clear();
- AbstractClassRep *walk = const_cast<AbstractClassRep *>( this );
- while( walk != NULL )
- {
- thisClassHeirarchy.push_front( walk );
- walk = walk->getParentClass();
- }
- static VectorPtr<AbstractClassRep *> compClassHeirarchy;
- compClassHeirarchy.clear();
- walk = const_cast<AbstractClassRep *>( otherClass );
- while( walk != NULL )
- {
- compClassHeirarchy.push_front( walk );
- walk = walk->getParentClass();
- }
- // Make sure we only iterate over the list the number of times we can
- S32 maxIterations = getMin( compClassHeirarchy.size(), thisClassHeirarchy.size() );
- U32 i = 0;
- for( ; i < maxIterations; i++ )
- {
- if( compClassHeirarchy[i] != thisClassHeirarchy[i] )
- break;
- }
- return compClassHeirarchy[i];
- }
- //------------------------------------------------------------------------------
- //-------------------------------------- ConsoleObject
- static char replacebuf[1024];
- static char* suppressSpaces(const char* in_pname)
- {
- U32 i = 0;
- char chr;
- do
- {
- chr = in_pname[i];
- replacebuf[i++] = (chr != 32) ? chr : '_';
- } while(chr);
- return replacebuf;
- }
- void ConsoleObject::addGroup(const char* in_pGroupname, const char* in_pGroupDocs)
- {
- // Remove spaces.
- char* pFieldNameBuf = suppressSpaces(in_pGroupname);
- // Append group type to fieldname.
- dStrcat(pFieldNameBuf, "_begingroup", 1024);
- // Create Field.
- AbstractClassRep::Field f;
- f.pFieldname = StringTable->insert(pFieldNameBuf);
- f.pGroupname = in_pGroupname;
- if(in_pGroupDocs)
- f.pFieldDocs = in_pGroupDocs;
- f.type = AbstractClassRep::StartGroupFieldType;
- f.elementCount = 0;
- f.groupExpand = false;
- f.validator = NULL;
- f.setDataFn = &defaultProtectedSetFn;
- f.getDataFn = &defaultProtectedGetFn;
- f.writeDataFn = &defaultProtectedWriteFn;
- f.networkMask = 0;
- // Add to field list.
- sg_tempFieldList.push_back(f);
- }
- void ConsoleObject::endGroup(const char* in_pGroupname)
- {
- // Remove spaces.
- char* pFieldNameBuf = suppressSpaces(in_pGroupname);
- // Append group type to fieldname.
- dStrcat(pFieldNameBuf, "_endgroup", 1024);
- // Create Field.
- AbstractClassRep::Field f;
- f.pFieldname = StringTable->insert(pFieldNameBuf);
- f.pGroupname = in_pGroupname;
- f.type = AbstractClassRep::EndGroupFieldType;
- f.groupExpand = false;
- f.validator = NULL;
- f.setDataFn = &defaultProtectedSetFn;
- f.getDataFn = &defaultProtectedGetFn;
- f.writeDataFn = &defaultProtectedWriteFn;
- f.elementCount = 0;
- f.networkMask = 0;
- // Add to field list.
- sg_tempFieldList.push_back(f);
- }
- void ConsoleObject::addArray( const char *arrayName, S32 count )
- {
- char *nameBuff = suppressSpaces(arrayName);
- dStrcat(nameBuff, "_beginarray", 1024);
- // Create Field.
- AbstractClassRep::Field f;
- f.pFieldname = StringTable->insert(nameBuff);
- f.pGroupname = arrayName;
- f.type = AbstractClassRep::StartArrayFieldType;
- f.elementCount = count;
- f.groupExpand = false;
- f.validator = NULL;
- f.setDataFn = &defaultProtectedSetFn;
- f.getDataFn = &defaultProtectedGetFn;
- f.writeDataFn = &defaultProtectedWriteFn;
- f.networkMask = 0;
- // Add to field list.
- sg_tempFieldList.push_back(f);
- }
- void ConsoleObject::endArray( const char *arrayName )
- {
- char *nameBuff = suppressSpaces(arrayName);
- dStrcat(nameBuff, "_endarray", 1024);
- // Create Field.
- AbstractClassRep::Field f;
- f.pFieldname = StringTable->insert(nameBuff);
- f.pGroupname = arrayName;
- f.type = AbstractClassRep::EndArrayFieldType;
- f.groupExpand = false;
- f.validator = NULL;
- f.setDataFn = &defaultProtectedSetFn;
- f.getDataFn = &defaultProtectedGetFn;
- f.writeDataFn = &defaultProtectedWriteFn;
- f.elementCount = 0;
- f.networkMask = 0;
- // Add to field list.
- sg_tempFieldList.push_back(f);
- }
- void ConsoleObject::addField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- const char* in_pFieldDocs,
- U32 flags )
- {
- addField(
- in_pFieldname,
- in_fieldType,
- in_fieldOffset,
- 1,
- in_pFieldDocs,
- flags );
- }
- void ConsoleObject::addField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::WriteDataNotify in_writeDataFn,
- const char* in_pFieldDocs,
- U32 flags)
- {
- addField(
- in_pFieldname,
- in_fieldType,
- in_fieldOffset,
- in_writeDataFn,
- 1,
- in_pFieldDocs,
- flags);
- }
- void ConsoleObject::addField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- const U32 in_elementCount,
- const char* in_pFieldDocs,
- U32 flags)
- {
- addField(in_pFieldname,
- in_fieldType,
- in_fieldOffset,
- &defaultProtectedWriteFn,
- in_elementCount,
- in_pFieldDocs,
- flags);
- }
- void ConsoleObject::addField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::WriteDataNotify in_writeDataFn,
- const U32 in_elementCount,
- const char* in_pFieldDocs,
- U32 flags)
- {
- AbstractClassRep::Field f;
- f.pFieldname = StringTable->insert(in_pFieldname);
- if (in_pFieldDocs)
- f.pFieldDocs = in_pFieldDocs;
- f.type = in_fieldType;
- f.offset = in_fieldOffset;
- f.elementCount = in_elementCount;
- f.validator = NULL;
- f.flag = flags;
- f.setDataFn = &defaultProtectedSetFn;
- f.getDataFn = &defaultProtectedGetFn;
- f.writeDataFn = in_writeDataFn;
- f.networkMask = 0;
- ConsoleBaseType* conType = ConsoleBaseType::getType(in_fieldType);
- AssertFatal(conType, "ConsoleObject::addField - invalid console type");
- f.table = conType->getEnumTable();
- sg_tempFieldList.push_back(f);
- }
- void ConsoleObject::addProtectedField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::SetDataNotify in_setDataFn,
- AbstractClassRep::GetDataNotify in_getDataFn,
- const char* in_pFieldDocs,
- U32 flags)
- {
- addProtectedField(
- in_pFieldname,
- in_fieldType,
- in_fieldOffset,
- in_setDataFn,
- in_getDataFn,
- &defaultProtectedWriteFn,
- 1,
- in_pFieldDocs,
- flags);
- }
- void ConsoleObject::addProtectedField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::SetDataNotify in_setDataFn,
- AbstractClassRep::GetDataNotify in_getDataFn,
- AbstractClassRep::WriteDataNotify in_writeDataFn,
- const char* in_pFieldDocs,
- U32 flags)
- {
- addProtectedField(
- in_pFieldname,
- in_fieldType,
- in_fieldOffset,
- in_setDataFn,
- in_getDataFn,
- in_writeDataFn,
- 1,
- in_pFieldDocs,
- flags);
- }
- void ConsoleObject::addProtectedField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::SetDataNotify in_setDataFn,
- AbstractClassRep::GetDataNotify in_getDataFn,
- const U32 in_elementCount,
- const char* in_pFieldDocs,
- U32 flags)
- {
- addProtectedField(
- in_pFieldname,
- in_fieldType,
- in_fieldOffset,
- in_setDataFn,
- in_getDataFn,
- &defaultProtectedWriteFn,
- in_elementCount,
- in_pFieldDocs,
- flags);
- }
- void ConsoleObject::addProtectedField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::SetDataNotify in_setDataFn,
- AbstractClassRep::GetDataNotify in_getDataFn,
- AbstractClassRep::WriteDataNotify in_writeDataFn,
- const U32 in_elementCount,
- const char* in_pFieldDocs,
- U32 flags)
- {
- AbstractClassRep::Field f;
- f.pFieldname = StringTable->insert(in_pFieldname);
- if (in_pFieldDocs)
- f.pFieldDocs = in_pFieldDocs;
- f.type = in_fieldType;
- f.offset = in_fieldOffset;
- f.elementCount = in_elementCount;
- f.validator = NULL;
- f.flag = flags;
- f.setDataFn = in_setDataFn;
- f.getDataFn = in_getDataFn;
- f.writeDataFn = in_writeDataFn;
- f.networkMask = 0;
- ConsoleBaseType* conType = ConsoleBaseType::getType(in_fieldType);
- AssertFatal(conType, "ConsoleObject::addProtectedField - invalid console type");
- f.table = conType->getEnumTable();
- sg_tempFieldList.push_back(f);
- }
- void ConsoleObject::addFieldV(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- TypeValidator *v,
- const char* in_pFieldDocs)
- {
- AbstractClassRep::Field f;
- f.pFieldname = StringTable->insert(in_pFieldname);
- if(in_pFieldDocs)
- f.pFieldDocs = in_pFieldDocs;
- f.type = in_fieldType;
- f.offset = in_fieldOffset;
- f.elementCount = 1;
- f.table = NULL;
- f.setDataFn = &defaultProtectedSetFn;
- f.getDataFn = &defaultProtectedGetFn;
- f.writeDataFn = &defaultProtectedWriteFn;
- f.validator = v;
- f.networkMask = 0;
- v->fieldIndex = sg_tempFieldList.size();
- sg_tempFieldList.push_back(f);
- }
- void ConsoleObject::addDeprecatedField(const char *fieldName)
- {
- AbstractClassRep::Field f;
- f.pFieldname = StringTable->insert(fieldName);
- f.type = AbstractClassRep::DeprecatedFieldType;
- f.offset = 0;
- f.elementCount = 0;
- f.table = NULL;
- f.validator = NULL;
- f.setDataFn = &defaultProtectedSetFn;
- f.getDataFn = &defaultProtectedGetFn;
- f.writeDataFn = &defaultProtectedWriteFn;
- f.networkMask = 0;
- 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()
- {
- }
- //--------------------------------------
- AbstractClassRep* ConsoleObject::getClassRep() const
- {
- return NULL;
- }
- bool ConsoleObject::disableFieldSubstitutions(const char* fieldname)
- {
- StringTableEntry slotname = StringTable->insert(fieldname);
- for (U32 i = 0; i < sg_tempFieldList.size(); i++)
- {
- if (sg_tempFieldList[i].pFieldname == slotname)
- {
- sg_tempFieldList[i].doNotSubstitute = true;
- sg_tempFieldList[i].keepClearSubsOnly = false;
- return true;
- }
- }
- return false;
- }
- bool ConsoleObject::onlyKeepClearSubstitutions(const char* fieldname)
- {
- StringTableEntry slotname = StringTable->insert(fieldname);
- for (U32 i = 0; i < sg_tempFieldList.size(); i++)
- {
- if (sg_tempFieldList[i].pFieldname == slotname)
- {
- sg_tempFieldList[i].doNotSubstitute = false;
- sg_tempFieldList[i].keepClearSubsOnly = true;
- return true;
- }
- }
- return false;
- }
- String ConsoleObject::_getLogMessage(const char* fmt, va_list args) const
- {
- String objClass = "UnknownClass";
- if(getClassRep())
- objClass = getClassRep()->getClassName();
-
- String formattedMessage = String::VToString(fmt, args);
- return String::ToString("%s - Object at %x - %s",
- objClass.c_str(), this, formattedMessage.c_str());
- }
- void ConsoleObject::logMessage(const char* fmt, ...) const
- {
- va_list args;
- va_start(args, fmt);
- Con::printf(_getLogMessage(fmt, args));
- va_end(args);
- }
- void ConsoleObject::logWarning(const char* fmt, ...) const
- {
- va_list args;
- va_start(args, fmt);
- Con::warnf(_getLogMessage(fmt, args));
- va_end(args);
- }
- void ConsoleObject::logError(const char* fmt, ...) const
- {
- va_list args;
- va_start(args, fmt);
- Con::errorf(_getLogMessage(fmt, args));
- va_end(args);
- }
- //------------------------------------------------------------------------------
- static const char* returnClassList( Vector< AbstractClassRep* >& classes, U32 bufSize )
- {
- if( !classes.size() )
- return "";
-
- dQsort( classes.address(), classes.size(), sizeof( AbstractClassRep* ), ACRCompare );
- char* ret = Con::getReturnBuffer( bufSize );
- dStrcpy( ret, classes[ 0 ]->getClassName(), bufSize );
- for( U32 i = 1; i < classes.size(); i ++ )
- {
- dStrcat( ret, "\t", bufSize );
- dStrcat( ret, classes[ i ]->getClassName(), bufSize );
- }
-
- return ret;
- }
- //------------------------------------------------------------------------------
- DefineEngineFunction( isClass, bool, ( const char* identifier ),,
- "@brief Returns true if the passed identifier is the name of a declared class.\n\n"
- "@ingroup Console")
- {
- AbstractClassRep* rep = AbstractClassRep::findClassRep( identifier );
- return rep != NULL;
- }
- DefineEngineFunction( isMemberOfClass, bool, ( const char* className, const char* superClassName ),,
- "@brief Returns true if the class is derived from the super class.\n\n"
- "If either class doesn't exist this returns false.\n"
- "@param className The class name.\n"
- "@param superClassName The super class to look for.\n"
- "@ingroup Console")
- {
- AbstractClassRep *pRep = AbstractClassRep::findClassRep( className );
- while (pRep)
- {
- if( !dStricmp( pRep->getClassName(), superClassName ) )
- return true;
- pRep = pRep->getParentClass();
- }
- return false;
- }
- DefineEngineFunction( getDescriptionOfClass, const char*, ( const char* className ),,
- "@brief Returns the description string for the named class.\n\n"
- "@param className The name of the class.\n"
- "@return The class description in string format.\n"
- "@ingroup Console")
- {
- AbstractClassRep* rep = AbstractClassRep::findClassRep( className );
- if( rep )
- return rep->getDescription();
- Con::errorf( "getDescriptionOfClass - no class called '%s'", className );
- return "";
- }
- DefineEngineFunction( getCategoryOfClass, const char*, ( const char* className ),,
- "@brief Returns the category of the given class.\n\n"
- "@param className The name of the class.\n"
- "@ingroup Console")
- {
- AbstractClassRep* rep = AbstractClassRep::findClassRep( className );
- if( rep )
- return rep->getCategory();
- Con::errorf( "getCategoryOfClass - no class called '%s'", className );
- return "";
- }
- DefineEngineFunction( enumerateConsoleClasses, const char*, ( const char* className ), ( "" ),
- "@brief Returns a list of classes that derive from the named class.\n\n"
- "If the named class is omitted this dumps all the classes.\n"
- "@param className The optional base class name.\n"
- "@return A tab delimited list of classes.\n"
- "@ingroup Editors\n"
- "@internal")
- {
- AbstractClassRep *base = NULL;
- if(className && *className)
- {
- base = AbstractClassRep::findClassRep(className);
- if(!base)
- return "";
- }
-
- Vector<AbstractClassRep*> classes;
- U32 bufSize = 0;
- for(AbstractClassRep *rep = AbstractClassRep::getClassList(); rep; rep = rep->getNextClass())
- {
- if( !base || rep->isClass(base))
- {
- classes.push_back(rep);
- bufSize += dStrlen(rep->getClassName()) + 1;
- }
- }
- return returnClassList( classes, bufSize );
- }
- DefineEngineFunction( enumerateConsoleClassesByCategory, const char*, ( String category ),,
- "@brief Provide a list of classes that belong to the given category.\n\n"
- "@param category The category name.\n"
- "@return A tab delimited list of classes.\n"
- "@ingroup Editors\n"
- "@internal")
- {
- U32 categoryLength = category.length();
-
- U32 bufSize = 0;
- Vector< AbstractClassRep* > classes;
-
- for( AbstractClassRep* rep = AbstractClassRep::getClassList(); rep != NULL; rep = rep->getNextClass() )
- {
- const String& repCategory = rep->getCategory();
-
- if( repCategory.length() >= categoryLength
- && ( repCategory.compare( category, categoryLength, String::NoCase ) == 0 )
- && ( repCategory[ categoryLength ] == ' ' || repCategory[ categoryLength ] == '\0' ) )
- {
- classes.push_back( rep );
- bufSize += dStrlen( rep->getClassName() ) + 1;
- }
- }
- return returnClassList( classes, bufSize );
- }
- DefineEngineFunction( dumpNetStats, void, (),,
- "@brief Dumps network statistics for each class to the console.\n\n"
- "The returned <i>avg</i>, <i>min</i> and <i>max</i> values are in bits sent per update. "
- "The <i>num</i> value is the total number of events collected.\n"
- "@note This method only works when TORQUE_NET_STATS is defined in torqueConfig.h.\n"
- "@ingroup Networking\n" )
- {
- #ifdef TORQUE_NET_STATS
- for (AbstractClassRep * rep = AbstractClassRep::getClassList(); rep; rep = rep->getNextClass())
- {
- if (rep->mNetStatPack.numEvents || rep->mNetStatUnpack.numEvents || rep->mNetStatWrite.numEvents || rep->mNetStatRead.numEvents)
- {
- Con::printf("class %s net info",rep->getClassName());
- if (rep->mNetStatPack.numEvents)
- Con::printf(" packUpdate: avg (%f), min (%i), max (%i), num (%i)",
- F32(rep->mNetStatPack.total)/F32(rep->mNetStatPack.numEvents),
- rep->mNetStatPack.min,
- rep->mNetStatPack.max,
- rep->mNetStatPack.numEvents);
- if (rep->mNetStatUnpack.numEvents)
- Con::printf(" unpackUpdate: avg (%f), min (%i), max (%i), num (%i)",
- F32(rep->mNetStatUnpack.total)/F32(rep->mNetStatUnpack.numEvents),
- rep->mNetStatUnpack.min,
- rep->mNetStatUnpack.max,
- rep->mNetStatUnpack.numEvents);
- if (rep->mNetStatWrite.numEvents)
- Con::printf(" write: avg (%f), min (%i), max (%i), num (%i)",
- F32(rep->mNetStatWrite.total)/F32(rep->mNetStatWrite.numEvents),
- rep->mNetStatWrite.min,
- rep->mNetStatWrite.max,
- rep->mNetStatWrite.numEvents);
- if (rep->mNetStatRead.numEvents)
- Con::printf(" read: avg (%f), min (%i), max (%i), num (%i)",
- F32(rep->mNetStatRead.total)/F32(rep->mNetStatRead.numEvents),
- rep->mNetStatRead.min,
- rep->mNetStatRead.max,
- rep->mNetStatRead.numEvents);
- S32 sum = 0;
- for (S32 i=0; i<32; i++)
- sum += rep->mDirtyMaskFrequency[i];
- if (sum)
- {
- Con::printf(" Mask bits:");
- for (S32 i=0; i<8; i++)
- {
- F32 avg0 = rep->mDirtyMaskFrequency[i] ? F32(rep->mDirtyMaskTotal[i])/F32(rep->mDirtyMaskFrequency[i]) : 0.0f;
- F32 avg8 = rep->mDirtyMaskFrequency[i+8] ? F32(rep->mDirtyMaskTotal[i+8])/F32(rep->mDirtyMaskFrequency[i+8]) : 0.0f;
- F32 avg16 = rep->mDirtyMaskFrequency[i+16] ? F32(rep->mDirtyMaskTotal[i+16])/F32(rep->mDirtyMaskFrequency[i+16]) : 0.0f;
- F32 avg24 = rep->mDirtyMaskFrequency[i+24] ? F32(rep->mDirtyMaskTotal[i+24])/F32(rep->mDirtyMaskFrequency[i+24]) : 0.0f;
- Con::printf(" %2i - %4i (%6.2f) %2i - %4i (%6.2f) %2i - %4i (%6.2f) %2i - %4i, (%6.2f)",
- i ,rep->mDirtyMaskFrequency[i],avg0,
- i+8 ,rep->mDirtyMaskFrequency[i+8],avg8,
- i+16,rep->mDirtyMaskFrequency[i+16],avg16,
- i+24,rep->mDirtyMaskFrequency[i+24],avg24);
- }
- }
- }
- rep->resetNetStats();
- }
- #endif
- }
- DefineEngineFunction( sizeof, S32, ( const char *objectOrClass ),,
- "@brief Determines the memory consumption of a class or object.\n\n"
- "@param objectOrClass The object or class being measured.\n"
- "@return Returns the total size of an object in bytes.\n"
- "@ingroup Debugging\n")
- {
- AbstractClassRep *acr = NULL;
- SimObject *obj = Sim::findObject(objectOrClass);
- if(obj)
- acr = obj->getClassRep();
- if(!acr)
- acr = AbstractClassRep::findClassRep(objectOrClass);
- if(acr)
- return acr->getSizeof();
- if(dStricmp("ConsoleObject", objectOrClass) == 0)
- return sizeof(ConsoleObject);
- Con::warnf("could not find a class rep for that object or class name.");
- return 0;
- }
- DefineEngineFunction(linkNamespaces, bool, ( String childNSName, String parentNSName ),,
- "@brief Links childNS to parentNS.\n\n"
- "Links childNS to parentNS, or nothing if parentNS is NULL.\n"
- "Will unlink the namespace from previous namespace if a parent already exists.\n"
- "@internal\n")
- {
- StringTableEntry childNSSTE = StringTable->insert(childNSName.c_str());
- StringTableEntry parentNSSTE = StringTable->insert(parentNSName.c_str());
-
- Namespace *childNS = Namespace::find(childNSSTE);
- Namespace *parentNS = Namespace::find(parentNSSTE);
-
- if (!childNS)
- {
- return false;
- }
- Namespace *currentParent = childNS->getParent();
-
- // Link to new NS if applicable
-
- if (currentParent != parentNS)
- {
- if (currentParent != NULL)
- {
- if (!childNS->unlinkClass(currentParent))
- {
- return false;
- }
- }
-
- if (parentNS != NULL)
- {
- return childNS->classLinkTo(parentNS);
- }
- }
-
- return true;
- }
|