Instantiating T2D datablocks in C++
by Tim Doty · in Torque Game Builder · 05/17/2005 (12:58 pm) · 10 replies
How do you instantiate T2D datablocks in C++? For example, how would you do the following TorqueScript in C++
Basically, one of my classes sets up an image datablock for use by others. I could subclass from fxImageMapDatablock2D and maybe that would just be the better way of doing things, but by my way of thinking this class does not have an "is a" relationship, but a "has a". It is already inheriting from my virtual object class which, to my way of thinking, is what it "is"
%imagemapdatablock = new fxImageMapDatablock2D(%imagemap) {
mode = full;
textureName = %imagepath;
};Basically, one of my classes sets up an image datablock for use by others. I could subclass from fxImageMapDatablock2D and maybe that would just be the better way of doing things, but by my way of thinking this class does not have an "is a" relationship, but a "has a". It is already inheriting from my virtual object class which, to my way of thinking, is what it "is"
About the author
#2
05/24/2005 (12:31 am)
I havent a clue. But I know that you can still do "new fxImageMapDatablock2D". Then you just call the funtions, set variables, ... Dont know how to get it found tho :P
#3
I guess what gets me is that:
1. The constructor takes no arguments
2. Class members are strewn about in no apparent order (public, private, public, private; struct, functions, vars, functions; etc.)
3. It looks to be essentially a C++ wrapper for standard C-style code (for example, data members are public instead of using accessor functions? Yes, there are some private data members with accessor functions but, for example, mIsPOT is public? So in principle you just set it to true/false POT?)
Admittedly fxImageMapDatablock isn't too bad, but SimObject just meanders (well commented, but...) and due to code interdependencies you can't work from just a piece (e.g., to do anything with fxImageMapDatablock2D you have to refer to SimObject (for inheritance) and ConObject (I'm assuming is the source of some macros) at the least -- not the end of the world, but I'm used to well-defined classes where you can at least utilize a class without understanding its whole inheritance tree.
I was hoping to spend time producing rather than deciphering -- and in the meantime I've redrawn all of the map graphics and designed new maps using them so I have been productive -- I'll just knuckle down and slog through source some more.
05/24/2005 (4:52 am)
Thing is there are no pretty much no "functions" for the class. There are some accessor functions for some private data members, (empty) constructor and destructor, two utility functions (init persistant fields, onAdd, (un)packdatastream) -- but nothing to deal with (peculiar to the) class functionality.I guess what gets me is that:
1. The constructor takes no arguments
2. Class members are strewn about in no apparent order (public, private, public, private; struct, functions, vars, functions; etc.)
3. It looks to be essentially a C++ wrapper for standard C-style code (for example, data members are public instead of using accessor functions? Yes, there are some private data members with accessor functions but, for example, mIsPOT is public? So in principle you just set it to true/false POT?)
Admittedly fxImageMapDatablock isn't too bad, but SimObject just meanders (well commented, but...) and due to code interdependencies you can't work from just a piece (e.g., to do anything with fxImageMapDatablock2D you have to refer to SimObject (for inheritance) and ConObject (I'm assuming is the source of some macros) at the least -- not the end of the world, but I'm used to well-defined classes where you can at least utilize a class without understanding its whole inheritance tree.
I was hoping to spend time producing rather than deciphering -- and in the meantime I've redrawn all of the map graphics and designed new maps using them so I have been productive -- I'll just knuckle down and slog through source some more.
#4
(past) Time to head to work... (argh)
05/24/2005 (5:22 am)
The answer appears to be:pImagemapDatablock = new fxImageMapDatablock2D();
pImagemapDatablock->mImageMode = getImageMode("FULL");
pImagemapDatablock->mTextureName = StringTable->insert("imagepath");(past) Time to head to work... (argh)
#5
Sorry no one came in to answer the question for ya. I hope we continue to get more talented C++ programmers here, so you guys can help each other out with questions like this more.
Your criticisms of the SimObject code has merit. For T2D, of course, we just inherit this from core Torque. It'd be a big project, considering all the dependencies, to re-factor SimObject. And it'd also be a hard one to do really well, as there are lots of trade-offs you'd need to think through. So, that's probably why no one has updated the code recently. Still, if someone wanted to give it a shot, it'd be cool to see. As you say though, at least it's well commented. ;)
Glad you are making some progress with your game. If you have more questions on the C++ side of things, I'll try to help answer them more in the future. And like I say, hopefully we'll get more good C++ guys around here too.
05/24/2005 (10:50 am)
Hi Tim,Sorry no one came in to answer the question for ya. I hope we continue to get more talented C++ programmers here, so you guys can help each other out with questions like this more.
Your criticisms of the SimObject code has merit. For T2D, of course, we just inherit this from core Torque. It'd be a big project, considering all the dependencies, to re-factor SimObject. And it'd also be a hard one to do really well, as there are lots of trade-offs you'd need to think through. So, that's probably why no one has updated the code recently. Still, if someone wanted to give it a shot, it'd be cool to see. As you say though, at least it's well commented. ;)
Glad you are making some progress with your game. If you have more questions on the C++ side of things, I'll try to help answer them more in the future. And like I say, hopefully we'll get more good C++ guys around here too.
#6
Since T2D I have dug into the scripting end, usually its a pull with me when I'm working on a resource since the majority of T2D users dont want to make C++ changes. I still plan on doing some heftier things in the C++ end so if you need any help just post it up again and most of the time I'll be able to help figure it out with you :) Finally have been getting closer to a good overall grasp on it (lol its a bit overwhelming, especially the physics end of it).
In fact one of the things I plan on working on in the C++ end (a slot based generation inventory front end) will probably use some of the same calls your figuring out now, "Instantiating T2D datablocks in C++". Hopefully my very basic initial C++ tutorial can turn into a set that builds up to that.
05/24/2005 (11:07 am)
Glad you figured it out Tim! lol I was following this and each post I wanted to dig in and help, though just couldn't squeeze the time in (been digging in the physics code to return a "collision depth" to help with all the great work Gary's been doing with integrating ODE, what seemed like it would be easy ended up being like finding a needle in a haystack, lol got to love tracing functions back and forth, though think I finally got an acceptable solution), glad you figured it out though. Since T2D I have dug into the scripting end, usually its a pull with me when I'm working on a resource since the majority of T2D users dont want to make C++ changes. I still plan on doing some heftier things in the C++ end so if you need any help just post it up again and most of the time I'll be able to help figure it out with you :) Finally have been getting closer to a good overall grasp on it (lol its a bit overwhelming, especially the physics end of it).
In fact one of the things I plan on working on in the C++ end (a slot based generation inventory front end) will probably use some of the same calls your figuring out now, "Instantiating T2D datablocks in C++". Hopefully my very basic initial C++ tutorial can turn into a set that builds up to that.
#7
@Matt: You're indefatiguable! But still and all there are only so many hours in a day. Whatever you're putting your time into is worthwhile and others will benefit -- I know I appreciate it.
One other niggle I forgot to mention: the includes. The following is I think a complete (neglecting only the name which wasn't really necessary for my code) summary of equivalency:
becomes
And, yes, not only do I like C++ I'm a fan of the STL.
edit: wasn't paying enough attention, the core/StringTable.h is apparently included through a chain of includes, although it is good to know where it is and why you are referring to it with the StringTable->insert() function. Nicely commented file ;^)
05/24/2005 (4:30 pm)
@Josh: Thanks for your comments. In one sense I don't mind trail blazing, but then again I'm having more fun when I'm producing, not deciphering ;^) For all I could complain about the structure of SimObject it is so well commented that I didn't have any real problem deriving classes from it.@Matt: You're indefatiguable! But still and all there are only so many hours in a day. Whatever you're putting your time into is worthwhile and others will benefit -- I know I appreciate it.
One other niggle I forgot to mention: the includes. The following is I think a complete (neglecting only the name which wasn't really necessary for my code) summary of equivalency:
%imagemapdatablock = new fxImageMapDatablock2D(%imagemap) {
mode = full;
textureName = %imagepath;
};becomes
#include "T2D/fxImageMapDatablock2D.h" #include <string> pImagemapDatablock = new fxImageMapDatablock2D(); pImagemapDatablock->mImageMode = fxImageMapDatablock2D::FX_IMAGEMODE_FULL; pImagemapDatablock->mTextureName = StringTable->insert(strImagePath.c_str());
And, yes, not only do I like C++ I'm a fan of the STL.
edit: wasn't paying enough attention, the core/StringTable.h is apparently included through a chain of includes, although it is good to know where it is and why you are referring to it with the StringTable->insert() function. Nicely commented file ;^)
#8
Or a better question is can I return a datablock from an exposed C++ function (using ConsoleMethod) in my simobject derivation?
I'm trying to figure out the best way to pass several variables from c++ back to script at once and I'm thinking the datablock is the way to do it.
07/10/2005 (1:34 pm)
Ok, so once you do that to create the datablock in C++ how do you go about inserting it into to the script so that your script can access it?Or a better question is can I return a datablock from an exposed C++ function (using ConsoleMethod) in my simobject derivation?
I'm trying to figure out the best way to pass several variables from c++ back to script at once and I'm thinking the datablock is the way to do it.
#9
In the header file:
1. inherit from existing class (e.g., class myClass: public simObject)
2. declare parent (e.g., typedef simObject Parent)
3. declare conobject (e.g., DECLARE_CONOBJECT(myClass))
In the implementation file:
1. implement conobject (e.g., IMPLEMENT_CONOBJECT(myClass))
2. implement a console method for each function to be exposed
One of the things I had to dig a bit to find was the valid return values for the ConsoleMethod -- it was documented where I would expect it. IIRC these are char *, F32, S32, bool and void. To use the char * it looks like T2D has some helper functions. I like using std::string but as that can't be directly returned without hacking the base engine code I prefer to simply use their methods:
Note that for ConsoleMethod the parameters are: class, TorqeScript function name, minimum parameters, maximum parameters and usage information. In the above "HP" is a data member of the baseObject class which is itself a class. "object" is a pointer to the class you are making a console method for, in this case baseObject.
While doing the class implementations I also saw the datablock declarations, I just don't have that right in front of me and need to get ready for work. It was a slightly different from the above.
I'm not saying a datablock isn't the way to do it, but you can certainly do it by simply using a string and returning the variables separated by spaces in it. If memory serves this is how fxVector2D() does it.
07/14/2005 (4:58 am)
Ryan: I never got an email about your post to this thread... I would pass variables the way T2D does, as strings. In the C++ side of things using sprintf to return the string. I haven't made datablocks in C++ yet, but the code looks to be very similar to the object. This is documented in the source code, but in essence boils down to:In the header file:
1. inherit from existing class (e.g., class myClass: public simObject)
2. declare parent (e.g., typedef simObject Parent)
3. declare conobject (e.g., DECLARE_CONOBJECT(myClass))
In the implementation file:
1. implement conobject (e.g., IMPLEMENT_CONOBJECT(myClass))
2. implement a console method for each function to be exposed
One of the things I had to dig a bit to find was the valid return values for the ConsoleMethod -- it was documented where I would expect it. IIRC these are char *, F32, S32, bool and void. To use the char * it looks like T2D has some helper functions. I like using std::string but as that can't be directly returned without hacking the base engine code I prefer to simply use their methods:
ConsoleMethod(baseObject, getHP, const char *, 2, 2, "() - Returns the object's hit points") {
HitPoints HP = object->getHP();
// Create Returnable Buffer.
char * pBuffer = Con::getReturnBuffer(256);
// Format Buffer.
dSprintf(pBuffer, 256, "%d %d %d",HP.getFunction(), HP.getRepair(), HP.getDamage());
return pBuffer;
}Note that for ConsoleMethod the parameters are: class, TorqeScript function name, minimum parameters, maximum parameters and usage information. In the above "HP" is a data member of the baseObject class which is itself a class. "object" is a pointer to the class you are making a console method for, in this case baseObject.
While doing the class implementations I also saw the datablock declarations, I just don't have that right in front of me and need to get ready for work. It was a slightly different from the above.
I'm not saying a datablock isn't the way to do it, but you can certainly do it by simply using a string and returning the variables separated by spaces in it. If memory serves this is how fxVector2D() does it.
#10
My next hurdle is instantiating scripted objects from the c++ side.
07/14/2005 (8:31 am)
Yeah, I had already figured out how I needed to do it. I also found out that datablocks hold static variables shared by all objects of the same class, so I don't want to use those anyway.My next hurdle is instantiating scripted objects from the c++ side.
Torque Owner Tim Doty