Loading arrays from datablocks?
by Josh Albrecht · in Torque Game Engine · 03/08/2002 (6:30 pm) · 9 replies
I am attempting to read initialize an array of Point3Fs in the PlayerData class in the function where everything is read from the datablock (unpackData). How do I load an unknown number of Point3F classes from the datablock, to the code? Same questions with strings instead of Point3Fs, but I bet the same idea applies.
I can get a single Point3F to load fine, but the array has my stumped. I would be VERY thankful for any help. :)
I can get a single Point3F to load fine, but the array has my stumped. I would be VERY thankful for any help. :)
#2
Point3F myPoints[ARRAY_SIZE];
You can define ARRAY_SIZE to whatever you want.
Then create the datablock field in initPersistFields(). For an array, it should look something like this:
The key is to add ARRAY_SIZE to the end to turn the field into an array.
Then in packData() you send the array to the client:
Then in unpackData() just receive the data the same way:
Don't worry about having to send a whole array since datablocks are sent only once and ARRAY_SIZE shouldn't have to be that big.
To send a string, just use writeString() and readString() instead of mathWrite(), mathRead(). (And use TypeString instead of TypePoint3F in the addField())
Also it would be a good idea to initialize your array first and fill it with zeros or something. Btw, I haven't really tested the above so I'm not sure if everything's correct.
03/08/2002 (8:51 pm)
First you need an array in your class such as:Point3F myPoints[ARRAY_SIZE];
You can define ARRAY_SIZE to whatever you want.
Then create the datablock field in initPersistFields(). For an array, it should look something like this:
addField("myPoints", TypePoint3F, Offset(myPoints, PlayerData), ARRAY_SIZE);The key is to add ARRAY_SIZE to the end to turn the field into an array.
Then in packData() you send the array to the client:
for (U32 i = 0; i < ARRAY_SIZE; i++) {
mathWrite(*stream, myPoints[i]);
}Then in unpackData() just receive the data the same way:
for (U32 i = 0; i < ARRAY_SIZE; i++) {
mathRead(*stream, &myPoints[i]);
}Don't worry about having to send a whole array since datablocks are sent only once and ARRAY_SIZE shouldn't have to be that big.
To send a string, just use writeString() and readString() instead of mathWrite(), mathRead(). (And use TypeString instead of TypePoint3F in the addField())
Also it would be a good idea to initialize your array first and fill it with zeros or something. Btw, I haven't really tested the above so I'm not sure if everything's correct.
#3
03/10/2002 (9:15 am)
Wow, that was EXACTLY what I needed! I didnt ever think about adding the array size to the function call. Thank you very much! :)
#4
03/10/2002 (11:35 am)
mathWrite and mathRead are not real functions... What did you mean?
#5
The function just sends the xyz of the point.
inline bool mathWrite(Stream& stream, const Point3F& p)
{
bool success = stream.write(p.x);
success &= stream.write(p.y);
success &= stream.write(p.z);
return success;
}
If you dont want to use mathwrite and mathread just replace it with normal stream->write/read in your packdata() unpackdata():
stream->write(myPoint[i].x);
stream->write(myPoint[i].y);
stream->write(myPoint[i].z);
stream->read(&myPoint[i].x);
stream->read(&myPoint[i].y);
stream->read(&myPoint[i].z);
03/10/2002 (1:13 pm)
mathread() and mathwrite() are in mathIO.h. Maybe the file needs to #include "math/mathIO.h" ?The function just sends the xyz of the point.
inline bool mathWrite(Stream& stream, const Point3F& p)
{
bool success = stream.write(p.x);
success &= stream.write(p.y);
success &= stream.write(p.z);
return success;
}
If you dont want to use mathwrite and mathread just replace it with normal stream->write/read in your packdata() unpackdata():
stream->write(myPoint[i].x);
stream->write(myPoint[i].y);
stream->write(myPoint[i].z);
stream->read(&myPoint[i].x);
stream->read(&myPoint[i].y);
stream->read(&myPoint[i].z);
#6
03/10/2002 (2:03 pm)
Ahh, I had thought they had all the read/write functions in bitstream. Thanks! :)
#7
What if I want the datablock to be able to contain any number between 0 and the maximum number of array elements? As it stands now, I loop through and load all 20. If there are not 20 defined in the datablock, then it just keeps reading, messing up the later variables. how can I ONLY load as many array elements as are defined in the function?
03/11/2002 (3:59 pm)
This still isnt over... :)What if I want the datablock to be able to contain any number between 0 and the maximum number of array elements? As it stands now, I loop through and load all 20. If there are not 20 defined in the datablock, then it just keeps reading, messing up the later variables. how can I ONLY load as many array elements as are defined in the function?
#8
in packdata()...
stream->write(numPoints);
for (i = 0; i < numPoints; numPoints++) {
mathWrite(*stream, myPoints[i]);
}
then unpack...
stream->read(&numPoints);
for (i = 0; i < numPoints; numPoints++) {
mathRead(*stream, &myPoints[i]);
}
where numPoints is just another field in your datablock that you have to set.
03/11/2002 (4:38 pm)
Well, if you initialize the array with zeros, then maybe can assume the data isn't used if the values = 0. Or just send the number of elements before you send the array like:in packdata()...
stream->write(numPoints);
for (i = 0; i < numPoints; numPoints++) {
mathWrite(*stream, myPoints[i]);
}
then unpack...
stream->read(&numPoints);
for (i = 0; i < numPoints; numPoints++) {
mathRead(*stream, &myPoints[i]);
}
where numPoints is just another field in your datablock that you have to set.
#9
03/11/2002 (4:57 pm)
That second suggestion would be best. Thank you. :)
Torque Owner Matt Webster
So an array of 5 integers might look like....
"1 3 5 6 8"
You'll have to parse that string into 5 different integers, and ther are functions given just for that purpose (look in script functions defined in the c++)