better bamification

This commit is contained in:
David Rose 2002-03-21 23:34:55 +00:00
parent ecc7ea4d0c
commit 2b729db8e8
11 changed files with 220 additions and 10 deletions

View File

@ -28,6 +28,10 @@
#include "boundingLine.h" #include "boundingLine.h"
#include "qplensNode.h" #include "qplensNode.h"
#include "lens.h" #include "lens.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "lensNode.h" #include "lensNode.h"
#include "geomNode.h" #include "geomNode.h"
@ -259,3 +263,61 @@ fill_viz_geom() {
_viz_geom->add_geom(ray, get_other_viz_state()); _viz_geom->add_geom(ray, get_other_viz_state());
} }
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// CollisionRay.
////////////////////////////////////////////////////////////////////
void CollisionRay::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void CollisionRay::
write_datagram(BamWriter *manager, Datagram &dg) {
CollisionSolid::write_datagram(manager, dg);
_origin.write_datagram(dg);
_direction.write_datagram(dg);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type CollisionRay is encountered
// in the Bam file. It should create the CollisionRay
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
TypedWritable *CollisionRay::
make_from_bam(const FactoryParams &params) {
CollisionRay *node = new CollisionRay();
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
node->fillin(scan, manager);
return node;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionRay::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new CollisionRay.
////////////////////////////////////////////////////////////////////
void CollisionRay::
fillin(DatagramIterator &scan, BamReader *manager) {
CollisionSolid::fillin(scan, manager);
_origin.read_datagram(scan);
_direction.read_datagram(scan);
}

View File

@ -86,6 +86,14 @@ private:
LPoint3f _origin; LPoint3f _origin;
LVector3f _direction; LVector3f _direction;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);
protected:
static TypedWritable *make_from_bam(const FactoryParams &params);
void fillin(DatagramIterator &scan, BamReader *manager);
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -30,6 +30,10 @@
#include "lens.h" #include "lens.h"
#include "geomLine.h" #include "geomLine.h"
#include "geometricBoundingVolume.h" #include "geometricBoundingVolume.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "geomNode.h" #include "geomNode.h"
#include "lensNode.h" #include "lensNode.h"
@ -241,3 +245,61 @@ fill_viz_geom() {
_viz_geom->add_geom(segment, get_other_viz_state()); _viz_geom->add_geom(segment, get_other_viz_state());
} }
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// CollisionSegment.
////////////////////////////////////////////////////////////////////
void CollisionSegment::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void CollisionSegment::
write_datagram(BamWriter *manager, Datagram &dg) {
CollisionSolid::write_datagram(manager, dg);
_a.write_datagram(dg);
_b.write_datagram(dg);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type CollisionSegment is encountered
// in the Bam file. It should create the CollisionSegment
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
TypedWritable *CollisionSegment::
make_from_bam(const FactoryParams &params) {
CollisionSegment *node = new CollisionSegment();
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
node->fillin(scan, manager);
return node;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSegment::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new CollisionSegment.
////////////////////////////////////////////////////////////////////
void CollisionSegment::
fillin(DatagramIterator &scan, BamReader *manager) {
CollisionSolid::fillin(scan, manager);
_a.read_datagram(scan);
_b.read_datagram(scan);
}

View File

@ -88,6 +88,14 @@ protected:
private: private:
LPoint3f _a, _b; LPoint3f _a, _b;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);
protected:
static TypedWritable *make_from_bam(const FactoryParams &params);
void fillin(DatagramIterator &scan, BamReader *manager);
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -93,5 +93,7 @@ init_libcollide() {
qpCollisionNode::register_with_read_factory(); qpCollisionNode::register_with_read_factory();
CollisionPlane::register_with_read_factory(); CollisionPlane::register_with_read_factory();
CollisionPolygon::register_with_read_factory(); CollisionPolygon::register_with_read_factory();
CollisionRay::register_with_read_factory();
CollisionSegment::register_with_read_factory();
CollisionSphere::register_with_read_factory(); CollisionSphere::register_with_read_factory();
} }

View File

