consoleObject.cpp
Engine/source/console/consoleObject.cpp
Public Variables
char
replacebuf [1024]
sg_tempFieldList (__FILE__, __LINE__)
Public Functions
ACRCompare(const void * aptr, const void * bptr)
DefineEngineFunction(dumpNetStats , void , () , "@brief Dumps network statistics <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> each class <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n\n</a>" "The returned <<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>>avg</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>> , < <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >min</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > and< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >max</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > values are in bits sent per update. " "The< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >num</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > value is the total number of events <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">collected.\n</a>" " @note This method only works when TORQUE_NET_STATS is defined in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">torqueConfig.h.\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Networking\n</a>" )
DefineEngineFunction(enumerateConsoleClasses , const char * , (const char *className) , ("") , "@brief Returns a list of classes that derive from the named <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n\n</a>" "If the named class is omitted this dumps all the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">classes.\n</a>" "@param className The optional base class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">name.\n</a>" "@return A tab delimited list of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">classes.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editors\n</a>" "@internal" )
DefineEngineFunction(enumerateConsoleClassesByCategory , const char * , (String category) , "@brief Provide a list of classes that belong <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">category.\n\n</a>" "@param category The category <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">name.\n</a>" "@return A tab delimited list of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">classes.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editors\n</a>" "@internal" )
DefineEngineFunction(getCategoryOfClass , const char * , (const char *className) , "@brief Returns the category of the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n\n</a>" "@param className The name of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n</a>" "@ingroup Console" )
DefineEngineFunction(getDescriptionOfClass , const char * , (const char *className) , "@brief Returns the description string <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the named <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n\n</a>" "@param className The name of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n</a>" "@return The class description in string <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">format.\n</a>" "@ingroup Console" )
DefineEngineFunction(isClass , bool , (const char *identifier) , "@brief Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the passed identifier is the name of a declared <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n\n</a>" "@ingroup Console" )
DefineEngineFunction(isMemberOfClass , bool , (const char *className, const char *superClassName) , "@brief Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the class is derived from the super <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n\n</a>" "If either class doesn'<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a21feba301403a65090791a94f26c9d92">t</a> exist this returns <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">false.\n</a>" "@param className The class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">name.\n</a>" "@param superClassName The super class <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" "@ingroup Console" )
DefineEngineFunction(linkNamespaces , bool , (String childNSName, String parentNSName) , "@brief Links childNS <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">parentNS.\n\n</a>" "Links childNS <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> parentNS, or nothing <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> parentNS is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">NULL.\n</a>" "Will unlink the namespace from previous namespace <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> a parent already <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">exists.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">internal\n</a>" )
DefineEngineFunction(sizeof , S32 , (const char *objectOrClass) , "@brief Determines the memory consumption of a class or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "@param objectOrClass The object or class being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">measured.\n</a>" "@return Returns the total <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1ab7d671599a7b25ca99a487fa341bc33a">size</a> of an object in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">bytes.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Debugging\n</a>" )
IMPLEMENT_NONINSTANTIABLE_CLASS(ConsoleObject , "Legacy console system root class. Will disappear." )
IMPLEMENT_SCOPE(ConsoleAPI , Console , "Functionality related <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the legacy TorqueScript console system." )
const char *
returnClassList(Vector< AbstractClassRep * > & classes, U32 bufSize)
char *
suppressSpaces(const char * in_pname)
Detailed Description
Public Variables
char replacebuf [1024]
AbstractClassRep::FieldList sg_tempFieldList (__FILE__, __LINE__)
Public Functions
ACRCompare(const void * aptr, const void * bptr)
DefineEngineFunction(dumpNetStats , void , () , "@brief Dumps network statistics <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> each class <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n\n</a>" "The returned <<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>>avg</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>> , < <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >min</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > and< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >max</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > values are in bits sent per update. " "The< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >num</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > value is the total number of events <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">collected.\n</a>" " @note This method only works when TORQUE_NET_STATS is defined in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">torqueConfig.h.\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Networking\n</a>" )
DefineEngineFunction(enumerateConsoleClasses , const char * , (const char *className) , ("") , "@brief Returns a list of classes that derive from the named <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n\n</a>" "If the named class is omitted this dumps all the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">classes.\n</a>" "@param className The optional base class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">name.\n</a>" "@return A tab delimited list of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">classes.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editors\n</a>" "@internal" )
DefineEngineFunction(enumerateConsoleClassesByCategory , const char * , (String category) , "@brief Provide a list of classes that belong <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">category.\n\n</a>" "@param category The category <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">name.\n</a>" "@return A tab delimited list of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">classes.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editors\n</a>" "@internal" )
DefineEngineFunction(getCategoryOfClass , const char * , (const char *className) , "@brief Returns the category of the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n\n</a>" "@param className The name of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n</a>" "@ingroup Console" )
DefineEngineFunction(getDescriptionOfClass , const char * , (const char *className) , "@brief Returns the description string <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the named <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n\n</a>" "@param className The name of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n</a>" "@return The class description in string <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">format.\n</a>" "@ingroup Console" )
DefineEngineFunction(isClass , bool , (const char *identifier) , "@brief Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the passed identifier is the name of a declared <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n\n</a>" "@ingroup Console" )
DefineEngineFunction(isMemberOfClass , bool , (const char *className, const char *superClassName) , "@brief Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the class is derived from the super <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class.\n\n</a>" "If either class doesn'<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a21feba301403a65090791a94f26c9d92">t</a> exist this returns <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">false.\n</a>" "@param className The class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">name.\n</a>" "@param superClassName The super class <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" "@ingroup Console" )
DefineEngineFunction(linkNamespaces , bool , (String childNSName, String parentNSName) , "@brief Links childNS <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">parentNS.\n\n</a>" "Links childNS <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> parentNS, or nothing <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> parentNS is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">NULL.\n</a>" "Will unlink the namespace from previous namespace <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> a parent already <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">exists.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">internal\n</a>" )
DefineEngineFunction(sizeof , S32 , (const char *objectOrClass) , "@brief Determines the memory consumption of a class or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "@param objectOrClass The object or class being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">measured.\n</a>" "@return Returns the total <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1ab7d671599a7b25ca99a487fa341bc33a">size</a> of an object in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">bytes.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Debugging\n</a>" )
IMPLEMENT_NONINSTANTIABLE_CLASS(ConsoleObject , "Legacy console system root class. Will disappear." )
IMPLEMENT_SCOPE(ConsoleAPI , Console , "Functionality related <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the legacy TorqueScript console system." )
returnClassList(Vector< AbstractClassRep * > & classes, U32 bufSize)
suppressSpaces(const char * in_pname)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "console/consoleObject.h" 26 27#include "core/stringTable.h" 28#include "core/crc.h" 29#include "core/dataChunker.h" 30#include "console/console.h" 31#include "console/consoleInternal.h" 32#include "console/typeValidators.h" 33#include "console/simObject.h" 34#include "console/engineTypes.h" 35#include "console/engineAPI.h" 36 37 38IMPLEMENT_SCOPE( ConsoleAPI, Console,, 39 "Functionality related to the legacy TorqueScript console system." ); 40 41IMPLEMENT_NONINSTANTIABLE_CLASS( ConsoleObject, 42 "Legacy console system root class. Will disappear." ) 43END_IMPLEMENT_CLASS; 44 45 46AbstractClassRep * AbstractClassRep::classLinkList = NULL; 47AbstractClassRep::FieldList sg_tempFieldList( __FILE__, __LINE__ ); 48U32 AbstractClassRep::NetClassCount [NetClassGroupsCount][NetClassTypesCount] = {{"{"}}0, },}; 49U32 AbstractClassRep::NetClassBitSize[NetClassGroupsCount][NetClassTypesCount] = {{"{"}}0, },}; 50 51AbstractClassRep ** AbstractClassRep::classTable[NetClassGroupsCount][NetClassTypesCount]; 52 53U32 AbstractClassRep::classCRC[NetClassGroupsCount] = {CRC::INITIAL_CRC_VALUE, }; 54bool AbstractClassRep::initialized = false; 55 56 57 58//----------------------------------------------------------------------------- 59AbstractClassRep* AbstractClassRep::findFieldRoot(StringTableEntry fieldName) 60{ 61 // Find the field. 62 const Field* pField = findField(fieldName); 63 64 // Finish if not found. 65 if (pField == NULL) 66 return NULL; 67 68 // We're the root if we have no parent. 69 if (getParentClass() == NULL) 70 return this; 71 72 // Find the field root via the parent. 73 AbstractClassRep* pFieldRoot = getParentClass()->findFieldRoot(fieldName); 74 75 // We're the root if the parent does not have it else return the field root. 76 return pFieldRoot == NULL ? this : pFieldRoot; 77} 78 79void AbstractClassRep::init() 80{ 81 // Only add the renderable and selectable globals for 82 // classes derived from SceneObject which are the only 83 // objects for which these work. 84 if ( isSubclassOf( "SceneObject" ) ) 85 { 86 Con::addVariable( avar( "$%s::isRenderable", getClassName() ), TypeBool, &mIsRenderEnabled, 87 "@brief Disables rendering of all instances of this type.\n\n" ); 88 89 Con::addVariable( avar( "$%s::isSelectable", getClassName() ), TypeBool, &mIsSelectionEnabled, 90 "@brief Disables selection of all instances of this type.\n\n" ); 91 } 92} 93 94const AbstractClassRep::Field *AbstractClassRep::findField(StringTableEntry name) const 95{ 96 for(U32 i = 0; i < mFieldList.size(); i++) 97 if(mFieldList[i].pFieldname == name) 98 return &mFieldList[i]; 99 100 return NULL; 101} 102 103AbstractClassRep* AbstractClassRep::findClassRep(const char* in_pClassName) 104{ 105 AssertFatal(initialized, 106 "AbstractClassRep::findClassRep() - Tried to find an AbstractClassRep before AbstractClassRep::initialize()."); 107 108 for (AbstractClassRep *walk = classLinkList; walk; walk = walk->nextClass) 109 if (!dStricmp(walk->getClassName(), in_pClassName)) 110 return walk; 111 112 return NULL; 113} 114 115AbstractClassRep* AbstractClassRep::findClassRep( U32 groupId, U32 typeId, U32 classId ) 116{ 117 AssertFatal(initialized, 118 "AbstractClassRep::findClasRep() - Tried to create an object before AbstractClassRep::initialize()."); 119 AssertFatal(classId < NetClassCount[groupId][typeId], 120 "AbstractClassRep::findClassRep() - Class id out of range."); 121 AssertFatal(classTable[groupId][typeId][classId] != NULL, 122 "AbstractClassRep::findClassRep() - No class with requested ID type."); 123 124 // Look up the specified class and create it. 125 if(classTable[groupId][typeId][classId]) 126 return classTable[groupId][typeId][classId]; 127 128 return NULL; 129} 130 131//-------------------------------------- 132void AbstractClassRep::registerClassRep(AbstractClassRep* in_pRep) 133{ 134 AssertFatal(in_pRep != NULL, "AbstractClassRep::registerClassRep was passed a NULL pointer!"); 135 136#ifdef TORQUE_DEBUG // assert if this class is already registered. 137 for(AbstractClassRep *walk = classLinkList; walk; walk = walk->nextClass) 138 { 139 AssertFatal(dStrcmp(in_pRep->mClassName, walk->mClassName), 140 "Duplicate class name registered in AbstractClassRep::registerClassRep()"); 141 } 142#endif 143 144 in_pRep->nextClass = classLinkList; 145 classLinkList = in_pRep; 146} 147 148//-------------------------------------- 149void AbstractClassRep::removeClassRep(AbstractClassRep* in_pRep) 150{ 151 for( AbstractClassRep *walk = classLinkList; walk; walk = walk->nextClass ) 152 { 153 // This is the case that will most likely get hit. 154 if( walk->nextClass == in_pRep ) 155 walk->nextClass = walk->nextClass->nextClass; 156 else if( walk == in_pRep ) 157 { 158 AssertFatal( in_pRep == classLinkList, "Pat failed in his logic for un linking RuntimeClassReps from the class linked list" ); 159 classLinkList = in_pRep->nextClass; 160 } 161 } 162} 163 164//-------------------------------------- 165 166ConsoleObject* AbstractClassRep::create(const char* in_pClassName) 167{ 168 AssertFatal(initialized, 169 "AbstractClassRep::create() - Tried to create an object before AbstractClassRep::initialize()."); 170 171 const AbstractClassRep *rep = AbstractClassRep::findClassRep(in_pClassName); 172 if(rep) 173 return rep->create(); 174 175 AssertWarn(0, avar("Couldn't find class rep for dynamic class: %s", in_pClassName)); 176 return NULL; 177} 178 179//-------------------------------------- 180ConsoleObject* AbstractClassRep::create(const U32 groupId, const U32 typeId, const U32 in_classId) 181{ 182 AbstractClassRep* classRep = findClassRep( groupId, typeId, in_classId ); 183 if( !classRep ) 184 return NULL; 185 186 return classRep->create(); 187} 188 189//-------------------------------------- 190 191static S32 QSORT_CALLBACK ACRCompare(const void *aptr, const void *bptr) 192{ 193 const AbstractClassRep *a = *((const AbstractClassRep **) aptr); 194 const AbstractClassRep *b = *((const AbstractClassRep **) bptr); 195 196 if(a->mClassType != b->mClassType) 197 return a->mClassType - b->mClassType; 198 return dStrnatcasecmp(a->getClassName(), b->getClassName()); 199} 200 201void AbstractClassRep::initialize() 202{ 203 AssertFatal(!initialized, "Duplicate call to AbstractClassRep::initialize()!"); 204 Vector<AbstractClassRep*> dynamicTable(__FILE__, __LINE__); 205 206 AbstractClassRep *walk; 207 208 // Initialize namespace references... 209 for (walk = classLinkList; walk; walk = walk->nextClass) 210 { 211 walk->mNamespace = Con::lookupNamespace(StringTable->insert(walk->getClassName())); 212 walk->mNamespace->mUsage = walk->getDocString(); 213 walk->mNamespace->mClassRep = walk; 214 } 215 216 // Initialize field lists... (and perform other console registration). 217 for (walk = classLinkList; walk; walk = walk->nextClass) 218 { 219 // sg_tempFieldList is used as a staging area for field lists 220 // (see addField, addGroup, etc.) 221 sg_tempFieldList.setSize(0); 222 223 walk->init(); 224 225 // So if we have things in it, copy it over... 226 if (sg_tempFieldList.size() != 0) 227 walk->mFieldList = sg_tempFieldList; 228 229 // And of course delete it every round. 230 sg_tempFieldList.clear(); 231 } 232 233 // Calculate counts and bit sizes for the various NetClasses. 234 for (U32 group = 0; group < NetClassGroupsCount; group++) 235 { 236 U32 groupMask = 1 << group; 237 238 // Specifically, for each NetClass of each NetGroup... 239 for(U32 type = 0; type < NetClassTypesCount; type++) 240 { 241 // Go through all the classes and find matches... 242 for (walk = classLinkList; walk; walk = walk->nextClass) 243 { 244 if(walk->mClassType == type && walk->mClassGroupMask & groupMask) 245 dynamicTable.push_back(walk); 246 } 247 248 // Set the count for this NetGroup and NetClass 249 NetClassCount[group][type] = dynamicTable.size(); 250 if(!NetClassCount[group][type]) 251 continue; // If no classes matched, skip to next. 252 253 // Sort by type and then by name. 254 dQsort((void *) &dynamicTable[0], dynamicTable.size(), sizeof(AbstractClassRep *), ACRCompare); 255 256 // Allocate storage in the classTable 257 classTable[group][type] = new AbstractClassRep*[NetClassCount[group][type]]; 258 259 // Fill this in and assign class ids for this group. 260 for(U32 i = 0; i < NetClassCount[group][type];i++) 261 { 262 classTable[group][type][i] = dynamicTable[i]; 263 dynamicTable[i]->mClassId[group] = i; 264 } 265 266 // And calculate the size of bitfields for this group and type. 267 NetClassBitSize[group][type] = 268 getBinLog2(getNextPow2(NetClassCount[group][type] + 1)); 269 AssertFatal(NetClassCount[group][type] < (1 << NetClassBitSize[group][type]), "NetClassBitSize too small!"); 270 271 dynamicTable.clear(); 272 } 273 } 274 275 // Ok, we're golden! 276 initialized = true; 277} 278 279void AbstractClassRep::shutdown() 280{ 281 AssertFatal( initialized, "AbstractClassRep::shutdown - not initialized" ); 282 283 // Release storage allocated to the class table. 284 285 for (U32 group = 0; group < NetClassGroupsCount; group++) 286 for(U32 type = 0; type < NetClassTypesCount; type++) 287 if( classTable[ group ][ type ] ) 288 SAFE_DELETE_ARRAY( classTable[ group ][ type ] ); 289 290 initialized = false; 291} 292 293AbstractClassRep *AbstractClassRep::getCommonParent( const AbstractClassRep *otherClass ) const 294{ 295 // CodeReview: This may be a noob way of doing it. There may be some kind of 296 // super-spiffy algorithm to do what the code below does, but this appeared 297 // to make sense to me, and it is pretty easy to see what it is doing [6/23/2007 Pat] 298 299 static VectorPtr<AbstractClassRep*> thisClassHeirarchy; 300 thisClassHeirarchy.clear(); 301 302 AbstractClassRep *walk = const_cast<AbstractClassRep *>( this ); 303 304 while( walk != NULL ) 305 { 306 thisClassHeirarchy.push_front( walk ); 307 walk = walk->getParentClass(); 308 } 309 310 static VectorPtr<AbstractClassRep*> compClassHeirarchy; 311 compClassHeirarchy.clear(); 312 walk = const_cast<AbstractClassRep *>( otherClass ); 313 while( walk != NULL ) 314 { 315 compClassHeirarchy.push_front( walk ); 316 walk = walk->getParentClass(); 317 } 318 319 // Make sure we only iterate over the list the number of times we can 320 S32 maxIterations = getMin( compClassHeirarchy.size(), thisClassHeirarchy.size() ); 321 322 U32 i = 0; 323 for( ; i < maxIterations; i++ ) 324 { 325 if( compClassHeirarchy[i] != thisClassHeirarchy[i] ) 326 break; 327 } 328 329 return compClassHeirarchy[i]; 330} 331 332//------------------------------------------------------------------------------ 333//-------------------------------------- ConsoleObject 334 335static char replacebuf[1024]; 336static char* suppressSpaces(const char* in_pname) 337{ 338 U32 i = 0; 339 char chr; 340 do 341 { 342 chr = in_pname[i]; 343 replacebuf[i++] = (chr != 32) ? chr : '_'; 344 } while(chr); 345 346 return replacebuf; 347} 348 349void ConsoleObject::addGroup(const char* in_pGroupname, const char* in_pGroupDocs) 350{ 351 // Remove spaces. 352 char* pFieldNameBuf = suppressSpaces(in_pGroupname); 353 354 // Append group type to fieldname. 355 dStrcat(pFieldNameBuf, "_begingroup"); 356 357 // Create Field. 358 AbstractClassRep::Field f; 359 f.pFieldname = StringTable->insert(pFieldNameBuf); 360 f.pGroupname = in_pGroupname; 361 362 if(in_pGroupDocs) 363 f.pFieldDocs = in_pGroupDocs; 364 365 f.type = AbstractClassRep::StartGroupFieldType; 366 f.elementCount = 0; 367 f.groupExpand = false; 368 f.validator = NULL; 369 f.setDataFn = &defaultProtectedSetFn; 370 f.getDataFn = &defaultProtectedGetFn; 371 f.writeDataFn = &defaultProtectedWriteFn; 372 373 // Add to field list. 374 sg_tempFieldList.push_back(f); 375} 376 377void ConsoleObject::endGroup(const char* in_pGroupname) 378{ 379 // Remove spaces. 380 char* pFieldNameBuf = suppressSpaces(in_pGroupname); 381 382 // Append group type to fieldname. 383 dStrcat(pFieldNameBuf, "_endgroup"); 384 385 // Create Field. 386 AbstractClassRep::Field f; 387 f.pFieldname = StringTable->insert(pFieldNameBuf); 388 f.pGroupname = in_pGroupname; 389 f.type = AbstractClassRep::EndGroupFieldType; 390 f.groupExpand = false; 391 f.validator = NULL; 392 f.setDataFn = &defaultProtectedSetFn; 393 f.getDataFn = &defaultProtectedGetFn; 394 f.writeDataFn = &defaultProtectedWriteFn; 395 f.elementCount = 0; 396 397 // Add to field list. 398 sg_tempFieldList.push_back(f); 399} 400 401void ConsoleObject::addArray( const char *arrayName, S32 count ) 402{ 403 char *nameBuff = suppressSpaces(arrayName); 404 dStrcat(nameBuff, "_beginarray"); 405 406 // Create Field. 407 AbstractClassRep::Field f; 408 f.pFieldname = StringTable->insert(nameBuff); 409 f.pGroupname = arrayName; 410 411 f.type = AbstractClassRep::StartArrayFieldType; 412 f.elementCount = count; 413 f.groupExpand = false; 414 f.validator = NULL; 415 f.setDataFn = &defaultProtectedSetFn; 416 f.getDataFn = &defaultProtectedGetFn; 417 f.writeDataFn = &defaultProtectedWriteFn; 418 419 // Add to field list. 420 sg_tempFieldList.push_back(f); 421} 422 423void ConsoleObject::endArray( const char *arrayName ) 424{ 425 char *nameBuff = suppressSpaces(arrayName); 426 dStrcat(nameBuff, "_endarray"); 427 428 // Create Field. 429 AbstractClassRep::Field f; 430 f.pFieldname = StringTable->insert(nameBuff); 431 f.pGroupname = arrayName; 432 f.type = AbstractClassRep::EndArrayFieldType; 433 f.groupExpand = false; 434 f.validator = NULL; 435 f.setDataFn = &defaultProtectedSetFn; 436 f.getDataFn = &defaultProtectedGetFn; 437 f.writeDataFn = &defaultProtectedWriteFn; 438 f.elementCount = 0; 439 440 // Add to field list. 441 sg_tempFieldList.push_back(f); 442} 443 444void ConsoleObject::addField(const char* in_pFieldname, 445 const U32 in_fieldType, 446 const dsize_t in_fieldOffset, 447 const char* in_pFieldDocs, 448 U32 flags ) 449{ 450 addField( 451 in_pFieldname, 452 in_fieldType, 453 in_fieldOffset, 454 1, 455 in_pFieldDocs, 456 flags ); 457} 458 459void ConsoleObject::addField(const char* in_pFieldname, 460 const U32 in_fieldType, 461 const dsize_t in_fieldOffset, 462 AbstractClassRep::WriteDataNotify in_writeDataFn, 463 const char* in_pFieldDocs, 464 U32 flags) 465{ 466 addField( 467 in_pFieldname, 468 in_fieldType, 469 in_fieldOffset, 470 in_writeDataFn, 471 1, 472 in_pFieldDocs, 473 flags); 474} 475 476void ConsoleObject::addField(const char* in_pFieldname, 477 const U32 in_fieldType, 478 const dsize_t in_fieldOffset, 479 const U32 in_elementCount, 480 const char* in_pFieldDocs, 481 U32 flags) 482{ 483 addField(in_pFieldname, 484 in_fieldType, 485 in_fieldOffset, 486 &defaultProtectedWriteFn, 487 in_elementCount, 488 in_pFieldDocs, 489 flags); 490} 491 492void ConsoleObject::addField(const char* in_pFieldname, 493 const U32 in_fieldType, 494 const dsize_t in_fieldOffset, 495 AbstractClassRep::WriteDataNotify in_writeDataFn, 496 const U32 in_elementCount, 497 const char* in_pFieldDocs, 498 U32 flags) 499{ 500 AbstractClassRep::Field f; 501 f.pFieldname = StringTable->insert(in_pFieldname); 502 503 if (in_pFieldDocs) 504 f.pFieldDocs = in_pFieldDocs; 505 506 f.type = in_fieldType; 507 f.offset = in_fieldOffset; 508 f.elementCount = in_elementCount; 509 f.validator = NULL; 510 f.flag = flags; 511 512 f.setDataFn = &defaultProtectedSetFn; 513 f.getDataFn = &defaultProtectedGetFn; 514 f.writeDataFn = in_writeDataFn; 515 516 ConsoleBaseType* conType = ConsoleBaseType::getType(in_fieldType); 517 AssertFatal(conType, "ConsoleObject::addField - invalid console type"); 518 f.table = conType->getEnumTable(); 519 520 sg_tempFieldList.push_back(f); 521} 522 523void ConsoleObject::addProtectedField(const char* in_pFieldname, 524 const U32 in_fieldType, 525 const dsize_t in_fieldOffset, 526 AbstractClassRep::SetDataNotify in_setDataFn, 527 AbstractClassRep::GetDataNotify in_getDataFn, 528 const char* in_pFieldDocs, 529 U32 flags) 530{ 531 addProtectedField( 532 in_pFieldname, 533 in_fieldType, 534 in_fieldOffset, 535 in_setDataFn, 536 in_getDataFn, 537 &defaultProtectedWriteFn, 538 1, 539 in_pFieldDocs, 540 flags); 541} 542 543void ConsoleObject::addProtectedField(const char* in_pFieldname, 544 const U32 in_fieldType, 545 const dsize_t in_fieldOffset, 546 AbstractClassRep::SetDataNotify in_setDataFn, 547 AbstractClassRep::GetDataNotify in_getDataFn, 548 AbstractClassRep::WriteDataNotify in_writeDataFn, 549 const char* in_pFieldDocs, 550 U32 flags) 551{ 552 addProtectedField( 553 in_pFieldname, 554 in_fieldType, 555 in_fieldOffset, 556 in_setDataFn, 557 in_getDataFn, 558 in_writeDataFn, 559 1, 560 in_pFieldDocs, 561 flags); 562} 563 564void ConsoleObject::addProtectedField(const char* in_pFieldname, 565 const U32 in_fieldType, 566 const dsize_t in_fieldOffset, 567 AbstractClassRep::SetDataNotify in_setDataFn, 568 AbstractClassRep::GetDataNotify in_getDataFn, 569 const U32 in_elementCount, 570 const char* in_pFieldDocs, 571 U32 flags) 572{ 573 addProtectedField( 574 in_pFieldname, 575 in_fieldType, 576 in_fieldOffset, 577 in_setDataFn, 578 in_getDataFn, 579 &defaultProtectedWriteFn, 580 in_elementCount, 581 in_pFieldDocs, 582 flags); 583} 584void ConsoleObject::addProtectedField(const char* in_pFieldname, 585 const U32 in_fieldType, 586 const dsize_t in_fieldOffset, 587 AbstractClassRep::SetDataNotify in_setDataFn, 588 AbstractClassRep::GetDataNotify in_getDataFn, 589 AbstractClassRep::WriteDataNotify in_writeDataFn, 590 const U32 in_elementCount, 591 const char* in_pFieldDocs, 592 U32 flags) 593{ 594 AbstractClassRep::Field f; 595 f.pFieldname = StringTable->insert(in_pFieldname); 596 597 if (in_pFieldDocs) 598 f.pFieldDocs = in_pFieldDocs; 599 600 f.type = in_fieldType; 601 f.offset = in_fieldOffset; 602 f.elementCount = in_elementCount; 603 f.validator = NULL; 604 f.flag = flags; 605 606 f.setDataFn = in_setDataFn; 607 f.getDataFn = in_getDataFn; 608 f.writeDataFn = in_writeDataFn; 609 610 ConsoleBaseType* conType = ConsoleBaseType::getType(in_fieldType); 611 AssertFatal(conType, "ConsoleObject::addProtectedField - invalid console type"); 612 f.table = conType->getEnumTable(); 613 614 sg_tempFieldList.push_back(f); 615} 616 617void ConsoleObject::addFieldV(const char* in_pFieldname, 618 const U32 in_fieldType, 619 const dsize_t in_fieldOffset, 620 TypeValidator *v, 621 const char* in_pFieldDocs) 622{ 623 AbstractClassRep::Field f; 624 f.pFieldname = StringTable->insert(in_pFieldname); 625 if(in_pFieldDocs) 626 f.pFieldDocs = in_pFieldDocs; 627 f.type = in_fieldType; 628 f.offset = in_fieldOffset; 629 f.elementCount = 1; 630 f.table = NULL; 631 f.setDataFn = &defaultProtectedSetFn; 632 f.getDataFn = &defaultProtectedGetFn; 633 f.writeDataFn = &defaultProtectedWriteFn; 634 f.validator = v; 635 v->fieldIndex = sg_tempFieldList.size(); 636 637 sg_tempFieldList.push_back(f); 638} 639 640void ConsoleObject::addDeprecatedField(const char *fieldName) 641{ 642 AbstractClassRep::Field f; 643 f.pFieldname = StringTable->insert(fieldName); 644 f.type = AbstractClassRep::DeprecatedFieldType; 645 f.offset = 0; 646 f.elementCount = 0; 647 f.table = NULL; 648 f.validator = NULL; 649 f.setDataFn = &defaultProtectedSetFn; 650 f.getDataFn = &defaultProtectedGetFn; 651 f.writeDataFn = &defaultProtectedWriteFn; 652 653 sg_tempFieldList.push_back(f); 654} 655 656 657bool ConsoleObject::removeField(const char* in_pFieldname) 658{ 659 for (U32 i = 0; i < sg_tempFieldList.size(); i++) { 660 if (dStricmp(in_pFieldname, sg_tempFieldList[i].pFieldname) == 0) { 661 sg_tempFieldList.erase(i); 662 return true; 663 } 664 } 665 666 return false; 667} 668 669//-------------------------------------- 670void ConsoleObject::initPersistFields() 671{ 672} 673 674//-------------------------------------- 675void ConsoleObject::consoleInit() 676{ 677} 678 679//-------------------------------------- 680AbstractClassRep* ConsoleObject::getClassRep() const 681{ 682 return NULL; 683} 684 685String ConsoleObject::_getLogMessage(const char* fmt, va_list args) const 686{ 687 String objClass = "UnknownClass"; 688 if(getClassRep()) 689 objClass = getClassRep()->getClassName(); 690 691 String formattedMessage = String::VToString(fmt, args); 692 return String::ToString("%s - Object at %x - %s", 693 objClass.c_str(), this, formattedMessage.c_str()); 694} 695 696void ConsoleObject::logMessage(const char* fmt, ...) const 697{ 698 va_list args; 699 va_start(args, fmt); 700 Con::printf(_getLogMessage(fmt, args)); 701 va_end(args); 702} 703 704void ConsoleObject::logWarning(const char* fmt, ...) const 705{ 706 va_list args; 707 va_start(args, fmt); 708 Con::warnf(_getLogMessage(fmt, args)); 709 va_end(args); 710} 711 712void ConsoleObject::logError(const char* fmt, ...) const 713{ 714 va_list args; 715 va_start(args, fmt); 716 Con::errorf(_getLogMessage(fmt, args)); 717 va_end(args); 718} 719 720 721//------------------------------------------------------------------------------ 722 723static const char* returnClassList( Vector< AbstractClassRep*>& classes, U32 bufSize ) 724{ 725 if( !classes.size() ) 726 return ""; 727 728 dQsort( classes.address(), classes.size(), sizeof( AbstractClassRep* ), ACRCompare ); 729 730 char* ret = Con::getReturnBuffer( bufSize ); 731 dStrcpy( ret, classes[ 0 ]->getClassName() ); 732 for( U32 i = 1; i < classes.size(); i ++ ) 733 { 734 dStrcat( ret, "\t" ); 735 dStrcat( ret, classes[ i ]->getClassName() ); 736 } 737 738 return ret; 739} 740 741//------------------------------------------------------------------------------ 742 743DefineEngineFunction( isClass, bool, ( const char* identifier ),, 744 "@brief Returns true if the passed identifier is the name of a declared class.\n\n" 745 "@ingroup Console") 746{ 747 AbstractClassRep* rep = AbstractClassRep::findClassRep( identifier ); 748 return rep != NULL; 749} 750 751DefineEngineFunction( isMemberOfClass, bool, ( const char* className, const char* superClassName ),, 752 "@brief Returns true if the class is derived from the super class.\n\n" 753 "If either class doesn't exist this returns false.\n" 754 "@param className The class name.\n" 755 "@param superClassName The super class to look for.\n" 756 "@ingroup Console") 757{ 758 AbstractClassRep *pRep = AbstractClassRep::findClassRep( className ); 759 while (pRep) 760 { 761 if( !dStricmp( pRep->getClassName(), superClassName ) ) 762 return true; 763 pRep = pRep->getParentClass(); 764 } 765 return false; 766} 767 768DefineEngineFunction( getDescriptionOfClass, const char*, ( const char* className ),, 769 "@brief Returns the description string for the named class.\n\n" 770 "@param className The name of the class.\n" 771 "@return The class description in string format.\n" 772 "@ingroup Console") 773{ 774 AbstractClassRep* rep = AbstractClassRep::findClassRep( className ); 775 if( rep ) 776 return rep->getDescription(); 777 778 Con::errorf( "getDescriptionOfClass - no class called '%s'", className ); 779 return ""; 780} 781 782DefineEngineFunction( getCategoryOfClass, const char*, ( const char* className ),, 783 "@brief Returns the category of the given class.\n\n" 784 "@param className The name of the class.\n" 785 "@ingroup Console") 786{ 787 AbstractClassRep* rep = AbstractClassRep::findClassRep( className ); 788 if( rep ) 789 return rep->getCategory(); 790 791 Con::errorf( "getCategoryOfClass - no class called '%s'", className ); 792 return ""; 793} 794 795DefineEngineFunction( enumerateConsoleClasses, const char*, ( const char* className ), ( "" ), 796 "@brief Returns a list of classes that derive from the named class.\n\n" 797 "If the named class is omitted this dumps all the classes.\n" 798 "@param className The optional base class name.\n" 799 "@return A tab delimited list of classes.\n" 800 "@ingroup Editors\n" 801 "@internal") 802{ 803 AbstractClassRep *base = NULL; 804 if(className && *className) 805 { 806 base = AbstractClassRep::findClassRep(className); 807 if(!base) 808 return ""; 809 } 810 811 Vector<AbstractClassRep*> classes; 812 U32 bufSize = 0; 813 for(AbstractClassRep *rep = AbstractClassRep::getClassList(); rep; rep = rep->getNextClass()) 814 { 815 if( !base || rep->isClass(base)) 816 { 817 classes.push_back(rep); 818 bufSize += dStrlen(rep->getClassName()) + 1; 819 } 820 } 821 822 return returnClassList( classes, bufSize ); 823} 824 825DefineEngineFunction( enumerateConsoleClassesByCategory, const char*, ( String category ),, 826 "@brief Provide a list of classes that belong to the given category.\n\n" 827 "@param category The category name.\n" 828 "@return A tab delimited list of classes.\n" 829 "@ingroup Editors\n" 830 "@internal") 831{ 832 U32 categoryLength = category.length(); 833 834 U32 bufSize = 0; 835 Vector< AbstractClassRep*> classes; 836 837 for( AbstractClassRep* rep = AbstractClassRep::getClassList(); rep != NULL; rep = rep->getNextClass() ) 838 { 839 const String& repCategory = rep->getCategory(); 840 841 if( repCategory.length() >= categoryLength 842 && ( repCategory.compare( category, categoryLength, String::NoCase ) == 0 ) 843 && ( repCategory[ categoryLength ] == ' ' || repCategory[ categoryLength ] == '\0' ) ) 844 { 845 classes.push_back( rep ); 846 bufSize += dStrlen( rep->getClassName() + 1 ); 847 } 848 } 849 850 return returnClassList( classes, bufSize ); 851} 852 853DefineEngineFunction( dumpNetStats, void, (),, 854 "@brief Dumps network statistics for each class to the console.\n\n" 855 856 "The returned <i>avg</i>, <i>min</i> and <i>max</i> values are in bits sent per update. " 857 "The <i>num</i> value is the total number of events collected.\n" 858 859 "@note This method only works when TORQUE_NET_STATS is defined in torqueConfig.h.\n" 860 "@ingroup Networking\n" ) 861{ 862#ifdef TORQUE_NET_STATS 863 for (AbstractClassRep * rep = AbstractClassRep::getClassList(); rep; rep = rep->getNextClass()) 864 { 865 if (rep->mNetStatPack.numEvents || rep->mNetStatUnpack.numEvents || rep->mNetStatWrite.numEvents || rep->mNetStatRead.numEvents) 866 { 867 Con::printf("class %s net info",rep->getClassName()); 868 if (rep->mNetStatPack.numEvents) 869 Con::printf(" packUpdate: avg (%f), min (%i), max (%i), num (%i)", 870 F32(rep->mNetStatPack.total)/<a href="/coding/file/types_8h/#types_8h_1a841d3674577a1e86afdc2f4845f46c4b">F32</a>(rep->mNetStatPack.numEvents), 871 rep->mNetStatPack.min, 872 rep->mNetStatPack.max, 873 rep->mNetStatPack.numEvents); 874 if (rep->mNetStatUnpack.numEvents) 875 Con::printf(" unpackUpdate: avg (%f), min (%i), max (%i), num (%i)", 876 F32(rep->mNetStatUnpack.total)/<a href="/coding/file/types_8h/#types_8h_1a841d3674577a1e86afdc2f4845f46c4b">F32</a>(rep->mNetStatUnpack.numEvents), 877 rep->mNetStatUnpack.min, 878 rep->mNetStatUnpack.max, 879 rep->mNetStatUnpack.numEvents); 880 if (rep->mNetStatWrite.numEvents) 881 Con::printf(" write: avg (%f), min (%i), max (%i), num (%i)", 882 F32(rep->mNetStatWrite.total)/<a href="/coding/file/types_8h/#types_8h_1a841d3674577a1e86afdc2f4845f46c4b">F32</a>(rep->mNetStatWrite.numEvents), 883 rep->mNetStatWrite.min, 884 rep->mNetStatWrite.max, 885 rep->mNetStatWrite.numEvents); 886 if (rep->mNetStatRead.numEvents) 887 Con::printf(" read: avg (%f), min (%i), max (%i), num (%i)", 888 F32(rep->mNetStatRead.total)/<a href="/coding/file/types_8h/#types_8h_1a841d3674577a1e86afdc2f4845f46c4b">F32</a>(rep->mNetStatRead.numEvents), 889 rep->mNetStatRead.min, 890 rep->mNetStatRead.max, 891 rep->mNetStatRead.numEvents); 892 S32 sum = 0; 893 for (S32 i=0; i<32; i++) 894 sum += rep->mDirtyMaskFrequency[i]; 895 if (sum) 896 { 897 Con::printf(" Mask bits:"); 898 for (S32 i=0; i<8; i++) 899 { 900 F32 avg0 = rep->mDirtyMaskFrequency[i] ? F32(rep->mDirtyMaskTotal[i])/<a href="/coding/file/types_8h/#types_8h_1a841d3674577a1e86afdc2f4845f46c4b">F32</a>(rep->mDirtyMaskFrequency[i]) : 0.0f; 901 F32 avg8 = rep->mDirtyMaskFrequency[i+8] ? F32(rep->mDirtyMaskTotal[i+8])/<a href="/coding/file/types_8h/#types_8h_1a841d3674577a1e86afdc2f4845f46c4b">F32</a>(rep->mDirtyMaskFrequency[i+8]) : 0.0f; 902 F32 avg16 = rep->mDirtyMaskFrequency[i+16] ? F32(rep->mDirtyMaskTotal[i+16])/<a href="/coding/file/types_8h/#types_8h_1a841d3674577a1e86afdc2f4845f46c4b">F32</a>(rep->mDirtyMaskFrequency[i+16]) : 0.0f; 903 F32 avg24 = rep->mDirtyMaskFrequency[i+24] ? F32(rep->mDirtyMaskTotal[i+24])/<a href="/coding/file/types_8h/#types_8h_1a841d3674577a1e86afdc2f4845f46c4b">F32</a>(rep->mDirtyMaskFrequency[i+24]) : 0.0f; 904 Con::printf(" %2i - %4i (%6.2f) %2i - %4i (%6.2f) %2i - %4i (%6.2f) %2i - %4i, (%6.2f)", 905 i ,rep->mDirtyMaskFrequency[i],avg0, 906 i+8 ,rep->mDirtyMaskFrequency[i+8],avg8, 907 i+16,rep->mDirtyMaskFrequency[i+16],avg16, 908 i+24,rep->mDirtyMaskFrequency[i+24],avg24); 909 } 910 } 911 } 912 rep->resetNetStats(); 913 } 914#endif 915} 916 917DefineEngineFunction( sizeof, S32, ( const char *objectOrClass ),, 918 "@brief Determines the memory consumption of a class or object.\n\n" 919 "@param objectOrClass The object or class being measured.\n" 920 "@return Returns the total size of an object in bytes.\n" 921 "@ingroup Debugging\n") 922{ 923 AbstractClassRep *acr = NULL; 924 SimObject *obj = Sim::findObject(objectOrClass); 925 if(obj) 926 acr = obj->getClassRep(); 927 928 if(!acr) 929 acr = AbstractClassRep::findClassRep(objectOrClass); 930 931 if(acr) 932 return acr->getSizeof(); 933 934 if(dStricmp("ConsoleObject", objectOrClass) == 0) 935 return sizeof(ConsoleObject); 936 937 Con::warnf("could not find a class rep for that object or class name."); 938 return 0; 939} 940 941 942DefineEngineFunction(linkNamespaces, bool, ( String childNSName, String parentNSName ),, 943 "@brief Links childNS to parentNS.\n\n" 944 "Links childNS to parentNS, or nothing if parentNS is NULL.\n" 945 "Will unlink the namespace from previous namespace if a parent already exists.\n" 946 "@internal\n") 947{ 948 StringTableEntry childNSSTE = StringTable->insert(childNSName.c_str()); 949 StringTableEntry parentNSSTE = StringTable->insert(parentNSName.c_str()); 950 951 Namespace *childNS = Namespace::find(childNSSTE); 952 Namespace *parentNS = Namespace::find(parentNSSTE); 953 954 if (!childNS) 955 { 956 return false; 957 } 958 959 Namespace *currentParent = childNS->getParent(); 960 961 // Link to new NS if applicable 962 963 if (currentParent != parentNS) 964 { 965 if (currentParent != NULL) 966 { 967 if (!childNS->unlinkClass(currentParent)) 968 { 969 return false; 970 } 971 } 972 973 if (parentNS != NULL) 974 { 975 return childNS->classLinkTo(parentNS); 976 } 977 } 978 979 return true; 980} 981 982
