*** empty log message ***

This commit is contained in:
David Rose 2001-05-09 00:57:59 +00:00
parent bb81276fb2
commit 690b7776f4
88 changed files with 1043 additions and 1000 deletions

View File

@ -63,12 +63,10 @@ TypedWriteable* AnimBundle::
make_AnimBundle(const FactoryParams &params)
{
AnimBundle *me = new AnimBundle;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -77,12 +77,10 @@ TypedWriteable* AnimBundleNode::
make_AnimBundleNode(const FactoryParams &params)
{
AnimBundleNode *me = new AnimBundleNode;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -363,12 +363,10 @@ TypedWriteable* AnimChannelMatrixXfmTable::
make_AnimChannelMatrixXfmTable(const FactoryParams &params)
{
AnimChannelMatrixXfmTable *me = new AnimChannelMatrixXfmTable;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -307,12 +307,10 @@ TypedWriteable* AnimChannelScalarTable::
make_AnimChannelScalarTable(const FactoryParams &params)
{
AnimChannelScalarTable *me = new AnimChannelScalarTable;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -234,12 +234,10 @@ TypedWriteable* AnimGroup::
make_AnimGroup(const FactoryParams &params)
{
AnimGroup *me = new AnimGroup;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -126,12 +126,10 @@ TypedWriteable* MovingPartMatrix::
make_MovingPartMatrix(const FactoryParams &params)
{
MovingPartMatrix *me = new MovingPartMatrix;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -79,12 +79,10 @@ TypedWriteable* MovingPartScalar::
make_MovingPartScalar(const FactoryParams &params)
{
MovingPartScalar *me = new MovingPartScalar;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -404,12 +404,10 @@ TypedWriteable* PartBundle::
make_PartBundle(const FactoryParams &params)
{
PartBundle *me = new PartBundle;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
manager->register_finalize(me);
return me;

View File

@ -510,12 +510,10 @@ TypedWriteable* PartGroup::
make_PartGroup(const FactoryParams &params)
{
PartGroup *me = new PartGroup;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -470,12 +470,10 @@ TypedWriteable* Character::
make_Character(const FactoryParams &params)
{
Character *me = new Character;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -327,12 +327,10 @@ TypedWriteable* CharacterJoint::
make_CharacterJoint(const FactoryParams &params)
{
CharacterJoint *me = new CharacterJoint;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -41,12 +41,10 @@ TypedWriteable* CharacterJointBundle::
make_CharacterJointBundle(const FactoryParams &params)
{
CharacterJointBundle *me = new CharacterJointBundle;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
manager->register_finalize(me);
return me;

View File

@ -61,12 +61,10 @@ TypedWriteable* CharacterSlider::
make_CharacterSlider(const FactoryParams &params)
{
CharacterSlider *me = new CharacterSlider;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -407,12 +407,10 @@ TypedWriteable* ComputedVertices::
make_ComputedVertices(const FactoryParams &params)
{
ComputedVertices *me = new ComputedVertices;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -255,12 +255,10 @@ TypedWriteable* CollisionNode::
make_CollisionNode(const FactoryParams &params)
{
CollisionNode *me = new CollisionNode;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -285,12 +285,10 @@ TypedWriteable* CollisionPlane::
make_CollisionPlane(const FactoryParams &params)
{
CollisionPlane *me = new CollisionPlane;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -773,12 +773,10 @@ TypedWriteable* CollisionPolygon::
make_CollisionPolygon(const FactoryParams &params)
{
CollisionPolygon *me = new CollisionPolygon;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -370,12 +370,10 @@ write_datagram(BamWriter *manager, Datagram &me) {
TypedWriteable *CollisionSphere::
make_CollisionSphere(const FactoryParams &params) {
CollisionSphere *me = new CollisionSphere;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -115,12 +115,10 @@ write_datagram(BamWriter *manager, Datagram &me) {
TypedWriteable *GeomBinTransition::
make_GeomBinTransition(const FactoryParams &params) {
GeomBinTransition *me = new GeomBinTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -532,12 +532,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager)
TypedWriteable *LensFlareNode::
make_LensFlareNode(const FactoryParams &params) {
LensFlareNode *me = new LensFlareNode;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -14,7 +14,8 @@
clockObject.h config_express.cxx config_express.h datagram.I \
datagram.cxx datagram.h datagramGenerator.I datagramGenerator.cxx \
datagramGenerator.h datagramInputFile.I datagramInputFile.h \
datagramInputFile.cxx datagramIterator.cxx datagramIterator.h \
datagramInputFile.cxx datagramIterator.I \
datagramIterator.cxx datagramIterator.h \
datagramOutputFile.I datagramOutputFile.h datagramOutputFile.cxx \
datagramSink.I datagramSink.cxx datagramSink.h \
get_config_path.cxx get_config_path.h \
@ -38,7 +39,8 @@
bigEndian.I bigEndian.h buffer.I buffer.h circBuffer.I \
circBuffer.h clockObject.I clockObject.h config_express.h \
datagram.I datagram.h datagramInputFile.I datagramInputFile.h \
datagramIterator.h datagramOutputFile.I datagramOutputFile.h \
datagramIterator.I datagramIterator.h \
datagramOutputFile.I datagramOutputFile.h \
datagramSink.I datagramSink.h datagramGenerator.I \
datagramGenerator.h get_config_path.h \
hashVal.I hashVal.h \

View File

@ -0,0 +1,62 @@
// Filename: datagramIterator.I
// Created by: drose (08May01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: DatagramIterator::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE DatagramIterator::
DatagramIterator() :
_datagram((Datagram *)NULL),
_current_index(0)
{
}
////////////////////////////////////////////////////////////////////
// Function: DatagramIterator::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE DatagramIterator::
DatagramIterator(const Datagram &datagram, size_t offset) :
_datagram(&datagram),
_current_index(offset)
{
nassertv(_current_index <= _datagram->get_length());
}
////////////////////////////////////////////////////////////////////
// Function: DatagramIterator::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE DatagramIterator::
DatagramIterator(const DatagramIterator &copy) :
_datagram(copy._datagram),
_current_index(copy._current_index)
{
}
////////////////////////////////////////////////////////////////////
// Function: DatagramIterator::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void DatagramIterator::
operator = (const DatagramIterator &copy) {
_datagram = copy._datagram;
_current_index = copy._current_index;
}
////////////////////////////////////////////////////////////////////
// Function: DatagramIterator::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE DatagramIterator::
~DatagramIterator() {
}

View File

@ -8,19 +8,6 @@
#include <notify.h>
////////////////////////////////////////////////////////////////////
// Function: DatagramIterator::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
DatagramIterator::
DatagramIterator(const Datagram &datagram, size_t offset) :
_datagram(datagram),
_current_index(offset)
{
nassertv(_current_index <= _datagram.get_length());
}
// Various ways to get data and increment the iterator...
// Cut-and-paste-orama
@ -31,11 +18,12 @@ DatagramIterator(const Datagram &datagram, size_t offset) :
////////////////////////////////////////////////////////////////////
bool DatagramIterator::
get_bool() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_uint8 tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -51,11 +39,12 @@ get_bool() {
////////////////////////////////////////////////////////////////////
PN_int8 DatagramIterator::
get_int8() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_int8 tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -71,11 +60,12 @@ get_int8() {
////////////////////////////////////////////////////////////////////
PN_uint8 DatagramIterator::
get_uint8() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_uint8 tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -91,11 +81,12 @@ get_uint8() {
////////////////////////////////////////////////////////////////////
PN_int16 DatagramIterator::
get_int16() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_int16 tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -111,11 +102,12 @@ get_int16() {
////////////////////////////////////////////////////////////////////
PN_int32 DatagramIterator::
get_int32() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_int32 tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -131,11 +123,12 @@ get_int32() {
////////////////////////////////////////////////////////////////////
PN_int64 DatagramIterator::
get_int64() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_int64 tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -151,11 +144,12 @@ get_int64() {
////////////////////////////////////////////////////////////////////
PN_uint16 DatagramIterator::
get_uint16() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_uint16 tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -171,11 +165,12 @@ get_uint16() {
////////////////////////////////////////////////////////////////////
PN_uint32 DatagramIterator::
get_uint32() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_uint32 tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -191,11 +186,12 @@ get_uint32() {
////////////////////////////////////////////////////////////////////
PN_uint64 DatagramIterator::
get_uint64() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_uint64 tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -218,11 +214,12 @@ get_float32() {
// architectures we are concerned with. If we come across one that
// is different, we will have to convert.
nassertr(sizeof(float) == 4, 0.0);
nassertr(_current_index < _datagram.get_length(), 0.0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0.0);
float tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0.0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -238,11 +235,12 @@ get_float32() {
////////////////////////////////////////////////////////////////////
PN_float64 DatagramIterator::
get_float64() {
nassertr(_current_index < _datagram.get_length(), 0.0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0.0);
PN_float64 tempvar;
LittleEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0.0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -258,11 +256,12 @@ get_float64() {
////////////////////////////////////////////////////////////////////
PN_int16 DatagramIterator::
get_be_int16() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_int16 tempvar;
BigEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -278,11 +277,12 @@ get_be_int16() {
////////////////////////////////////////////////////////////////////
PN_int32 DatagramIterator::
get_be_int32() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_int32 tempvar;
BigEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -298,11 +298,12 @@ get_be_int32() {
////////////////////////////////////////////////////////////////////
PN_int64 DatagramIterator::
get_be_int64() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_int64 tempvar;
BigEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -318,11 +319,12 @@ get_be_int64() {
////////////////////////////////////////////////////////////////////
PN_uint16 DatagramIterator::
get_be_uint16() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_uint16 tempvar;
BigEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -338,11 +340,12 @@ get_be_uint16() {
////////////////////////////////////////////////////////////////////
PN_uint32 DatagramIterator::
get_be_uint32() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_uint32 tempvar;
BigEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -358,11 +361,12 @@ get_be_uint32() {
////////////////////////////////////////////////////////////////////
PN_uint64 DatagramIterator::
get_be_uint64() {
nassertr(_current_index < _datagram.get_length(), 0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0);
PN_uint64 tempvar;
BigEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -385,11 +389,12 @@ get_be_float32() {
// architectures we are concerned with. If we come across one that
// is different, we will have to convert.
nassertr(sizeof(float) == 4, 0.0);
nassertr(_current_index < _datagram.get_length(), 0.0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0.0);
float tempvar;
BigEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0.0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -405,11 +410,12 @@ get_be_float32() {
////////////////////////////////////////////////////////////////////
PN_float64 DatagramIterator::
get_be_float64() {
nassertr(_current_index < _datagram.get_length(), 0.0);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index < _datagram->get_length(), 0.0);
PN_float64 tempvar;
BigEndian s =
_datagram.get_message().substr(_current_index, sizeof(tempvar));
_datagram->get_message().substr(_current_index, sizeof(tempvar));
nassertr(s.length() == sizeof(tempvar), 0.0);
memcpy((void *)&tempvar, (void *)s.data(), sizeof(tempvar));
@ -428,10 +434,11 @@ get_string() {
// First, get the length of the string
PN_uint16 s_len = get_uint16();
nassertr(_current_index + s_len <= _datagram.get_length(), "");
nassertr(_datagram != (const Datagram *)NULL &&
_current_index + s_len <= _datagram->get_length(), "");
string s =
_datagram.get_message().substr(_current_index, s_len);
_datagram->get_message().substr(_current_index, s_len);
nassertr(s.length() == s_len, "");
_current_index += s_len;
@ -448,10 +455,11 @@ get_string() {
////////////////////////////////////////////////////////////////////
string DatagramIterator::
get_fixed_string(size_t size) {
nassertr(_current_index + size <= _datagram.get_length(), "");
nassertr(_datagram != (const Datagram *)NULL &&
_current_index + size <= _datagram->get_length(), "");
string s =
_datagram.get_message().substr(_current_index, size);
_datagram->get_message().substr(_current_index, size);
_current_index += size;
size_t zero_byte = s.find('\0');
@ -467,7 +475,7 @@ get_fixed_string(size_t size) {
void DatagramIterator::
skip_bytes(size_t size) {
nassertv((int)size >= 0);
nassertv(_current_index + size <= _datagram.get_length());
nassertv(_current_index + size <= _datagram->get_length());
_current_index += size;
}
@ -480,11 +488,12 @@ skip_bytes(size_t size) {
string DatagramIterator::
extract_bytes(size_t size) {
nassertr((int)size >= 0, "");
nassertr(_current_index + size <= _datagram.get_length(), "");
nassertr(_datagram != (const Datagram *)NULL &&
_current_index + size <= _datagram->get_length(), "");
int start = _current_index;
_current_index += size;
return _datagram.get_message().substr(start, size);
return _datagram->get_message().substr(start, size);
}
////////////////////////////////////////////////////////////////////
@ -495,8 +504,9 @@ extract_bytes(size_t size) {
////////////////////////////////////////////////////////////////////
string DatagramIterator::
get_remaining_bytes() const {
nassertr(_current_index <= _datagram.get_length(), "");
return _datagram.get_message().substr(_current_index);
nassertr(_datagram != (const Datagram *)NULL &&
_current_index <= _datagram->get_length(), "");
return _datagram->get_message().substr(_current_index);
}
////////////////////////////////////////////////////////////////////
@ -506,7 +516,7 @@ get_remaining_bytes() const {
////////////////////////////////////////////////////////////////////
int DatagramIterator::
get_remaining_size() const {
return _datagram.get_length() - _current_index;
return _datagram->get_length() - _current_index;
}
////////////////////////////////////////////////////////////////////
@ -516,7 +526,7 @@ get_remaining_size() const {
////////////////////////////////////////////////////////////////////
const Datagram &DatagramIterator::
get_datagram() const {
return _datagram;
return *_datagram;
}
////////////////////////////////////////////////////////////////////

View File

@ -19,7 +19,11 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEXPRESS DatagramIterator {
PUBLISHED:
DatagramIterator(const Datagram &datagram, size_t offset = 0);
INLINE DatagramIterator();
INLINE DatagramIterator(const Datagram &datagram, size_t offset = 0);
INLINE DatagramIterator(const DatagramIterator &copy);
INLINE void operator = (const DatagramIterator &copy);
INLINE ~DatagramIterator();
bool get_bool();
PN_int8 get_int8();
@ -56,9 +60,10 @@ PUBLISHED:
size_t get_current_index() const;
private:
const Datagram &_datagram;
const Datagram *_datagram;
size_t _current_index;
};
#include "datagramIterator.I"
#endif

View File

@ -60,12 +60,10 @@ write_datagram(BamWriter *manager, Datagram &me)
TypedWriteable* GeomLine::
make_GeomLine(const FactoryParams &params) {
GeomLine *me = new GeomLine;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
me->make_dirty();
me->config();

View File

@ -72,12 +72,10 @@ write_datagram(BamWriter *manager, Datagram &me) {
TypedWriteable* GeomLinestrip::
make_GeomLinestrip(const FactoryParams &params) {
GeomLinestrip *me = new GeomLinestrip;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
me->make_dirty();
me->config();

View File

@ -68,12 +68,10 @@ write_datagram(BamWriter *manager, Datagram &me) {
TypedWriteable* GeomPoint::
make_GeomPoint(const FactoryParams &params) {
GeomPoint *me = new GeomPoint;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
me->make_dirty();
me->config();

View File

@ -56,12 +56,10 @@ draw_immediate(GraphicsStateGuardianBase *gsg) const {
TypedWriteable* GeomPolygon::
make_GeomPolygon(const FactoryParams &params) {
GeomPolygon *me = new GeomPolygon;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
me->make_dirty();
me->config();

View File

@ -107,12 +107,10 @@ get_tris() const {
TypedWriteable* GeomQuad::
make_GeomQuad(const FactoryParams &params) {
GeomQuad *me = new GeomQuad;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
me->make_dirty();
me->config();

View File

@ -40,13 +40,13 @@ TypedWriteable* GeomSphere::
make_GeomSphere(const FactoryParams &params)
{
GeomSphere *me = new GeomSphere;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
me->make_dirty();
me->config();
return me;
}

View File

@ -91,12 +91,10 @@ write_datagram(BamWriter *manager, Datagram &me) {
TypedWriteable* GeomSprite::
make_GeomSprite(const FactoryParams &params) {
GeomSprite *me = new GeomSprite;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
me->make_dirty();
me->config();

View File

@ -221,12 +221,10 @@ get_tris() const {
TypedWriteable* GeomTri::
make_GeomTri(const FactoryParams &params) {
GeomTri *me = new GeomTri;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
me->make_dirty();
me->config();

View File

@ -385,12 +385,10 @@ get_tris() const {
TypedWriteable* GeomTrifan::
make_GeomTrifan(const FactoryParams &params) {
GeomTrifan *me = new GeomTrifan;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
me->make_dirty();
me->config();

View File

@ -496,12 +496,10 @@ get_tris() const {
TypedWriteable* GeomTristrip::
make_GeomTristrip(const FactoryParams &params) {
GeomTristrip *me = new GeomTristrip;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
me->make_dirty();
me->config();

View File

@ -157,12 +157,10 @@ write_datagram(BamWriter *manager, Datagram &me) {
TypedWriteable *Material::
make_Material(const FactoryParams &params) {
Material *me = new Material;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -500,11 +500,10 @@ make_Texture(const FactoryParams &params)
//be done through calls to TexturePool, which ensures
//that any loads of the same Texture, refer to the
//same memory
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
string name = scan.get_string();
string alpha_name = scan.get_string();

View File

@ -61,12 +61,10 @@ TypedWriteable* NamedNode::
make_NamedNode(const FactoryParams &params)
{
NamedNode *me = new NamedNode;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -78,6 +78,7 @@ Node::
DownRelationPointers::iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *arc = (*drpi);
nassertv(arc != (NodeRelation *)NULL);
// This deletes the arc and anything below it through the magic
// of reference-counting.
@ -504,12 +505,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable* Node::
make_Node(const FactoryParams &params) {
Node *me = new Node;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -944,12 +944,10 @@ TypedWriteable* NodeRelation::
make_NodeRelation(const FactoryParams &params)
{
NodeRelation *me = new NodeRelation(get_class_type());
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -84,10 +84,8 @@ open_read(const Filename &filename, bool report_errors) {
// Access: Public
// Description: Reads and returns the next object from the Bam file,
// or NULL if the end of the file has been reached, or
// if there is an error condition.
//
// Note that there is presently no way to differentiate
// a normal end-of-file from an error.
// if there is an error condition. Use is_eof() to
// differentiate these two cases.
//
// The pointers returned by this method will not be
// valid for use until resolve() is subsequently called.
@ -101,6 +99,18 @@ read_object() {
return _reader->read_object();
}
////////////////////////////////////////////////////////////////////
// Function: BamFile::is_eof
// Access: Public
// Description: Returns true if the reader has reached end-of-file,
// false otherwise. This call is only valid after a
// call to read_object().
////////////////////////////////////////////////////////////////////
bool BamFile::
is_eof() const {
return _reader != (BamReader *)NULL && _reader->is_eof();
}
////////////////////////////////////////////////////////////////////
// Function: BamFile::resolve
// Access: Public
@ -108,8 +118,9 @@ read_object() {
// been read via calls to read_object() in order to
// resolve all internal pointer references in the
// objects read and make all the pointers valid. It
// returns true if successful, false if there is some
// error.
// returns true if all objects are successfully
// resolved, or false if some have not been (in which
// case you must call resolve() again later).
////////////////////////////////////////////////////////////////////
bool BamFile::
resolve() {

View File

@ -19,7 +19,17 @@ class Filename;
////////////////////////////////////////////////////////////////////
// Class : BamFile
// Description : The principle public interface to reading and writing
// Bam disk files.
// Bam disk files. See also BamReader and BamWriter,
// the more general implementation of this class.
//
// Bam files are most often used to store scene graphs
// or subgraphs, and by convention they are given
// filenames ending in the extension ".bam" when they
// are used for this purpose. However, a Bam file may
// store any arbitrary list of TypedWriteable objects;
// in this more general usage, they are given filenames
// ending in ".boo" to differentiate them from the more
// common scene graph files.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA BamFile {
public:
@ -28,6 +38,7 @@ public:
bool open_read(const Filename &filename, bool report_errors = true);
TypedWriteable *read_object();
bool is_eof() const;
bool resolve();
bool open_write(const Filename &filename, bool report_errors = true);

View File

@ -89,14 +89,21 @@ load_file(const Filename &path, bool report_errors) const
result = DCAST(Node, object);
if (report_errors) {
if (bam_file.read_object() != TypedWriteable::Null) {
bam_file.read_object();
if (!bam_file.is_eof()) {
loader_cat.warning()
<< "Ignoring extra objects in " << path << "\n";
}
}
}
bam_file.resolve();
if (!bam_file.resolve()) {
if (report_errors) {
loader_cat.error()
<< "Unable to resolve Bam file.\n";
result = (Node *)NULL;
}
}
return result;
}

View File

@ -556,12 +556,10 @@ register_with_read_factory() {
TypedWriteable *ClassicNurbsCurve::
make_ClassicNurbsCurve(const FactoryParams &params) {
ClassicNurbsCurve *me = new ClassicNurbsCurve;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -563,12 +563,10 @@ register_with_read_factory() {
TypedWriteable *CubicCurveseg::
make_CubicCurveseg(const FactoryParams &params) {
CubicCurveseg *me = new CubicCurveseg;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -914,12 +914,10 @@ register_with_read_factory() {
TypedWriteable *HermiteCurve::
make_HermiteCurve(const FactoryParams &params) {
HermiteCurve *me = new HermiteCurve;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -2,30 +2,65 @@
// Created by: jason (12Jun00)
//
#include <algorithm>
////////////////////////////////////////////////////////////////////
// Function: BamReader::Constructor
// Function: BamReader::is_eof
// Access: Public
// Description:
// Description: Returns true if the reader has reached end-of-file,
// false otherwise. This call is only valid after a
// call to read_object().
////////////////////////////////////////////////////////////////////
INLINE BamReader::
BamReader(DatagramGenerator *generator)
: _source(generator)
{
INLINE bool BamReader::
is_eof() const {
return _source->is_eof();
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::get_file_major_ver
// Access: Public
// Description: Returns the major version number of the Bam file
// currently being read.
////////////////////////////////////////////////////////////////////
INLINE int BamReader::
get_file_major_ver() const {
return _file_major;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::create_factory
// Access: Private, Static
// Description: Creates a new WriteableFactory for generating
// TypedWriteable objects
// Function: BamReader::get_file_minor_ver
// Access: Public
// Description: Returns the minor version number of the Bam file
// currently being read.
////////////////////////////////////////////////////////////////////
INLINE void BamReader::
create_factory(void)
{
_factory = new WriteableFactory;
INLINE int BamReader::
get_file_minor_ver() const {
return _file_minor;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::get_current_major_ver
// Access: Public
// Description: Returns the major version number of Bam files
// supported by the current code base. This must match
// get_file_major_ver() in order to successfully read a
// file.
////////////////////////////////////////////////////////////////////
INLINE int BamReader::
get_current_major_ver() const {
return _cur_major;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::get_current_minor_ver
// Access: Public
// Description: Returns the minor version number of Bam files
// supported by the current code base. This must match
// or exceed get_file_minor_ver() in order to
// successfully read a file.
////////////////////////////////////////////////////////////////////
INLINE int BamReader::
get_current_minor_ver() const {
return _cur_minor;
}
////////////////////////////////////////////////////////////////////
@ -35,78 +70,21 @@ create_factory(void)
// TypedWriteable objects
////////////////////////////////////////////////////////////////////
INLINE WriteableFactory* BamReader::
get_factory(void)
{
get_factory() {
if (_factory == NullFactory)
create_factory();
return _factory;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::get_file_major_ver
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int BamReader::
get_file_major_ver(void)
{
return _file_major;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::get_file_minor_ver
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int BamReader::
get_file_minor_ver(void)
{
return _file_minor;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::get_current_major_ver
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int BamReader::
get_current_major_ver(void)
{
return _cur_major;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::get_current_minor_ver
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int BamReader::
get_current_minor_ver(void)
{
return _cur_minor;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::queue
// Access: Private
// Description: queues the objId of the object needing to be created
// Function: BamReader::create_factory
// Access: Private, Static
// Description: Creates a new WriteableFactory for generating
// TypedWriteable objects
////////////////////////////////////////////////////////////////////
INLINE void BamReader::
queue(PN_uint16 objId)
{
if (!binary_search(_deferred_reads.begin(), _deferred_reads.end(), objId))
_deferred_reads.push_back(objId);
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::clear_queue
// Access: Private
// Description: Clears all pending object reads
////////////////////////////////////////////////////////////////////
INLINE void BamReader::
clear_queue(void)
{
_deferred_reads.clear();
create_factory() {
_factory = new WriteableFactory;
}
////////////////////////////////////////////////////////////////////
@ -119,15 +97,10 @@ clear_queue(void)
// managing BamReader object
////////////////////////////////////////////////////////////////////
INLINE void
parse_params(const FactoryParams &params, BamReader* &manager, Datagram &packet)
{
WriteableParam *datagram_param = DCAST(WriteableParam, params.get_param(0));
BamReaderParam *manager_param = DCAST(BamReaderParam, params.get_param(1));
parse_params(const FactoryParams &params,
DatagramIterator &scan, BamReader *&manager) {
BamReaderParam *param = DCAST(BamReaderParam, params.get_param(0));
Datagram temp_packet = datagram_param->get_datagram();
DatagramIterator scan(temp_packet);
string mesg = scan.get_remaining_bytes();
packet.append_data(mesg.data(), mesg.size());
manager = manager_param->get_manager();
scan = param->get_iterator();
manager = param->get_manager();
}

View File

@ -11,45 +11,50 @@
#include "config_util.h"
WriteableFactory *BamReader::_factory = (WriteableFactory*)0L;
BamReader* const BamReader::Null = (BamReader*)0L;
WriteableFactory* const BamReader::NullFactory = (WriteableFactory*)0L;
BamReader *const BamReader::Null = (BamReader*)0L;
WriteableFactory *const BamReader::NullFactory = (WriteableFactory*)0L;
const int BamReader::_cur_major = _bam_major_ver;
const int BamReader::_cur_minor = _bam_minor_ver;
////////////////////////////////////////////////////////////////////
// Function: BamReader::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
BamReader::
BamReader(DatagramGenerator *generator)
: _source(generator)
{
_num_extra_objects = 0;
_pta_id = -1;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
BamReader::
~BamReader(void)
{
~BamReader() {
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::init
// Access: Public
// Description: Does all initialization necessary for BamReader to work
// Current this means reading in the Type Map stored as
// the header of the file. This TypeMap contains the
// name of all types written out and their type indeces
// as set when the file was created. This map is used
// for later determing the current TypeHandle for each
// object written. Each Object is identified in the file
// with the old index for space reason.
// Description: Initializes the BamReader prior to reading any
// objects from its source.
//
// This returns true if the BamReader successfully
// initialized, false otherwise.
////////////////////////////////////////////////////////////////////
bool BamReader::
init(void)
{
init() {
Datagram header;
if (_source->is_error())
{
if (_source->is_error()) {
return false;
}
@ -66,8 +71,7 @@ init(void)
// If the major version is different, or the minor version is
// *newer*, we can't safely load the file.
if (_file_major != _bam_major_ver || _file_minor > _bam_minor_ver)
{
if (_file_major != _bam_major_ver || _file_minor > _bam_minor_ver) {
bam_cat.error()
<< "Bam file is version " << _file_major << "." << _file_minor
<< ".\n";
@ -103,189 +107,264 @@ init(void)
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::read_handle
// Function: BamReader::read_object
// Access: Public
// Description: Reads a TypeHandle out of the Datagram. If the Type
// has not been registered yet, BamReader will register
// the Type with TypeRegistry
// Description: Reads a single object from the Bam file. If the
// object type is known, a new object of the appropriate
// type is created and returned; otherwise, NULL is
// returned. NULL is also returned when the end of the
// file is reached. is_eof() may be called to
// differentiate between these two cases.
//
// This may be called repeatedly to extract out all the
// objects in the Bam file, but typically (especially
// for scene graph files, indicated with the .bam
// extension), only one object is retrieved directly
// from the Bam file: the root of the scene graph. The
// remaining objects will all be retrieved recursively
// by the first object.
//
// Note that the object returned may not yet be
// complete. In particular, some of its pointers may
// not be filled in; you must call resolve() to fill in
// all the available pointers before you can safely use
// any objects returned by read_object().
////////////////////////////////////////////////////////////////////
TypeHandle BamReader::
read_handle(DatagramIterator& scan)
{
int id = scan.get_uint16();
if (id == 0)
{
//This indicates an object that should have already been read in,
//so return TypeHandle::none() to indicate this.
TypedWriteable *BamReader::
read_object() {
nassertr(_num_extra_objects == 0, (TypedWriteable *)NULL);
// First, read the base object.
int object_id = p_read_object();
// Now that object might have included some pointers to other
// objects, which may still need to be read. And those objects
// might in turn require reading additional objects. Read all the
// remaining objects.
while (_num_extra_objects > 0) {
p_read_object();
_num_extra_objects--;
}
// Now look up the pointer of the object we read first. It should
// be available now.
if (object_id == 0) {
#ifndef NDEBUG
if (bam_cat.is_spam()) {
bam_cat.spam()
<< "Reading previously read TypeHandle.\n";
<< "Returning NULL\n";
}
#endif
return (TypedWriteable *)NULL;
}
CreatedObjs::iterator oi = _created_objs.find(object_id);
if (oi == _created_objs.end()) {
bam_cat.error()
<< "Undefined object encountered!\n";
return (TypedWriteable *)NULL;
} else {
TypedWriteable *object = (*oi).second;
#ifndef NDEBUG
if (bam_cat.is_spam()) {
if (object != (TypedWriteable *)NULL) {
bam_cat.spam()
<< "Returning object of type " << object->get_type() << "\n";
}
}
#endif
return object;
}
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::resolve
// Access: Public
// Description: This may be called at any time during processing of
// the Bam file to resolve all the known pointers so
// far. It is usually called at the end of the
// processing, after all objects have been read, which
// is generally the best time to call it.
//
// This must be called at least once after reading a
// particular object via get_object() in order to
// validate that object.
//
// The return value is true if all objects have been
// resolved, or false if some objects are still
// outstanding (in which case you will need to call
// resolve() again later).
////////////////////////////////////////////////////////////////////
bool BamReader::
resolve() {
bool all_completed = true;
// Walk through all the objects that still have outstanding pointers.
Requests::iterator ri;
ri = _deferred_pointers.begin();
while (ri != _deferred_pointers.end()) {
TypedWriteable *whom = (*ri).first;
const vector_ushort &pointers = (*ri).second;
// Now make sure we have all of the pointers this object is
// waiting for. If any of the pointers has not yet been read in,
// we can't resolve this object--we can't do anything for a given
// object until we have *all* outstanding pointers for that
// object.
bool is_complete = true;
vector_typedWriteable references;
vector_ushort::const_iterator pi;
for (pi = pointers.begin(); pi != pointers.end() && is_complete; ++pi) {
int object_id = (*pi);
if (object_id == 0) {
// A NULL pointer is a NULL pointer.
references.push_back((TypedWriteable *)NULL);
} else {
// See if we have the pointer available now.
CreatedObjs::const_iterator oi = _created_objs.find(object_id);
if (oi == _created_objs.end()) {
// No, too bad.
is_complete = false;
} else {
// Yes, it's ready.
references.push_back((*oi).second);
}
}
}
if (is_complete) {
// Okay, here's the complete list of pointers for you!
whom->complete_pointers(references, this);
// Now remove this object from the list of things that need
// completion. We have to be a bit careful when deleting things
// from the STL container while we are traversing it.
Requests::iterator old = ri;
++ri;
_deferred_pointers.erase(old);
} else {
// Couldn't complete this object yet; it'll wait for next time.
bam_cat.warning()
<< "Unable to complete " << whom->get_type() << "\n";
++ri;
all_completed = false;
}
}
if (all_completed) {
finalize();
}
return all_completed;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::read_handle
// Access: Public
// Description: Reads a TypeHandle out of the Datagram.
////////////////////////////////////////////////////////////////////
TypeHandle BamReader::
read_handle(DatagramIterator &scan) {
// We encode TypeHandles within the Bam file by writing a unique
// index number for each one to the file. When we write a
// particular TypeHandle for the first type, we assign it a new
// index number and then immediately follow it by its definition;
// when we write the same TypeHandle on subsequent times we only
// write the index number.
// Thus, to read a TypeHandle, we first read the index number. If
// it is a number we have not yet encountered, we must then read the
// definition.
// Here's the index number.
int id = scan.get_uint16();
if (id == 0) {
// Index number 0 is always, by convention, TypeHandle::none().
// This indicates an object that should have already been read in,
// so return TypeHandle::none() to indicate this.
#ifndef NDEBUG
if (bam_cat.is_spam()) {
bam_cat.spam()
<< "Read TypeHandle::none().\n";
}
#endif
return TypeHandle::none();
}
if (_index_map.find(id) == _index_map.end())
{
//Have not loaded this type before
string name = scan.get_string();
TypeHandle type = TypeRegistry::ptr()->find_type(name);
bool new_type = false;
if (type == TypeHandle::none())
{
//This is a new type we've never heard of before so register it
//with the type registry
type = TypeRegistry::ptr()->register_dynamic_type(name);
bam_cat.warning()
<< "Bam file contains objects of unknown type: " << type << "\n";
new_type = true;
}
_index_map[id] = type;
IndexMap::const_iterator mi = _index_map.find(id);
if (mi != _index_map.end()) {
// We've encountered this index number before, so there should be
// no type definition following the id. Simply return the
// TypeHandle we previously associated with the id.
TypeHandle type = (*mi).second;
// Now pick up the derivation information.
int num_parent_classes = scan.get_uint8();
for (int i = 0; i < num_parent_classes; i++) {
TypeHandle parent_type = read_handle(scan);
if (new_type) {
TypeRegistry::ptr()->record_derivation(type, parent_type);
} else {
if (type.get_parent_towards(parent_type) != parent_type) {
bam_cat.warning()
<< "Bam file indicates a derivation of " << type
<< " from " << parent_type << " which is no longer true.\n";
}
#ifndef NDEBUG
if (bam_cat.is_spam()) {
bam_cat.spam()
<< "Read TypeHandle for " << type << ".\n";
}
#endif
return type;
}
// We haven't encountered this index number before. This means it
// will be immediately followed by the type definition. This
// consists of the string name, followed by the list of parent
// TypeHandles for this type.
string name = scan.get_string();
bool new_type = false;
TypeHandle type = TypeRegistry::ptr()->find_type(name);
if (type == TypeHandle::none()) {
// We've never heard of this type before! This is really an error
// condition, but we'll do the best we can and declare it
// on-the-fly.
type = TypeRegistry::ptr()->register_dynamic_type(name);
bam_cat.warning()
<< "Bam file contains objects of unknown type: " << type << "\n";
new_type = true;
}
// Now pick up the derivation information.
int num_parent_classes = scan.get_uint8();
for (int i = 0; i < num_parent_classes; i++) {
TypeHandle parent_type = read_handle(scan);
if (new_type) {
TypeRegistry::ptr()->record_derivation(type, parent_type);
} else {
if (type.get_parent_towards(parent_type) != parent_type) {
bam_cat.warning()
<< "Bam file indicates a derivation of " << type
<< " from " << parent_type << " which is no longer true.\n";
}
}
}
bool inserted = _index_map.insert(IndexMap::value_type(id, type)).second;
nassertr(inserted, type);
#ifndef NDEBUG
if (bam_cat.is_spam()) {
bam_cat.spam()
<< "Reading TypeHandle for " << _index_map[id] << ".\n";
<< "Read TypeHandle for " << type << ".\n";
}
#endif
return _index_map[id];
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::read_object
// Access: Public
// Description: Reads an object definition from the DatagramGenerator
// and generates an object of the correct type, and returns
// a pointer to that object.
////////////////////////////////////////////////////////////////////
TypedWriteable* BamReader::
read_object(void)
{
Datagram packet, body;
//if (_source->empty()) //If the source is empty, then we merely have
//{ //back reference read's queue, so clear the queue
// clear_queue();
// return TypedWriteable::Null;
//}
if (_source->is_error())
{
return TypedWriteable::Null;
}
if (!_source->get_datagram(packet)) {
// The datagram source is empty.
#ifndef NDEBUG
if (bam_cat.is_debug()) {
bam_cat.debug()
<< "Reached end of bam source.\n";
}
#endif
return TypedWriteable::Null;
}
//Now pull out the type ID and Object ID from the
//datagram and pass the remaining data in that
//datagram, the body to the WriteableParam for
//creation of the object
DatagramIterator scan(packet);
TypeHandle type = read_handle(scan);
PN_uint16 objId = scan.get_uint16();
//Before anything else, check to see if type is none
//If that is the case, then we SHOULD have already read
//in and created the object (although pointers in that object
//may not be fully instanciated yet), so just return a pointer
//to that already created obj and don't try to re-create it
if (type != TypeHandle::none())
{
string message = scan.get_remaining_bytes();
body.append_data(message.data(), message.size());
//Generate FactoryParams object to pass to the factory for
//creating the object
FactoryParams list;
list.add_param(new WriteableParam(body));
list.add_param(new BamReaderParam(this));
//Due to the recursive nature of reading in objects (and their pointers)
//this line is to ensure that objId gets into the map _created_objs
//before we call make_instance. It works due to the nature of map.
//What happens is that a pair consistenting of objId and some random
//pointer is put into the map. But this is okay, since in the
//recursion we only refer to this objId for purposes of whether
//it is there or not and we immediately override it with a good
//value otherwise
_created_objs[objId];
_created_objs[objId] = _factory->make_instance_more_general(type, list);
//Just some sanity checks
if (_created_objs[objId] == (TypedWriteable *)NULL) {
bam_cat.error()
<< "Unable to create an object of type " << type << endl;
} else if (_created_objs[objId]->get_type() != type) {
bam_cat.warning()
<< "Attempted to create a " << type.get_name() \
<< " but a " << _created_objs[objId]->get_type() \
<< " was created instead." << endl;
} else {
#ifndef NDEBUG
if (bam_cat.is_spam()) {
bam_cat.spam()
<< "Read a " << _created_objs[objId]->get_type() << "\n";
}
#endif
}
}
#ifndef NDEBUG
if (bam_cat.is_spam()) {
bam_cat.spam()
<< "Emptying queue.\n";
}
#endif
empty_queue();
TypedWriteable *object = _created_objs[objId];
#ifndef NDEBUG
if (bam_cat.is_spam()) {
if (object == (TypedWriteable *)NULL) {
bam_cat.spam()
<< "Returning NULL\n";
} else {
bam_cat.spam()
<< "Returning object of type " << object->get_type() << "\n";
}
}
#endif
return object;
return type;
}
////////////////////////////////////////////////////////////////////
@ -310,22 +389,21 @@ read_object(void)
// object properly.
////////////////////////////////////////////////////////////////////
void BamReader::
read_pointer(DatagramIterator& scan, TypedWriteable* forWhom)
{
PN_uint16 objId = scan.get_uint16();
_deferred_pointers[forWhom].push_back(objId);
// This is safe since we have already read the full datagram for the
// object requesting this object. So there can be no collision on
// that front.
read_pointer(DatagramIterator &scan, TypedWriteable *for_whom) {
// Read the object ID, and associate it with the requesting object.
int object_id = scan.get_uint16();
_deferred_pointers[for_whom].push_back(object_id);
// IMPORTANT NOTE: This does make the assumption that objects are
// requested by other objects in the same order that they wrote them
// originally.
// Don't queue a read of a null pointer or if the object has already
// been read
if ((objId != 0) && (_created_objs.find(objId) == _created_objs.end()))
queue(objId);
// If the object ID is zero (which indicates a NULL pointer), we
// don't have to do anything else.
if (object_id != 0) {
if (_created_objs.count(object_id) == 0) {
// If we don't already have an entry in the map for this object
// ID (that is, we haven't encountered this object before), we
// must remember to read the object definition later.
_num_extra_objects++;
}
}
}
////////////////////////////////////////////////////////////////////
@ -336,9 +414,9 @@ read_pointer(DatagramIterator& scan, TypedWriteable* forWhom)
// read_pointer() count times.
////////////////////////////////////////////////////////////////////
void BamReader::
read_pointers(DatagramIterator &scan, TypedWriteable *forWhom, int count) {
read_pointers(DatagramIterator &scan, TypedWriteable *for_whom, int count) {
for (int i = 0; i < count; i++) {
read_pointer(scan, forWhom);
read_pointer(scan, for_whom);
}
}
@ -358,13 +436,20 @@ skip_pointer(DatagramIterator &scan) {
////////////////////////////////////////////////////////////////////
// Function: BamReader::register_finalize
// Access: Public
// Description: Register for later finalization
// Description: Should be called by an object reading itself from the
// Bam file to indicate that this particular object
// would like to receive the finalize() callback when
// all the objects and pointers in the Bam file are
// completely read.
//
// This provides a hook for objects (like Characters)
// that need to do any additional finalization work
// after all of their related pointers are guaranteed to
// be filled in.
////////////////////////////////////////////////////////////////////
void BamReader::
register_finalize(TypedWriteable *whom)
{
if (whom == TypedWriteable::Null)
{
register_finalize(TypedWriteable *whom) {
if (whom == TypedWriteable::Null) {
bam_cat.error() << "Can't register a null pointer to finalize!" << endl;
return;
}
@ -374,66 +459,206 @@ register_finalize(TypedWriteable *whom)
////////////////////////////////////////////////////////////////////
// Function: BamReader::finalize_now
// Access: Public
// Description: Force finalization of a particular object
// Description: Forces the finalization of a particular object. This
// may be called by any of the objects during
// finalization, to guarantee finalization ordering
// where it is important.
////////////////////////////////////////////////////////////////////
void BamReader::
finalize_now(TypedWriteable *whom)
{
if (whom == TypedWriteable::Null)
{
bam_cat.error() << "Can't finalize null pointer!" << endl;
return;
}
if (_finalize_list.find(whom) != _finalize_list.end())
{
finalize_now(TypedWriteable *whom) {
nassertv(whom != (TypedWriteable *)NULL);
Finalize::iterator fi = _finalize_list.find(whom);
if (fi != _finalize_list.end()) {
_finalize_list.erase(fi);
whom->finalize();
_finalize_list.erase(whom);
}
else
{
bam_cat.warning() << "Request to finalize object of type "
<< whom->get_type().get_name() << " failed"
<< endl;
}
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::empty_queue
// Access: Private
// Description: For every objId in the queue, reads an object
// from the datagram source
// Function: BamReader::get_pta
// Access: Public
// Description: This function works in conjection with
// register_pta(), below, to read a PointerToArray (PTA)
// from the Bam file, and unify references to the same
// PTA.
//
// The first time get_pta() encounters a particular PTA,
// it will return NULL. This is the indication that the
// caller should then read in the data associated with
// the PTA, and subsequently call register_pta() with
// the address of the filled-in array.
//
// The next time (and all subsequent times) that
// get_pta() encounters this same PTA, it will return
// the pointer that was passed with register_pta().
//
// Also see the READ_PTA() macro, which consolidates all
// the work that must be done to read a PTA.
////////////////////////////////////////////////////////////////////
void BamReader::
empty_queue(void) {
size_t num_reads = _deferred_reads.size();
_deferred_reads.clear();
void *BamReader::
get_pta(DatagramIterator &scan) {
nassertr(_pta_id == -1, (void *)NULL);
int id = scan.get_uint16();
while (num_reads > 0) {
read_object();
num_reads--;
if (id == 0) {
// As always, a 0 ID indicates a NULL pointer. The caller will
// not be able to differentiate this case from that of a
// previously-read pointer, but that's OK because the next data in
// the Bam file is the length of the array, which will be
// zero--indicating an empty or NULL array.
return (void *)NULL;
}
PTAMap::iterator pi = _ptamap.find(id);
if (pi == _ptamap.end()) {
// This is the first time we've encountered this particular ID,
// meaning we need to read the data now and register it.
_pta_id = id;
return (void *)NULL;
}
return (*pi).second;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::finalize_this
// Access: Private
// Description:
// Function: BamReader::register_pta
// Access: Public
// Description: The second part of read_pta(), this should be called
// with the pointer to the array that was read in after
// read_pta() returned NULL. This associates the
// pointer with the ID that was previously read, so that
// future calls to read_pta() will return the same
// pointer.
//
// Also see the READ_PTA() macro, which consolidates all
// the work that must be done to read a PTA.
////////////////////////////////////////////////////////////////////
void BamReader::
finalize_this(TypedWriteable *whom)
{
whom->finalize();
_finalize_list.erase(whom);
register_pta(void *ptr) {
if (_pta_id != -1) {
bool inserted = _ptamap.insert(PTAMap::value_type(_pta_id, ptr)).second;
_pta_id = -1;
nassertv(inserted);
}
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::p_read_object
// Access: Private
// Description: The private implementation of read_object(), this
// reads an object from the file and returns its object
// ID.
////////////////////////////////////////////////////////////////////
int BamReader::
p_read_object() {
Datagram packet;
if (_source->is_error()) {
return 0;
}
// First, read a datagram for the object.
if (!_source->get_datagram(packet)) {
// When we run out of datagrams, we're at the end of the file.
#ifndef NDEBUG
if (bam_cat.is_debug()) {
bam_cat.debug()
<< "Reached end of bam source.\n";
}
#endif
return 0;
}
// Now extract the object definition from the datagram.
DatagramIterator scan(packet);
// An object definition in a Bam file consists of a TypeHandle
// definition, defining the object's type, followed by an object ID
// index, defining the particular instance (e.g. pointer) of this
// object.
TypeHandle type = read_handle(scan);
int object_id = scan.get_uint16();
// There are two cases. Either this is a new object definition, or
// this is a reference to an object that was previously defined.
// We use the TypeHandle to differentiate these two cases. By
// convention, we write a TypeHandle::none() to the Bam file when we
// are writing a reference to a previously-defined object, but we
// write the object's actual type when we are writing its definition
// right now.
// Therefore, if the type is TypeHandle::none(), then we must have
// already read in and created the object (although its pointers may
// not be fully instantiated yet). On the other hand, if the type
// is anything else, then we must read the definition to follow.
if (type != TypeHandle::none()) {
// Now we are going to read and create a new object.
// Defined the parameters for passing to the object factory.
FactoryParams fparams;
fparams.add_param(new BamReaderParam(scan, this));
// First, we must add an entry into the map for this object ID, so
// that in case this function is called recursively during the
// object's factory constructor, we will have some definition for
// the object. It doesn't matter yet what the pointer is.
CreatedObjs::iterator oi =
_created_objs.insert(CreatedObjs::value_type(object_id, NULL)).first;
// Now we can call the factory to create the object.
TypedWriteable *object =
_factory->make_instance_more_general(type, fparams);
// And now we can store the new object pointer in the map.
(*oi).second = object;
//Just some sanity checks
if (object == (TypedWriteable *)NULL) {
bam_cat.error()
<< "Unable to create an object of type " << type << endl;
} else if (object->get_type() != type) {
bam_cat.warning()
<< "Attempted to create a " << type.get_name() \
<< " but a " << object->get_type() \
<< " was created instead." << endl;
} else {
#ifndef NDEBUG
if (bam_cat.is_spam()) {
bam_cat.spam()
<< "Read a " << object->get_type() << "\n";
}
#endif
}
}
#ifndef NDEBUG
if (bam_cat.is_spam()) {
bam_cat.spam()
<< "Emptying queue.\n";
}
#endif
return object_id;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::finalize
// Access: Private
// Description: Call finalize_this on all objects stored
// Description: Should be called after all objects have been read,
// this will finalize all the objects that registered
// themselves for the finalize callback.
////////////////////////////////////////////////////////////////////
void BamReader::
finalize(void)
{
finalize() {
#ifndef NDEBUG
if (bam_cat.is_debug()) {
bam_cat.debug()
@ -442,143 +667,12 @@ finalize(void)
#endif
Finalize::iterator fi = _finalize_list.begin();
while(fi != _finalize_list.end())
{
if (*fi == TypedWriteable::Null)
{
bam_cat.error() << "Spun off into the weeds. "
<< "somehow a null was registered to be "
<< "finalized." << endl;
_finalize_list.erase(fi);
}
else
{
finalize_this(*fi);
}
while (fi != _finalize_list.end()) {
TypedWriteable *object = (*fi);
nassertv(object != (TypedWriteable *)NULL);
_finalize_list.erase(fi);
object->finalize();
fi = _finalize_list.begin();
}
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::get_pta
// Access: Public
// Description: Requests an already read PTA from BamReader. If
// the PTA has not already been read and registered,
// returns a NULL
////////////////////////////////////////////////////////////////////
void* BamReader::
get_pta(DatagramIterator &scan)
{
int _id = scan.get_uint16();
if (_id == 0)
{
_pta_id = -1;
return (void*)NULL;
}
if (_ptamap.find(_id) == _ptamap.end())
{
_pta_id = _id;
return (void*)NULL;
}
else
{
//Just to enforce that register_pta should do nothing if
//get_pta returns a good value or a NULL was what was
//actually written
_pta_id = -1;
}
return _ptamap[_id];
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::register_pta
// Access: Public
// Description: Utility function to be called by the objects reading
// themselves from a Datagram. Registers a PTA with
// BamReader, so that if there are any shared ptr references,
// BamReader can detect and resolve those. To be used
// in conjunction with get_pta
////////////////////////////////////////////////////////////////////
void BamReader::
register_pta(void *ptr)
{
//Just a sanity check to make sure that register_pta
//does nothing if get_pta has not been called first
if (_pta_id != -1)
{
_ptamap[_pta_id] = ptr;
}
_pta_id = -1;
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::resolve
// Access: Public
// Description: Calling this function, asks BamReader to go ahead
// and resolve all pointer requests that can be resolved
////////////////////////////////////////////////////////////////////
bool BamReader::
resolve(void)
{
Requests::iterator whom, old;
vector_ushort::iterator request;
bool objReferencesComplete;
vector_typedWriteable references;
//Loop through the list of all objects who registered themselves as wanting
//a pointer to another object to be completed
whom = _deferred_pointers.begin();
while(whom != _deferred_pointers.end())
{
//For each of those objects, loop through its list of objects that it is
//interested in. If any one of those is not complete, then do nothing
//for that object, as when it is passed the list of pointers, it will
//expect them in a certain order and in totality.
objReferencesComplete = true;
references.clear();
for(request = (*whom).second.begin(); request != (*whom).second.end(); request++)
{
//Check and see if the request was for a null pointer
if (*request == 0)
{
references.push_back(TypedWriteable::Null);
}
else
{
//Test to see if the object requested has been created or not yet
if (_created_objs.find((*request)) == _created_objs.end())
{
objReferencesComplete = false;
break;
}
references.push_back(_created_objs[(*request)]);
}
}
if (objReferencesComplete)
{
(*whom).first->complete_pointers(references, this);
//The request list has been completed, so delete the
//list froms storage
//Annoying STL design flaw forces this delete trick
old = whom;
whom++;
_deferred_pointers.erase(old);
}
else
{
// nassertv(objReferencesComplete);
bam_cat.warning()
<< "Unable to complete " << (*whom).first->get_type() << "\n";
whom++;
}
}
finalize();
return true;
}

View File

@ -11,11 +11,12 @@
#include "typedWriteable.h"
#include "datagramGenerator.h"
#include "datagramIterator.h"
#include "writeableParam.h"
#include "bamReaderParam.h"
#include "factory.h"
#include "vector_ushort.h"
#include <deque>
#include <algorithm>
//Useful define for reading pta's
#define READ_PTA(Manager, source, Read_func, array) \
@ -34,55 +35,68 @@
////////////////////////////////////////////////////////////////////
// Class : BamReader
// Description : This class manages all aspects of reading the data
// structure from a DatagramGenerator Requests are made to
// read an object out of the source. This class will then
// read in all the necessary data and pass that data into
// a factory object for creating TypedWriteable objects.
// The factory, will call the particular "make" function
// of the class of the object being created.
// If that object has pointers to any objects that are
// also stored in the binary source, then that object will
// make a request to BamReader for that object to be
// read and register itself with BamReader. Once BamReader
// has read in the objects requested, resolve can be called
// to go back and complete the pointer requests. BamReader's
// interface back into the functions is complete_pointers,
// which is defined in TypedWriteable
// Description : This is the fundamental interface for extracting
// binary objects from a Bam file, as generated by a
// BamWriter.
//
// A Bam file can be thought of as a linear collection
// of objects. Each object is an instance of a class
// that inherits, directly or indirectly, from
// TypedWriteable. The objects may include pointers to
// other objects within the Bam file; the BamReader
// automatically manages these and restores the pointers
// correctly.
//
// This is the abstract interface and does not
// specifically deal with disk files, but rather with a
// DatagramGenerator of some kind, which is simply a
// linear source of Datagrams. It is probably from a
// disk file, but it might conceivably be streamed
// directly from a network or some such nonsense.
//
// Bam files are most often used to store scene graphs
// or subgraphs, and by convention they are given
// filenames ending in the extension ".bam" when they
// are used for this purpose. However, a Bam file may
// store any arbitrary list of TypedWriteable objects;
// in this more general usage, they are given filenames
// ending in ".boo" to differentiate them from the more
// common scene graph files.
//
// See also BamFile, which defines a higher-level
// interface to read and write Bam files on disk.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA BamReader {
public:
typedef Factory<TypedWriteable> WriteableFactory;
static BamReader* const Null;
static WriteableFactory* const NullFactory;
static BamReader *const Null;
static WriteableFactory *const NullFactory;
INLINE BamReader(DatagramGenerator *generator);
~BamReader(void);
// The primary interface for a caller.
bool init(void);
TypedWriteable* read_object(void);
//When a client class asks BamReader to read out an object that it
//points to, it needs to pass a reference to itself, that BamReader
//can register in itself for later "fixing"
void read_pointer(DatagramIterator &scan, TypedWriteable* forWhom);
void read_pointers(DatagramIterator &scan, TypedWriteable* forWhom, int count);
BamReader(DatagramGenerator *generator);
~BamReader();
bool init();
TypedWriteable *read_object();
INLINE bool is_eof() const;
bool resolve();
INLINE int get_file_major_ver() const;
INLINE int get_file_minor_ver() const;
INLINE int get_current_major_ver() const;
INLINE int get_current_minor_ver() const;
public:
// Functions to support classes that read themselves from the Bam.
void read_pointer(DatagramIterator &scan, TypedWriteable *for_whom);
void read_pointers(DatagramIterator &scan, TypedWriteable *for_whom, int count);
void skip_pointer(DatagramIterator &scan);
//At any time you can call this function to try and resolve all
//outstanding pointer requests. Will resolve all requests that
//it can, and ignores those it can't. This allows for immediate
//use of part of a full definition if that is wanted.
bool resolve(void);
//There are some classes that need to perform certain tasks before they
//are useable, but those taks can not be performed before all pointer
//references have been completed. So this function is provided as an
//interface to allow each class to register itself to be finalized
void register_finalize(TypedWriteable *whom);
//Since there may be an ordering dependency on who gets finalized first,
//either the parent or the children. So this function is provided as an
//interface to force finalization of an object
void finalize_now(TypedWriteable *whom);
void *get_pta(DatagramIterator &scan);
@ -91,51 +105,50 @@ public:
TypeHandle read_handle(DatagramIterator &scan);
//Version access functions
INLINE int get_file_major_ver(void);
INLINE int get_file_minor_ver(void);
INLINE int get_current_major_ver(void);
INLINE int get_current_minor_ver(void);
public:
INLINE static WriteableFactory* get_factory(void);
INLINE static WriteableFactory *get_factory();
private:
INLINE static void create_factory(void);
INLINE static void create_factory();
private:
INLINE void queue(PN_uint16);
void empty_queue(void);
INLINE void clear_queue(void);
void finalize_this(TypedWriteable *whom);
void finalize(void);
int p_read_object();
void finalize();
private:
typedef map<int, TypedWriteable*> Created;
typedef map<TypedWriteable*, vector_ushort> Requests;
typedef set<TypedWriteable*> Finalize;
typedef deque<PN_uint16> DeferredReads;
static WriteableFactory *_factory;
DatagramGenerator *_source;
//Map of old TypeHandle index number to current TypeHandle
map<int, TypeHandle> _index_map;
//Map of unique object ID in Binary structure to created object
Created _created_objs;
//Map of Objects that need pointers completed, to the
//object ID of the objects they need
Requests _deferred_pointers;
DeferredReads _deferred_reads;
//Keep track of all objects needing to be finalized
// This maps the type index numbers encountered within the Bam file
// to actual TypeHandles.
typedef map<int, TypeHandle> IndexMap;
IndexMap _index_map;
// This maps the object ID numbers encountered within the Bam file
// to the actual pointers of the corresponding generated objects.
typedef map<int, TypedWriteable *> CreatedObjs;
CreatedObjs _created_objs;
// This records all the objects that still need their pointers
// completed, along with the object ID's of the pointers they need,
// in the order in which read_pointer() was called.
typedef map<TypedWriteable *, vector_ushort> Requests;
Requests _deferred_pointers;
// This is the number of extra objects that must still be read (and
// saved in the _created_objs map) before returning from
// read_object().
int _num_extra_objects;
// This is the set of all objects that registered themselves for
// finalization.
typedef set<TypedWriteable *> Finalize;
Finalize _finalize_list;
//Map of unique PTA ID's to the PTA's
map<int, void*> _ptamap;
//When register_pta is called, this is the unique
//PTA ID that was stored during the call to
//get_pta that failed.
// These are used by get_pta() and register_pta() to unify multiple
// references to the same PointerToArray.
typedef map<int, void *> PTAMap;
PTAMap _ptamap;
int _pta_id;
int _file_major, _file_minor;
@ -145,11 +158,13 @@ private:
typedef BamReader::WriteableFactory WriteableFactory;
//Useful function for taking apart the Factory Params
//in the static functions that need to be defined in each
//writeable class that will be generated by a factory. Sets a
//datagram and a BamReader
INLINE void parse_params(const FactoryParams &, BamReader* &, Datagram &);
// Useful function for taking apart the Factory Params in the static
// functions that need to be defined in each writeable class that will
// be generated by a factory. Sets the DatagramIterator and the
// BamReader pointers.
INLINE void
parse_params(const FactoryParams &params,
DatagramIterator &scan, BamReader *&manager);
#include "bamReader.I"

View File

@ -3,56 +3,46 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: BamReaderParam::get_iterator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const DatagramIterator &BamReaderParam::
get_iterator() {
return _iterator;
}
////////////////////////////////////////////////////////////////////
// Function: BamReaderParam::get_manager
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE BamReader *BamReaderParam::
get_manager() {
return _manager;
}
////////////////////////////////////////////////////////////////////
// Function: BamReaderParam::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE BamReaderParam::
BamReaderParam(BamReader *manager) :
BamReaderParam(const DatagramIterator &dgi, BamReader *manager) :
_iterator(dgi),
_manager(manager)
{
}
////////////////////////////////////////////////////////////////////
// Function: BamReaderParam::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE BamReaderParam::
BamReaderParam(const BamReaderParam &copy) :
FactoryParam(copy),
_manager(copy._manager)
{
}
////////////////////////////////////////////////////////////////////
// Function: BamReaderParam::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void BamReaderParam::
operator = (const BamReaderParam &copy) {
FactoryParam::operator = (copy);
_manager = copy._manager;
}
////////////////////////////////////////////////////////////////////
// Function: BamReaderParam::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE BamReaderParam::
~BamReaderParam(void) {
~BamReaderParam() {
}
////////////////////////////////////////////////////////////////////
// Function: BamReaderParam::get_datagram
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE BamReader* BamReaderParam::
get_manager(void) {
return _manager;
}

View File

@ -9,30 +9,26 @@
#include <pandabase.h>
#include "factoryParam.h"
#include "datagram.h"
#include <vector>
class BamReader;
class DatagramIterator;
////////////////////////////////////////////////////////////////////
// Class : BamReaderParam
// Description : The specific derivation of FactoryParam that
// contains the information needed by a TypedWriteable
// object. Simply contains a pointer to the managing
// BamReader
// Description : The parameters that are passed through the Factory to
// any object constructing itself from a Bam file.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA BamReaderParam : public FactoryParam {
public:
INLINE BamReader *get_manager(void);
INLINE const DatagramIterator &get_iterator();
INLINE BamReader *get_manager();
private:
const DatagramIterator &_iterator;
BamReader *_manager;
public:
INLINE BamReaderParam(BamReader *manager);
INLINE BamReaderParam(const BamReaderParam &other);
INLINE void operator = (const BamReaderParam &other);
INLINE BamReaderParam(const DatagramIterator &dgi, BamReader *manager);
INLINE ~BamReaderParam();
public:

View File

@ -50,12 +50,10 @@ TypedWriteable* Person::
make_person(const FactoryParams &params)
{
Person *me = new Person;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(me, scan, manager);
return me;
}
@ -98,12 +96,10 @@ TypedWriteable* Parent::
make_parent(const FactoryParams &params)
{
Parent *me = new Parent;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(me, scan, manager);
return me;
}
@ -158,12 +154,11 @@ TypedWriteable* Child::
make_child(const FactoryParams &params)
{
Child *me = new Child;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(me, scan, manager);
me->fillin(me, scan, manager);
return me;

View File

@ -205,12 +205,10 @@ TypedWriteable* BillboardTransition::
make_BillboardTransition(const FactoryParams &params)
{
BillboardTransition *me = new BillboardTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -54,12 +54,10 @@ TypedWriteable* ColorMatrixTransition::
make_ColorMatrixTransition(const FactoryParams &params)
{
ColorMatrixTransition *me = new ColorMatrixTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -120,12 +120,10 @@ TypedWriteable* CullFaceTransition::
make_CullFaceTransition(const FactoryParams &params)
{
CullFaceTransition *me = new CullFaceTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -55,12 +55,10 @@ TypedWriteable* DecalTransition::
make_DecalTransition(const FactoryParams &params)
{
DecalTransition *me = new DecalTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -111,12 +111,10 @@ write_datagram(BamWriter *manager, Datagram &me) {
TypedWriteable* DepthTestTransition::
make_DepthTestTransition(const FactoryParams &params) {
DepthTestTransition *me = new DepthTestTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -63,12 +63,10 @@ write_datagram(BamWriter *manager, Datagram &me) {
TypedWriteable *DepthWriteTransition::
make_DepthWriteTransition(const FactoryParams &params) {
DepthWriteTransition *me = new DepthWriteTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -140,12 +140,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *) {
TypedWriteable* MaterialTransition::
make_MaterialTransition(const FactoryParams &params) {
MaterialTransition *me = new MaterialTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -54,12 +54,10 @@ TypedWriteable* PruneTransition::
make_PruneTransition(const FactoryParams &params)
{
PruneTransition *me = new PruneTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -78,12 +78,10 @@ TypedWriteable* RenderRelation::
make_RenderRelation(const FactoryParams &params)
{
RenderRelation *me = new RenderRelation;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -118,12 +118,10 @@ TypedWriteable* TextureApplyTransition::
make_TextureApplyTransition(const FactoryParams &params)
{
TextureApplyTransition *me = new TextureApplyTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -141,12 +141,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *) {
TypedWriteable* TextureTransition::
make_TextureTransition(const FactoryParams &params) {
TextureTransition *me = new TextureTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -54,12 +54,10 @@ TypedWriteable* TransformTransition::
make_TransformTransition(const FactoryParams &params)
{
TransformTransition *me = new TransformTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -118,12 +118,10 @@ TypedWriteable* TransparencyTransition::
make_TransparencyTransition(const FactoryParams &params)
{
TransparencyTransition *me = new TransparencyTransition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -285,12 +285,10 @@ TypedWriteable* GeomNode::
make_GeomNode(const FactoryParams &params)
{
GeomNode *me = new GeomNode;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -70,12 +70,10 @@ register_with_read_factory() {
TypedWriteable* ModelNode::
make_ModelNode(const FactoryParams &params) {
ModelNode *me = new ModelNode;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -39,12 +39,10 @@ register_with_read_factory() {
TypedWriteable* ModelRoot::
make_ModelRoot(const FactoryParams &params) {
ModelRoot *me = new ModelRoot;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -170,12 +170,10 @@ write_datagram(BamWriter *manager, Datagram &me) {
TypedWriteable *LODNode::
make_LODNode(const FactoryParams &params) {
LODNode *me = new LODNode;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -164,12 +164,10 @@ fillin(DatagramIterator &scan, BamReader *manager) {
TypedWriteable *SequenceNode::
make_SequenceNode(const FactoryParams &params) {
SequenceNode *me = new SequenceNode;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -116,8 +116,10 @@ get_info(const Filename &filename) {
typedef vector<TypedWriteable *> Objects;
Objects objects;
TypedWriteable *object = bam_file.read_object();
while (object != (TypedWriteable *)NULL) {
objects.push_back(object);
while (!bam_file.is_eof()) {
if (object != (TypedWriteable *)NULL) {
objects.push_back(object);
}
object = bam_file.read_object();
}
bam_file.resolve();

View File

@ -139,12 +139,10 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
TypedWriteable* DestTextureImage::
make_DestTextureImage(const FactoryParams &params) {
DestTextureImage *me = new DestTextureImage;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -571,12 +571,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable* EggFile::
make_EggFile(const FactoryParams &params) {
EggFile *me = new EggFile;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -648,12 +648,10 @@ finalize() {
TypedWriteable *PaletteGroup::
make_PaletteGroup(const FactoryParams &params) {
PaletteGroup *me = new PaletteGroup;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
manager->register_finalize(me);
return me;

View File

@ -305,12 +305,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable* PaletteGroups::
make_PaletteGroups(const FactoryParams &params) {
PaletteGroups *me = new PaletteGroups;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -798,12 +798,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable *PaletteImage::
make_PaletteImage(const FactoryParams &params) {
PaletteImage *me = new PaletteImage;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -312,12 +312,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable* PalettePage::
make_PalettePage(const FactoryParams &params) {
PalettePage *me = new PalettePage;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -927,12 +927,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable* Palettizer::
make_Palettizer(const FactoryParams &params) {
Palettizer *me = new Palettizer;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -206,12 +206,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable *SourceTextureImage::
make_SourceTextureImage(const FactoryParams &params) {
SourceTextureImage *me = new SourceTextureImage;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -1131,12 +1131,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable *TextureImage::
make_TextureImage(const FactoryParams &params) {
TextureImage *me = new TextureImage;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -977,12 +977,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable* TexturePlacement::
make_TexturePlacement(const FactoryParams &params) {
TexturePlacement *me = new TexturePlacement;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -112,12 +112,10 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
TypedWriteable* TexturePosition::
make_TexturePosition(const FactoryParams &params) {
TexturePosition *me = new TexturePosition;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -591,12 +591,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable* TextureProperties::
make_TextureProperties(const FactoryParams &params) {
TextureProperties *me = new TextureProperties;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -731,12 +731,10 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
TypedWriteable* TextureReference::
make_TextureReference(const FactoryParams &params) {
TextureReference *me = new TextureReference;
DatagramIterator scan;
BamReader *manager;
Datagram packet;
parse_params(params, manager, packet);
DatagramIterator scan(packet);
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}

View File

@ -186,7 +186,7 @@ extract_record(FltRecordReader &reader) {
return false;
}
if (_header->get_flt_version() >= 15.2) {
if (_header->get_flt_version() >= 1520) {
_texture_mapping_index = iterator.get_be_int16();
iterator.skip_bytes(2);
_color_index = iterator.get_be_int32();
@ -238,7 +238,7 @@ build_record(FltRecordWriter &writer) const {
return false;
}
if (_header->get_flt_version() >= 15.2) {
if (_header->get_flt_version() >= 1520) {
// New with 15.2
datagram.add_be_int16(_texture_mapping_index);
datagram.pad_bytes(2);

View File

@ -222,14 +222,15 @@ get_auto_attr_update() const {
// Function: FltHeader::get_flt_version
// Access: Public
// Description: Returns the version number of the flt file as
// reported in the header.
// reported in the header, times 100. Divide by 100 to
// get the floating-point version number.
////////////////////////////////////////////////////////////////////
double FltHeader::
int FltHeader::
get_flt_version() const {
if (_format_revision_level < 1420) {
return _format_revision_level;
return _format_revision_level * 100;
} else {
return _format_revision_level / 100.0;
return _format_revision_level;
}
}
@ -237,14 +238,15 @@ get_flt_version() const {
// Function: FltHeader::set_flt_version
// Access: Public
// Description: Changes the version number of the flt file that will
// be reported in the header.
// be reported in the header. Pass in the
// floating-point version number times 100.
////////////////////////////////////////////////////////////////////
void FltHeader::
set_flt_version(double version) {
set_flt_version(int version) {
if (version < 14.2) {
_format_revision_level = (int)floor(version + 0.5);
_format_revision_level = version / 100;
} else {
_format_revision_level = (int)floor(version * 100.0 + 0.5);
_format_revision_level = version;
}
}
@ -252,24 +254,24 @@ set_flt_version(double version) {
// Function: FltHeader::min_flt_version
// Access: Public, Static
// Description: Returns the earliest flt version number that this
// codebase supports. Earlier versions will probably
// not work.
// codebase supports (times 100). Earlier versions will
// probably not work.
////////////////////////////////////////////////////////////////////
double FltHeader::
int FltHeader::
min_flt_version() {
return 14.2;
return 1420;
}
////////////////////////////////////////////////////////////////////
// Function: FltHeader::max_flt_version
// Access: Public, Static
// Description: Returns the latest flt version number that this
// codebase is known to support. Later versions might
// work, but then again they may not.
// codebase is known to support (times 100). Later
// versions might work, but then again they may not.
////////////////////////////////////////////////////////////////////
double FltHeader::
int FltHeader::
max_flt_version() {
return 15.7;
return 1570;
}
////////////////////////////////////////////////////////////////////
@ -284,20 +286,20 @@ max_flt_version() {
////////////////////////////////////////////////////////////////////
bool FltHeader::
check_version() const {
double version = get_flt_version();
int version = get_flt_version();
if (version < min_flt_version() && !IS_NEARLY_EQUAL(version, min_flt_version())) {
if (version < min_flt_version()) {
nout << "Warning! The version number of this file appears to be "
<< version << ", which is older than " << min_flt_version()
<< version << ", which is older than " << min_flt_version() / 100.0
<< ", the oldest OpenFlight version understood by this program. "
"It is unlikely that this program will be able to read the file "
"correctly.\n";
return false;
}
if (version > max_flt_version() && !IS_NEARLY_EQUAL(version, max_flt_version())) {
if (version > max_flt_version()) {
nout << "Warning! The version number of this file appears to be "
<< version << ", which is newer than " << max_flt_version()
<< version << ", which is newer than " << max_flt_version() / 100.0
<< ", the newest OpenFlight version understood by this program. "
"Chances are good that the program will still be able to read it "
"correctly, but any features in the file that are specific to "
@ -1202,19 +1204,19 @@ extract_record(FltRecordReader &reader) {
_next_road_id = iterator.get_be_int16();
_next_cat_id = iterator.get_be_int16();
if (get_flt_version() >= 15.2 && iterator.get_remaining_size() > 0) {
if (get_flt_version() >= 1520 && iterator.get_remaining_size() > 0) {
iterator.skip_bytes(2 + 2 + 2 + 2);
_earth_model = (EarthModel)iterator.get_be_int32();
// Undocumented padding.
iterator.skip_bytes(4);
if (get_flt_version() >= 15.6 && iterator.get_remaining_size() > 0) {
if (get_flt_version() >= 1560 && iterator.get_remaining_size() > 0) {
_next_adaptive_id = iterator.get_be_int16();
_next_curve_id = iterator.get_be_int16();
iterator.skip_bytes(4);
if (get_flt_version() >= 15.7 && iterator.get_remaining_size() > 0) {
if (get_flt_version() >= 1570 && iterator.get_remaining_size() > 0) {
_delta_z = iterator.get_be_float64();
_radius = iterator.get_be_float64();
_next_mesh_id = iterator.get_be_int16();
@ -1340,20 +1342,20 @@ build_record(FltRecordWriter &writer) const {
datagram.add_be_int16(_next_road_id);
datagram.add_be_int16(_next_cat_id);
if (get_flt_version() >= 15.2) {
if (get_flt_version() >= 1520) {
// New with 15.2
datagram.pad_bytes(2 + 2 + 2 + 2);
datagram.add_be_int32(_earth_model);
datagram.pad_bytes(4);
if (get_flt_version() >= 15.6) {
if (get_flt_version() >= 1560) {
// New with 15.6
datagram.add_be_int16(_next_adaptive_id);
datagram.add_be_int16(_next_curve_id);
datagram.pad_bytes(4);
if (get_flt_version() >= 15.7) {
if (get_flt_version() >= 1570) {
// New with 15.7
datagram.add_be_float64(_delta_z);
datagram.add_be_float64(_radius);
@ -1714,7 +1716,7 @@ FltError FltHeader::
write_material_palette(FltRecordWriter &writer) const {
FltError result;
if (get_flt_version() >= 15.2) {
if (get_flt_version() >= 1520) {
// Write a version 15 material palette.
Materials::const_iterator mi;
for (mi = _materials.begin(); mi != _materials.end(); ++mi) {

View File

@ -128,10 +128,10 @@ public:
int _next_mesh_id;
public:
double get_flt_version() const;
void set_flt_version(double version);
static double min_flt_version();
static double max_flt_version();
int get_flt_version() const;
void set_flt_version(int version);
static int min_flt_version();
static int max_flt_version();
bool check_version() const;
DistanceUnit get_units() const;

View File

@ -59,7 +59,7 @@ get_opcode() const {
////////////////////////////////////////////////////////////////////
int FltVertex::
get_record_length() const {
if (_header->get_flt_version() < 15.2) {
if (_header->get_flt_version() < 1520) {
// Version 14.2
switch (get_opcode()) {
case FO_vertex_c:
@ -193,7 +193,7 @@ extract_record(FltRecordReader &reader) {
if (!_packed_color.extract_record(reader)) {
return false;
}
if (_header->get_flt_version() >= 15.2) {
if (_header->get_flt_version() >= 1520) {
_color_index = iterator.get_be_int32();
if (_has_normal && iterator.get_remaining_size() > 0) {
@ -244,7 +244,7 @@ build_record(FltRecordWriter &writer) const {
return false;
}
if (_header->get_flt_version() >= 15.2) {
if (_header->get_flt_version() >= 1520) {
// New with 15.2
datagram.add_be_uint32(_color_index);

View File

@ -59,12 +59,13 @@ FltTrans() :
void FltTrans::
run() {
if (_got_new_version) {
if (_new_version < FltHeader::min_flt_version() ||
_new_version > FltHeader::max_flt_version()) {
nout << "Cannot write flt files of version " << _new_version
int new_version = (int)floor(_new_version * 100.0 + 0.5);
if (new_version < FltHeader::min_flt_version() ||
new_version > FltHeader::max_flt_version()) {
nout << "Cannot write flt files of version " << new_version / 100.0
<< ". This program only understands how to write flt files between version "
<< FltHeader::min_flt_version() << " and "
<< FltHeader::max_flt_version() << ".\n";
<< FltHeader::min_flt_version() / 100.0 << " and "
<< FltHeader::max_flt_version() / 100.0 << ".\n";
exit(1);
}
}
@ -80,11 +81,12 @@ run() {
}
if (header->check_version()) {
nout << "Version is " << header->get_flt_version() << "\n";
nout << "Version is " << header->get_flt_version() / 100.0 << "\n";
}
if (_got_new_version) {
header->set_flt_version(_new_version);
int new_version = (int)floor(_new_version * 100.0 + 0.5);
header->set_flt_version(new_version);
}
result = header->write_flt(get_output());