Game Development Community

How do I expose a field to scripting?

by Igor G · in Torque Game Engine · 03/30/2007 (2:32 pm) · 8 replies

I have a class with a Path* field and I want to expose this field to scripting.

So, inside initPersistFields, I make this call:

addField("path", TypeSimObjectPtr, Offset(m_Path, MyClass));

In my script, it's always 0, even though it's initialized in my code (with a m_Path = new Path()), so can anybody give me any help on how to expose this field to scripting?

Thanks.

#1
03/31/2007 (1:32 am)
You might want to post some code...

As far as I know you only need a few things to expose it to scripting.
1. You initialized it properly in the class constructor in your .cc file
2. You defined it right in the .h file
3. the addField command is used right in the initPersistFields
4. If you need to use it in the client code I think you need to add some stuff to the packupdate and unpackupdate functions in the .cc file, but i doubt that's the problem

Either there's a mistake in one of those or I don't know... maybe try initializing it in onAdd() instead of the constructor or something wacky like that...
#2
03/31/2007 (8:53 am)
I think due to my field being a pointer, there's some issues with that and scripting. Exposing fields of other variable types work fine.

So, I have a class X with a variable Path* p
I want this variable p to be exposed to scripting, so I call
addField("path", TypeSimObjectPtr, Offset(p, X)); inside X::initPersistFields.

I have a function X::CreatePath() that creates a path by doing p = new Path(); and this method is exposed to scripts.

Now, in my script, I make do:
%classx = new X();
%classx.CreatePath();

Now, when I do %classx.path, this is always "0".

After some experimentation, after doing p = new path(); I call p->registerObject(); and this seems to work.
I'm not sure why. Any ideas?

Also, should I do a if(p) delete p; in my class X destructor? because this seems to crash Torque when it exits...How am I supposed to cleanup the memory here?

Thanks.
#3
03/31/2007 (10:25 am)
Things to check:

Is your Path class derived from SimObject?

Is m_Path variable an instance of SimObjectPtr?

If you are using the TypeSimObjectPtr then m_Path should be defined like so:

SimObjectPtr<Path>  m_Path

and not just

Path *mPath;

Also after you call m_Path = new Path() are you calling m_Path->registerObject()?
#4
03/31/2007 (11:43 am)
Well, Path is a Torque defined class in sim/simPath, so it's not my class and should work fine.

I'll try doing SimObjectPtr m_Path instead of Path* mPath to see if that works.
#5
03/31/2007 (11:50 am)
What exactly does the registerObject() method do?
Does it register the object for scripts to access?
#6
03/31/2007 (11:56 am)
registerObject() registers the sim object with the simulation amongst other things. It basically lets the world know it exists and wants to be taken into account, etc. So any time that you create a SimObject derived class with new you are going to want to call registerObject() on it.
#7
03/31/2007 (7:53 pm)
@Neo: that's -slightly- misleading only because you are using the term you in the "you are going to want to call registerObject() on it".

The TorqueScript new operator takes care of all simulation registration (including the ::onAdd() script callback) automatically, so unless you are creating a new object in c++, you don't need to register it manually.


The main problem for the original poster is that you cannot expose a pointer to script as a field--it will cause all sorts of problems. You should name your paths or something similar, and if script needs to access them directly (as opposed to the controlling class), then implement console methods to do so.
#8
03/31/2007 (8:17 pm)
@Stephen:

Well he mentioned addField("path", TypeSimObjectPtr, Offset(m_Path, MyClass)); so I assumed he was talking about the C++ side of things.

A TypeSimObjectPtr handles setting/getting an actual pointer to a sim object by looking up its id when the the field value is set - that was what I was getting at (thus the questions about is it a SimObject, etc)

On reading the question again, it seems I was mistaken...

cheers
~neo