SimObject::dumpFields() and SimObject::dumpMethods()
by Orion Elenzil · 02/12/2008 (9:11 am) · 6 comments
Improvements to dump().
(note i originally submitted a much simpler version of this improvement which was just trivial; this version has some real utility)
This resource improves %obj.dump() and provides new methods %obj.dumpFields() and %obj.dumpMethods() and also a new function dumpMethods(className).
The result is that you can easily see two things:
First, the class inheritance of an object, and second, the method inheritance of an object.
warning as of 20080211, this resource can mislead you in the case where a child namespace implements a function which is also in a parent namespace: it will appear in the first namespace to implement it, and not in the children who also implement it. see discussion here.
The modifications are simple,
but familiarity with C++ and the Torque codebase is assumed.
the following is based on a TGE 1.3.5 codebase, but is probably applicable to TGE 1.X, TGB, TGEA, etc.
simBase.h
add this somewhere to the declaration of class SimObject:
simBase.cc
replace the whole ConsoleMethod(SimObject, dump, void, 2, 2, "obj.dump()") section of code w/ this:
consoleInternal.h
right after the line static void dump();
add:
consoleInternal.cc
right after the method void Namespace::dump()
add:
at the bottom of the file (just after ConsoleFunctionGroupEnd( Packages );),
add:
example output:
note this can also be used to dump global functions which belong to a namespace.
eg, if:
orion elenzil 2008
(note i originally submitted a much simpler version of this improvement which was just trivial; this version has some real utility)
This resource improves %obj.dump() and provides new methods %obj.dumpFields() and %obj.dumpMethods() and also a new function dumpMethods(className).
The result is that you can easily see two things:
First, the class inheritance of an object, and second, the method inheritance of an object.
warning as of 20080211, this resource can mislead you in the case where a child namespace implements a function which is also in a parent namespace: it will appear in the first namespace to implement it, and not in the children who also implement it. see discussion here.
The modifications are simple,
but familiarity with C++ and the Torque codebase is assumed.
the following is based on a TGE 1.3.5 codebase, but is probably applicable to TGE 1.X, TGB, TGEA, etc.
simBase.h
add this somewhere to the declaration of class SimObject:
public: void dumpFields (); void dumpMethods ();
simBase.cc
replace the whole ConsoleMethod(SimObject, dump, void, 2, 2, "obj.dump()") section of code w/ this:
void SimObject::dumpFields()
{
const AbstractClassRep::FieldList &list = getFieldList();
S32 bufSize = 1024;
char* expandedBuffer = new char[bufSize];
Con::printf("Member Fields:");
Vector<const AbstractClassRep::Field *> flist(__FILE__, __LINE__);
for(U32 n = 0; n < list.size(); n++)
flist.push_back(&list[n]);
dQsort(flist.address(),flist.size(),sizeof(AbstractClassRep::Field *),compareFields);
for(Vector<const AbstractClassRep::Field *>::iterator itr = flist.begin(); itr != flist.end(); itr++)
{
const AbstractClassRep::Field* f = *itr;
if(f->type == AbstractClassRep::DepricatedFieldType ||
f->type == AbstractClassRep::StartGroupFieldType ||
f->type == AbstractClassRep::EndGroupFieldType ) continue;
for(U32 j = 0; S32(j) < f->elementCount; j++)
{
const char *val = (f->getDataFn)(this, Con::getData(f->type, (void *) (((const char *)this) + f->offset), j, f->table, f->flag));
if(!val || !*val)
continue;
S32 worstCaseSize = dStrlen(val) * 4 + dStrlen(f->pFieldname) + 32; // 32 is arbitrary, just for spaces and quotes and stuff.
if (worstCaseSize > bufSize)
{
delete [] expandedBuffer;
bufSize = worstCaseSize;
expandedBuffer = new char[bufSize];
}
if(f->elementCount == 1)
dSprintf(expandedBuffer, bufSize, " %s = \"", f->pFieldname);
else
dSprintf(expandedBuffer, bufSize, " %s[%d] = \"", f->pFieldname, j);
S32 bufUsed = dStrlen(expandedBuffer);
expandEscape(expandedBuffer + bufUsed, val, sizeof(expandedBuffer) - bufUsed);
Con::printf("%s\"", expandedBuffer);
}
}
Con::printf("Tagged Fields:");
if(getFieldDictionary())
getFieldDictionary()->printFields(this);
delete [] expandedBuffer;
}
void SimObject::dumpMethods()
{
getNamespace()->dumpMethods();
}
ConsoleMethod(SimObject, dump, void, 2, 2, "obj.dump()")
{
object->dumpFields ();
object->dumpMethods();
}
ConsoleMethod(SimObject, dumpFields, void, 2, 2, "obj.dumpFields()")
{
object->dumpFields ();
}
ConsoleMethod(SimObject, dumpMethods, void, 2, 2, "obj.dumpMethods()")
{
object->dumpMethods();
}consoleInternal.h
right after the line static void dump();
add:
void dumpMethods();
consoleInternal.cc
right after the method void Namespace::dump()
add:
void Namespace::dumpMethods()
{
if (this == NULL) // i <3 madness!
return;
mParent->dumpMethods();
Vector<Namespace::Entry *> vec(__FILE__, __LINE__);
getEntryList(&vec);
bool isNative;
S32 count = 0;
for (Vector<Namespace::Entry *>::iterator j = vec.begin(); j != vec.end(); j++)
{
if (mParent == NULL)
isNative = true;
else
isNative = (mParent->lookup((*j)->mFunctionName) == NULL);
count += isNative ? 1 : 0;
}
const char* formatString;
if (mPackage != NULL)
formatString = "%3d Methods from %s in package %s:";
else
formatString = "%3d Methods from %s:";
Con::printf(formatString, count, mName, mPackage);
for (Vector<Namespace::Entry *>::iterator j = vec.begin(); j != vec.end(); j++)
{
if (mParent == NULL)
isNative = true;
else
isNative = (mParent->lookup((*j)->mFunctionName) == NULL);
if (isNative)
{
#ifdef TORQUE_DEBUG
formatString = " %-40s() %3s - %s";
#else // TORQUE_DEBUG
formatString = " %-40s() %3s";
#endif // TORQUE_DEBUG
Con::printf(formatString, (*j)->mFunctionName, (*j)->mType == Entry::ScriptFunctionType ? "scr" : "eng", (*j)->mUsage ? (*j)->mUsage : "");
}
}
}at the bottom of the file (just after ConsoleFunctionGroupEnd( Packages );),
add:
ConsoleFunctionGroupBegin( Namespaces, "Functions relating to Namespaces.");
ConsoleFunction(dumpMethods, void, 2, 2, "dumpMethods(nameSpace)")
{
Namespace* ns = Namespace::find(StringTable->insert(argv[1]));
if (ns == NULL)
{
Con::errorf("dumpMethods(\"%s\") - unknown namespace.", argv[1]);
return;
}
ns->dumpMethods();
}
ConsoleFunctionGroupEnd( Namespaces );example output:
==>dumpMethods(aiplayer); 33 Methods from SimObject: addToAVPlayerNameList () - allowInstanceMethods () - obj.allowInstanceMethods() etc.. 10 Methods from NetObject: clearScopeToClient () - clearScopeToClient(%client)Undo the effects of a scopeToClient() call. getGhostID () - etc.. 33 Methods from SceneObject: getDCObject () - getForwardVector () - Returns a vector indicating the direction this object is facing. etc.. 2 Methods from GameBase: getDataBlock () - ()Return the datablock this GameBase is using. setDataBlock () - (DataBlock db)Assign this GameBase to use the specified datablock. etc.. 89 Methods from ShapeBase: applyDamage () - (float amt) applyImpulse () - (Point3F Pos, VectorF vel) etc.. 165 Methods from Player: addBuddy () - (id buddy) addIgnore () - (id ignore) etc.. 10 Methods from AIPlayer: clearAim () - ()Stop aiming at anything. getAimLocation () - ()Returns the point the AI is aiming at. etc..
note this can also be used to dump global functions which belong to a namespace.
eg, if:
function foo::bar()
{
// blah blah
}then:==>dumpmethods("foo");
Methods from foo:
bar ()orion elenzil 2008
About the author
#2
02/04/2008 (4:26 pm)
heheh
#3
02/08/2008 (12:39 pm)
hey bank, if you're watching this, i just made it a bit more useful.
#4
02/08/2008 (12:47 pm)
wow! this is more than a "bit more" useful :) ty for sharing!
#5
where it now additionally shows whether each method is a ScriptMethod or an EngineMethod.
11/17/2008 (1:04 pm)
added an improvement,where it now additionally shows whether each method is a ScriptMethod or an EngineMethod.
#6
02/03/2009 (3:00 pm)
a simple extension of this also yields SimObject::dumpNamespaces():[2/3/2009 14:58:34][Inf][General] ==>bixxy.dumpNamespaces(); [2/3/2009 14:58:34][Inf][General] 10294-AIPlayer-Bixxy-s-Bixxy [2/3/2009 14:58:34][Inf][General] 60 Methods from SimObject [2/3/2009 14:58:34][Inf][General] 10 Methods from NetObject [2/3/2009 14:58:34][Inf][General] 39 Methods from SceneObject [2/3/2009 14:58:34][Inf][General] 2 Methods from GameBase [2/3/2009 14:58:34][Inf][General] 112 Methods from ShapeBase [2/3/2009 14:58:34][Inf][General] 251 Methods from Player [2/3/2009 14:58:34][Inf][General] 48 Methods from AIPlayer

Associate Fyodor -bank- Osokin
Dedicated Logic