Game Development Community

New Return Types

by David Means · in Technical Issues · 01/07/2007 (11:25 am) · 2 replies

Hello all,

Here's my situation: I am implementing a modified version of the TinyXML/TorqueConsole interface script (here). Now, I need to return a handle on a found object in TorqueScript like so (not at all to do with books, but for example):

new xmlDoc(doc);

%book = doc.pushFirstChildElement("book");

However, as you can see in xmlDoc.cc, this method return a boolean value, and modifies the original calling object. So, %book will be a 1 or 0 based on if the function worked... not a handle on the actual object of TiXmlElement* and doc would be modified to be the pointer... thus throwing everything into chaos. A simplified example of the method is this:

ConsoleMethod(xmlDoc, getEl, bool, 3, 3, "Return not what I want!!!")
{
object = object->getEl( argv[2]);

return true;
}

I've worked through this (TDN -- Console Types), and can create a dataType that will compile:

consoleTypes.h
DefineConsoleType( TypeTiXmlElement )

consoleTypes.cc
//include tinyxml so that TiXmlElement is a recognizable type...
#include "xml/tinyxml.h"

...

//Other document stuff...

...

// TypeTiXmlElement
ConsoleType( TiXmlElement, TypeTiXmlElement, sizeof(TiXmlElement*) )

ConsoleSetType( TypeTiXmlElement )
{
   if(argc == 1)
   {
      TiXmlElement **obj = (TiXmlElement **)dptr;
      *obj = dynamic_cast<TiXmlElement*>(Sim::findObject(argv[0]));
   }
   else
      Con::printf("(TypeTiXmlElement) Cannot set multiple args to a single TiXmlElement.");
}

ConsoleGetType( TypeTiXmlElement )
{
   TiXmlElement **obj = (TiXmlElement**)dptr;
   char* returnBuffer = Con::getReturnBuffer(256);
   dSprintf(returnBuffer, 256, "%s", *obj ? (*obj)->getName() : "");
   return returnBuffer;
}

So all that will compile, but when I try to implement this in xmlDoc.cc....
TiXmlElement* xmlDoc::getEl(const char* rName)
{
   TiXmlElement* pElement;
   if(!m_paNode.empty())
   {
      const int iLastElement = m_paNode.size() - 1;
      TiXmlElement* pNode = m_paNode[iLastElement];

      pElement = pNode->FirstChildElement(rName);
   }
   else
      pElement = m_qDocument->FirstChildElement(rName);

   return pElement;
}

ConsoleMethod(xmlDoc, getEl, TypeTiXmlElement, 3, 3, "Get a handle on first element...")
{
   return object->getEl( argv[2] );
}

...I get compiler errors such as (fairly cropped, it was several pages :D):
<pathToTorque>\torque\sdk\engine\<myGame>\xmlDoc.cc(20) : error C2059: syntax error : ')'
<pathToTorque>\torque\sdk\engine\<myGame>\xmlDoc.cc(360) : error C2146: syntax error : missing ';' before identifier 'cxmlDocgetEl'
<pathToTorque>\torque\sdk\engine\<myGame>\xmlDoc.cc(360) : error C2433: 'TypeTiXmlElement' : 'inline' not permitted on data declarations
...
<pathToTorque>\torque\sdk\engine\<myGame>\xmlDoc.cc(360) : error C2146: syntax error : missing ';' before identifier 'cxmlDocgetElcaster'
<pathToTorque>\torque\sdk\engine\<myGame>\xmlDoc.cc(360) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
<pathToTorque>\torque\sdk\engine\<myGame>\xmlDoc.cc(360) : error C2086: 'S32 TypeTiXmlElement' : redefinition
...
<pathToTorque>\torque\sdk\engine\console\consoletypes.h(38) : see declaration of 'TypeTiXmlElement'
...
<pathToTorque>\torque\sdk\engine\<myGame>\xmlDoc.cc(362) : error C2440: 'return' : cannot convert from 'TiXmlElement *' to 'int'

However, all the declarations I have in my header files, and the actual usage in the cc files, do not have ints anywhere, they all return TiXmlElement* or TiXmlElement, the only thing that does differently is the ConsoleMethod as you can see above which uses the declared console-type of TypeTiXmlElement.

So, any thoughts? Any help would be greatly appreciated.

#1
01/07/2007 (11:42 am)
Alright, so I ran out of characters in that post, now for some specs:

A Compaq laptop with:

WinXP Home SP2 (I know, Evil Empire)

Torque SDK 1.4 (I know the console XML parser was for T2D, but it works in TGE)

Visual C++ 2005 Express Edition (more Evil Empire, but it's what my employer uses :P)

AMD Athlon 64 3200+ (2GHz)

1280 MiB Ram (1024 + 256)

I don't know think any of this is helpful (except which version of Torque and VC++), but thought I'd throw it out there just because it's sometimes helpful for some esoteric reason.
#2
01/07/2007 (5:15 pm)
Ok, I overlooked something (boneheaded mistake)... I still haven't solved my problems but I found something out. What do they say about assumptions?

They make an ASS out of U and ME

I assumed the TypeSimObjectPtr that was defined was based off and returning object handles... not so... it's based off S32

Here's the TypeSimObjectPtr that I ripped:
consoleTypes.cc
//////////////////////////////////////////////////////////////////////////
// TypeSimObjectPtr
//////////////////////////////////////////////////////////////////////////
ConsoleType( SimObjectPtr, TypeSimObjectPtr, sizeof(SimObject*) )

ConsoleSetType( TypeSimObjectPtr )
{
   if(argc == 1)
   {
      SimObject **obj = (SimObject **)dptr;
      *obj = Sim::findObject(argv[0]);
   }
   else
      Con::printf("(TypeSimObjectPtr) Cannot set multiple args to a single S32.");
}

ConsoleGetType( TypeSimObjectPtr )
{
   SimObject **obj = (SimObject**)dptr;
   char* returnBuffer = Con::getReturnBuffer(256);
   dSprintf(returnBuffer, 256, "%s", *obj ? (*obj)->getName() : "");
   return returnBuffer;
}

Here are the macro codes:
dynamicTypes.h
#define DefineConsoleType( type ) extern S32 type;

#define ConsoleType( typeName, type, size ) \
   class ConsoleType##type : public ConsoleBaseType \
   { \
   public: \
      ConsoleType##type (const S32 aSize, S32 *idPtr, const char *aTypeName) : ConsoleBaseType(aSize, idPtr, aTypeName) { } \
      virtual void setData(void *dptr, S32 argc, const char **argv, EnumTable *tbl, BitSet32 flag); \
      virtual const char *getData(void *dptr, EnumTable *tbl, BitSet32 flag ); \
      virtual const char *getTypeClassName() { return #typeName ; } \
   }; \
   S32 type = -1; \
   ConsoleType##type gConsoleType##type##Instance(size,&type,#type); \

#define ConsoleSetType( type ) \
   void ConsoleType##type::setData(void *dptr, S32 argc, const char **argv, EnumTable *tbl, BitSet32 flag)

#define ConsoleGetType( type ) \
   const char *ConsoleType##type::getData(void *dptr, EnumTable *tbl, BitSet32 flag )

Silly me... extern S32... it's an int. However... I know I can't just change the macro types and have it work, because it's dependent on other integer operations in the macro itself. Can anyone help?