@ -1821,6 +1821,7 @@ register_with_read_factory() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void PandaNode:: void PandaNode::
write_datagram(BamWriter *manager, Datagram &dg) { write_datagram(BamWriter *manager, Datagram &dg) {
TypedWritable::write_datagram(manager, dg);
dg.add_string(get_name()); dg.add_string(get_name());
manager->write_cdata(dg, _cycler); manager->write_cdata(dg, _cycler);

View File

@ -123,9 +123,9 @@ public:
return _type_handle; return _type_handle;
} }
static void init_type() { static void init_type() {
TypedReferenceCount::init_type(); PandaNode::init_type();
register_type(_type_handle, "qpFog", register_type(_type_handle, "qpFog",
TypedReferenceCount::get_class_type()); PandaNode::get_class_type());
} }
virtual TypeHandle get_type() const { virtual TypeHandle get_type() const {
return get_class_type(); return get_class_type();

View File

@ -100,6 +100,9 @@ register_with_read_factory() {
void qpLensNode:: void qpLensNode::
write_datagram(BamWriter *manager, Datagram &dg) { write_datagram(BamWriter *manager, Datagram &dg) {
PandaNode::write_datagram(manager, dg); PandaNode::write_datagram(manager, dg);
// We should actually write out the lens. Easy to do, but not
// immediately pressing; I hope no one gets burned by the omission.
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -16,12 +16,13 @@
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include <pandabase.h> #include "pandabase.h"
#include <notify.h> #include "notify.h"
#include "config_util.h" #include "config_util.h"
#include "bam.h" #include "bam.h"
#include "bamWriter.h" #include "bamWriter.h"
#include "bamReader.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: BamWriter::Constructor // Function: BamWriter::Constructor
@ -129,6 +130,20 @@ write_object(const TypedWritable *object) {
TypeHandle type = object->get_type(); TypeHandle type = object->get_type();
nassertr(type != TypeHandle::none(), false); nassertr(type != TypeHandle::none(), false);
// Determine what the nearest kind of type is that the reader
// will be able to handle, and write that instead.
TypeHandle registered_type =
BamReader::get_factory()->find_registered_type(type);
if (registered_type == TypeHandle::none()) {
// We won't be able to read this type again.
util_cat.warning()
<< "Objects of type " << type << " cannot be read; bam file is invalid.\n";
} else if (registered_type != type) {
util_cat.info()
<< "Writing " << registered_type << " instead of " << type << "\n";
type = registered_type;
}
write_handle(dg, type); write_handle(dg, type);
dg.add_uint16(object_id); dg.add_uint16(object_id);
@ -358,7 +373,15 @@ enqueue_object(const TypedWritable *object) {
// No object should ever be written out that is not registered as a // No object should ever be written out that is not registered as a
// child of TypedWritable. The only way this can happen is if // child of TypedWritable. The only way this can happen is if
// someone failed to initialize their type correctly in init_type(). // someone failed to initialize their type correctly in init_type().
nassertr(object->is_of_type(TypedWritable::get_class_type()), 0); #ifndef NDEBUG
if (!object->is_of_type(TypedWritable::get_class_type())) {
util_cat.error()
<< "Type " << object->get_type()
<< " does not indicate inheritance from TypedWritable.\n"
<< "(this is almost certainly an oversight in " << object->get_type()
<< "::init_type().)\n";
}
#endif
// We need to assign a unique index number to every object we write // We need to assign a unique index number to every object we write
// out. Has this object been assigned a number yet? // out. Has this object been assigned a number yet?

View File

@ -80,15 +80,19 @@ make_instance(TypeHandle handle, const FactoryParams &params) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
TypedObject *FactoryBase:: TypedObject *FactoryBase::
make_instance_more_general(TypeHandle handle, const FactoryParams &params) { make_instance_more_general(TypeHandle handle, const FactoryParams &params) {
// Walk up the left side of the inheritance tree until we find
// something we know about.
TypedObject *object = make_instance_exact(handle, params); TypedObject *object = make_instance_exact(handle, params);
while (object == (TypedObject *)NULL) {
if (object == (TypedObject *)NULL) {
// Recursively search through the entire inheritance tree until we
// find something we know about.
if (handle.get_num_parent_classes() == 0) { if (handle.get_num_parent_classes() == 0) {
return NULL; return NULL;
} }
handle = handle.get_parent_class(0);
object = make_instance_exact(handle, params); int num_parents = handle.get_num_parent_classes();
for (int i = 0; i < num_parents && object == (TypedObject *)NULL; i++) {
object = make_instance_more_general(handle.get_parent_class(i), params);
}
} }
if (util_cat.is_debug()) { if (util_cat.is_debug()) {
@ -105,6 +109,41 @@ make_instance_more_general(TypeHandle handle, const FactoryParams &params) {
return object; return object;
} }
////////////////////////////////////////////////////////////////////
// Function: FactoryBase::find_registered_type
// Access: Public
// Description: Returns the TypeHandle given, if it is a registered
// type, or if it is not registered, searches for the
// nearest ancestor of the indicated type that is
// registered and returns it. If no ancestor of the
// indicated type is registered, returns
// TypeHandle::none().
////////////////////////////////////////////////////////////////////
TypeHandle FactoryBase::
find_registered_type(TypeHandle handle) {
Creators::const_iterator ci = _creators.find(handle);
if (ci != _creators.end()) {
// This type is registered.
return handle;
}
// Recursively search through the entire inheritance tree until we
// find something we know about.
if (handle.get_num_parent_classes() == 0) {
return TypeHandle::none();
}
int num_parents = handle.get_num_parent_classes();
for (int i = 0; i < num_parents; i++) {
TypeHandle result = find_registered_type(handle.get_parent_class(i));
if (result != TypeHandle::none()) {
return result;
}
}
// No known types.
return TypeHandle::none();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: FactoryBase::register_factory // Function: FactoryBase::register_factory

View File

@ -63,6 +63,8 @@ public:
INLINE TypedObject *make_instance_more_general(const string &type_name, INLINE TypedObject *make_instance_more_general(const string &type_name,
const FactoryParams &params); const FactoryParams &params);
TypeHandle find_registered_type(TypeHandle handle);
void register_factory(TypeHandle handle, BaseCreateFunc *func); void register_factory(TypeHandle handle, BaseCreateFunc *func);
int get_num_types() const; int get_num_types() const;