Can't access C++ fields in script?
by Justin Tolchin · in Torque Game Engine · 05/10/2005 (10:04 am) · 9 replies
Sigh... well I must be doing something dumb but I can't tell what it is. I have a C++ class "RTSBuilding" exposed to the scripting engine and I have a field "mNumFloors" which I expose to the script engine as "numFloors" in initPersistFields. I only actually set the value of the mNumFloors field in C++, but I need to access it from script. For some reason, when I do a %building.dump() in the console the field shows up with the correct value, but when I try to print it out from the console as %building.numFloors it acts like it's an empty string (or some field it's never heard of). What am I doing wrong?
Here's the code I'm calling:
and here's the script output:
Why can't I access the numFloors field?
I feel like such a noob...
Here's the code I'm calling:
%building.dump();
echo("clientCmdBuildComplete called for building =" SPC %building);
echo("numFloors =" SPC %building.numFloors);and here's the script output:
Member Fields: dataBlock = "refineryBlock" elapsedTaskTime = "0" numFloors = "2" position = "-55.12 -77.2 400" requiresRallyPoint = "0" rotation = "1 0 0 0" RTSState = "Idle" scale = "1 1 1" Tagged Fields: Methods: addModifier() - ( RTSUnitModifierData modifier )Adds a modifier to this unit addtopathfinder() - adds a unit or building to the pathing terrain applyDamage() - (float amt) applyImpulse() - (Point3F Pos, VectorF vel) applyRepair() - (float amt) assignWeapon() - ... ... <whole bunch of methods here> ... clientCmdBuildComplete called for building = 1524 numFloors =
Why can't I access the numFloors field?
I feel like such a noob...
#2
BTW, I actually did end up writing a "getNumFloors()" console method as you suggested but that seems weird. :-)
On a semi-related note... if I have a field mapped to the scripting engine as described in the OP, and I update that field (in script) on a server-side object that is ghosted, is there a way to get it to update the client-side version of the object without writing a "setXXX" method which calls setMaskBits(someMask)?
05/10/2005 (12:18 pm)
Hmmm... okay, I know I'm being stupid here, but what is the point of initPersistFields then, if I can't get access to those mapped fields without a separate accessor? I've used mapped fields before so I don't know why this one is causing me grief. Is it because I'm trying to access the field on a ghosted object?BTW, I actually did end up writing a "getNumFloors()" console method as you suggested but that seems weird. :-)
On a semi-related note... if I have a field mapped to the scripting engine as described in the OP, and I update that field (in script) on a server-side object that is ghosted, is there a way to get it to update the client-side version of the object without writing a "setXXX" method which calls setMaskBits(someMask)?
#3
Just reading the field should work fine as long as you're access an object with the right values in it. I suspect you're accessing the server instance for your dump() above and the client instance for your access thereof. Compare object IDs for better info.
05/10/2005 (12:57 pm)
The point of initPersistFields is to let you modify C++ members of an object directly from script and the editors. The accessors are gonna let you do things like set the mask bits so things update properly.Just reading the field should work fine as long as you're access an object with the right values in it. I suspect you're accessing the server instance for your dump() above and the client instance for your access thereof. Compare object IDs for better info.
#4
I don't see how the engine can know what the numFloors field is during the "dump()" call and not know what it is 2 lines of script later.
05/10/2005 (3:49 pm)
@Ben: those 3 lines of script I listed above are all in the exact same function in that sequence. I added the "dump" call just to debug this problem. So it has to be the same object. That's why this doesn't make any sense to me. Here's the entire function up to the lines I listed...function clientCmdBuildComplete(%ghost)
{
%building = ServerConnection.resolveGhostID(%ghost);
if(!isObject(%building))
{
error("clientCmdBuildComplete - unable to resolve building ghost id!");
return;
}
%building.dump();
echo("clientCmdBuildComplete called for building =" SPC %building);
echo("numFloors =" SPC %building.numFloors);
...
...I don't see how the engine can know what the numFloors field is during the "dump()" call and not know what it is 2 lines of script later.
#5
05/10/2005 (7:23 pm)
What if you get it into an intermediate value, then use that intermediate variable in the printing process?
#6
%numFloors = %building.numFloors;
I tried doing that just now and when I echo it, %numFloors is still comes up as an empty string.
It's ok for now if I just use an accessor to get the value, but this is just one more weird little thing I don't understand (in what seems to be an ever-growing list). :-)
Edit: I just noticed that if I hardcode the value in the script:
%building.numFloors = 2;
then I can assign it over to %numFloors or just print it directly as %building.numFloors and it prints out fine. According to the dump it already had that value though, so I don't know why there's a difference in behavior.
05/11/2005 (9:19 am)
I assume you mean assigning it to a separate variable like this:%numFloors = %building.numFloors;
I tried doing that just now and when I echo it, %numFloors is still comes up as an empty string.
It's ok for now if I just use an accessor to get the value, but this is just one more weird little thing I don't understand (in what seems to be an ever-growing list). :-)
Edit: I just noticed that if I hardcode the value in the script:
%building.numFloors = 2;
then I can assign it over to %numFloors or just print it directly as %building.numFloors and it prints out fine. According to the dump it already had that value though, so I don't know why there's a difference in behavior.
#7
05/11/2005 (9:41 am)
This all makes me wonder... when you have a C++ class with some mapped fields, and you create an instance of that class in script, are there really two objects created, one in C++ and one in the script engine, and they communicate back and forth when a field gets updated? Or is there just one instance, and when the script engine needs a value it works directly on that object? I'm just wondering if somehow there's a "proxy" object in the script engine (there must be something that holds dynamic fields, right?) and there's some disconnect between them, since I'm only updating the mNumFloors field in C++. Does the script engine need some sort of "notification" that a mapped field changed? I'm just thinking maybe when you do a "dump" of an object, it reads the values off the C++ object, but when I try to print a field it's using a "cached" value (which in this case hasn't been updated yet).
#8
05/12/2005 (6:17 pm)
No, it's all working off the same objects. I suspect there's just something subtly wrong with where you're setting the field and how you're trying to read it off.
#9
I'm having the same one. A persistent field always returns an empty string on the ghosted object even though the corresponding c++ member has the correct value. It works fine when using a getter function but i'd prefer to avoid that. The field works as intended on the server side. The field isn't actually changed in script atm, just accessed (since I want to set an update mask). I was thinking that maybe i should use the setField() function instead of just manipulating the member in c++, but I got the same results with that.
Any ideas?
12/03/2006 (10:00 am)
Was there a solution to this problem?I'm having the same one. A persistent field always returns an empty string on the ghosted object even though the corresponding c++ member has the correct value. It works fine when using a getter function but i'd prefer to avoid that. The field works as intended on the server side. The field isn't actually changed in script atm, just accessed (since I want to set an update mask). I was thinking that maybe i should use the setField() function instead of just manipulating the member in c++, but I got the same results with that.
Any ideas?
Torque 3D Owner Stephen Zepp
Take a look at some of the ConsoleMethod implementations for the functions you see in .dump (look in the appropriate c++ file, most likely RTSUnit.cc/h for your particular reference), and figure out what they are doing, and then duplicate it.
If you need additional assistance, feel free to ask!