Game Development Community

Passing objects to C++ (or alternatives)

by baylor wetzel · in Torque Game Builder · 08/26/2009 (5:20 pm) · 3 replies

The short question: How does one pass an object from TorqueScript to C++ or vice-versa?


Details: i have some objects in C++, which handle non-visual things. i have objects in TorqueScript, which mostly handle drawing image maps. i want to pass objects back and forth but i'm not sure how. In past games, i could create C++ objects and pass ints back and forth, but i'm not sure about objects

Example:
My game is a dress-up game. The most important object is an article of clothing. It has two parts. In C++ is ArticleOfClothing, which has a hashtable filled with things needed for AI (it's a dress-up game with a ton of AI). Technically, those things are called InfluenceModifiers (basically, a hashtable of ints). In TorqueScript is ArticleOfClothingView, which holds a hashtable (sorta; i made it out of a SimSet) of ImageMaps. C++ also has an Ensemble, which is a hashtable of ArticleOfClothing objects plus some AI stuff. TorqueScript has Person (primarily responsible for drawing using ArticleOfClothingView objects), which has a variable of class Ensemble. There's also a bunch of enums (an earlier post explained about EnumTables, so hopefully i have that covered). The main interaction will be Person (TS) adding ArticleOfClothing objects (C++) to Ensemble (C++) and Person (TS) pulling InfluenceModifiers (C++) from Ensemble (C++)

Here's the interface for TorqueScript to call Ensemble:
//--- Ones with objects; the ones i don't know how to do
void addItem(ArticleOfClothing* piece)
ArticleOfClothing* getItem(ClothingType type)
int  getInfluence(vector<TypeOfSocialGroup> groups, InfluenceType influenceType)

//--- Ones with only ints, enums or void
bool hasItem(ClothingType type)
int  getInfluence(TypeOfSocialGroup group, InfluenceType influenceType)
void removeClothingLayer(ClothingType layer)
void strip()

My problem: i don't know how to pass, say, ArticleOfClothing*, to or from TorqueScript

i considered doing everything in C++, but then i'd have to keep all the ImageMaps in C++ and pass those to TorqueScript or handle all drawing to the scene in C++. i don't know how to do either so i don't know if that approach is easier or harder

Anyone know of a tutorial, sample code, etc. that could get me started or any advice for this particular problem?

#1
08/26/2009 (6:12 pm)
You will need to understand what type of object it is before passing from TS to C++, but the basic code goes like this:
t2dSceneObject *sceneObject;
if ( !Sim::findObject( argv[2], sceneObject ) )
{
    Con::warnf( "Unable to find object!" );
    return;
}
The example there is the "typical" use inside a ConsoleMethod or ConsoleFunction. The first parameter can either be an integer or a string. If it is a string, it will search for either the ID *or* the name of the object.

To pass back is really easy, you just need to return the ID of the object.
return ( sceneObject ) ? sceneObject->getId() : 0;
Again, that is coming from a ConsoleMethod or ConsoleFunction.
#2
08/26/2009 (6:20 pm)
Ugh, that was pretty yuck, here is a complete example:
ConsoleFunction( getObjectId, S32, 2, 2, "( SimObject )" )
{
    SimObject *myObject;
    if ( !Sim::findObject( argv[1], myObject ) )
    {
        Con::warnf( "Error!" );
        return 0;
    }

    return myObject->getId();
}

TorqueScript:
%testObject = new ScriptObject(MyObject);
echo( %testObject SPC getObjectId( %testObject ) SPC getObjectId( MyObject ) );
#3
08/26/2009 (10:58 pm)
TO clarify, you don't actually pass objects, you pass IDs of an object, correct?

If so, how does one turn an ID into an object?

Off the top of my head, i think i want to do something like this:

TorqueScript:
$person = new ScriptObject();
$person.ensemble = createEnsemble(); // global/console function that returns int ID?
%itemView = new ScriptObject();
%itemView.item = createItem(TYPE_HAT, "A fancy hat");
$person.ensemble.addItem(%itemView.item);

C++:
void Ensemble::addItem(ArticleOfClothing* piece)
{
    ClothingType type = piece->getType();
    clothes[type] = piece;  // clothes = map<type, article*>
}
ConsoleFunction(Ensemble, addItem, void, 3, 3, "" )
{
    S32 objectID = argv[2];
    ArticleOfClothing* item = dynamic_cast<ArticleOfClothing*>(
        Sim::findObject(objectID));
   
    object->addItem(item);
}

So i guess the trick to this is passing IDs rather than objects and knowing that the Sim::findObject call exists. Oh yeah, and i guess anything that goes through TS needs to inherit from SimObject

Thanks Phil!