pgraph bam
This commit is contained in:
parent
02e35e725b
commit
5306f05c77
|
|
@ -75,7 +75,7 @@ fillin(DatagramIterator& scan, BamReader* manager)
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int AnimBundleNode::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader* manager)
|
||||
complete_pointers(TypedWritable **p_list, BamReader* manager)
|
||||
{
|
||||
int start = NamedNode::complete_pointers(p_list, manager);
|
||||
_bundle = DCAST(AnimBundle, p_list[start]);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
virtual int complete_pointers(TypedWritable **p_list,
|
||||
BamReader *manager);
|
||||
|
||||
static TypedWritable *make_AnimBundleNode(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ fillin(DatagramIterator& scan, BamReader* manager)
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int AnimGroup::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader*)
|
||||
complete_pointers(TypedWritable **p_list, BamReader*)
|
||||
{
|
||||
nassertr(p_list[0] != TypedWritable::Null, 0);
|
||||
_root = DCAST(AnimBundle, p_list[0]);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ protected:
|
|||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
virtual int complete_pointers(TypedWritable **p_list,
|
||||
BamReader *manager);
|
||||
|
||||
static TypedWritable *make_AnimGroup(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ fillin(DatagramIterator& scan, BamReader* manager)
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PartBundleNode::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader* manager)
|
||||
complete_pointers(TypedWritable **p_list, BamReader* manager)
|
||||
{
|
||||
int start = NamedNode::complete_pointers(p_list, manager);
|
||||
_bundle = DCAST(PartBundle, p_list[start]);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ private:
|
|||
|
||||
public:
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
virtual int complete_pointers(TypedWritable **p_list,
|
||||
BamReader *manager);
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ fillin(DatagramIterator& scan, BamReader* manager)
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PartGroup::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader*)
|
||||
complete_pointers(TypedWritable **p_list, BamReader*)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < _num_children; i++)
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ protected:
|
|||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
virtual int complete_pointers(TypedWritable **p_list,
|
||||
BamReader *manager);
|
||||
|
||||
static TypedWritable *make_PartGroup(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ fillin(DatagramIterator& scan, BamReader* manager)
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Character::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader* manager)
|
||||
complete_pointers(TypedWritable **p_list, BamReader* manager)
|
||||
{
|
||||
int start = PartBundleNode::complete_pointers(p_list, manager);
|
||||
_computed_vertices = DCAST(ComputedVertices, p_list[start]);
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
virtual int complete_pointers(TypedWritable **p_list,
|
||||
BamReader *manager);
|
||||
|
||||
static TypedWritable *make_Character(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ fillin(DatagramIterator& scan, BamReader* manager)
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int CharacterJoint::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader* manager)
|
||||
complete_pointers(TypedWritable **p_list, BamReader* manager)
|
||||
{
|
||||
int i;
|
||||
int start = MovingPartMatrix::complete_pointers(p_list, manager);
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
virtual int complete_pointers(TypedWritable **p_list,
|
||||
BamReader *manager);
|
||||
|
||||
static TypedWritable *make_CharacterJoint(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ fillin(DatagramIterator& scan, BamReader* manager)
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int CollisionNode::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader* manager) {
|
||||
complete_pointers(TypedWritable **p_list, BamReader* manager) {
|
||||
int num_solids = _solids.size();
|
||||
int start = NamedNode::complete_pointers(p_list, manager);
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &plist,
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
static TypedWritable *make_CollisionNode(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -170,13 +170,6 @@ public:
|
|||
INLINE CoordinateSystem get_coordinate_system() const;
|
||||
virtual CoordinateSystem get_internal_coordinate_system() const;
|
||||
|
||||
// This function may only be called during a render traversal; it
|
||||
// will compute the distance to the indicated point, assumed to be
|
||||
// in modelview coordinates, from the camera plane. This is a
|
||||
// virtual function because different GSG's may define the modelview
|
||||
// coordinate space differently.
|
||||
virtual float compute_distance_to(const LPoint3f &point) const=0;
|
||||
|
||||
INLINE void clear_cached_state(void) { _state.clear(); };
|
||||
|
||||
virtual void issue_transform(const TransformState *transform);
|
||||
|
|
|
|||
|
|
@ -507,7 +507,7 @@ fillin(DatagramIterator &scan, BamReader *manager)
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int LensFlareNode::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader *manager)
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager)
|
||||
{
|
||||
int i;
|
||||
int start = Node::complete_pointers(p_list, manager);
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &plist,
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
static TypedWritable *make_LensFlareNode(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@
|
|||
|
||||
#include "loaderFileTypeEgg.h"
|
||||
#include "load_egg_file.h"
|
||||
#include "qpload_egg_file.h"
|
||||
|
||||
#include <eggData.h>
|
||||
#include "eggData.h"
|
||||
|
||||
TypeHandle LoaderFileTypeEgg::_type_handle;
|
||||
|
||||
|
|
@ -74,3 +75,14 @@ load_file(const Filename &path, bool) const {
|
|||
PT_NamedNode result = load_egg_file(path);
|
||||
return result.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LoaderFileTypeEgg::load_file
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PandaNode) LoaderFileTypeEgg::
|
||||
qpload_file(const Filename &path, bool) const {
|
||||
PT(PandaNode) result = qpload_egg_file(path);
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@
|
|||
#ifndef LOADERFILETYPEEGG_H
|
||||
#define LOADERFILETYPEEGG_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#include <loaderFileType.h>
|
||||
#include "loaderFileType.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : LoaderFileTypeEgg
|
||||
|
|
@ -36,6 +36,7 @@ public:
|
|||
|
||||
virtual void resolve_filename(Filename &path) const;
|
||||
virtual PT_Node load_file(const Filename &path, bool report_errors) const;
|
||||
virtual PT(PandaNode) qpload_file(const Filename &path, bool report_errors) const;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ register_with_read_factory(void) {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomSprite::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader *manager) {
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int index = Geom::complete_pointers(p_list, manager);
|
||||
_texture = DCAST(Texture, p_list[index]);
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public:
|
|||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &me);
|
||||
|
||||
int complete_pointers(vector_typedWritable &plist, BamReader *manager);
|
||||
int complete_pointers(TypedWritable **plist, BamReader *manager);
|
||||
static TypedWritable *make_GeomSprite(const FactoryParams ¶ms);
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -562,7 +562,7 @@ write_datagram(BamWriter *manager, Datagram &me) {
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Node::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader *manager) {
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
if (manager->get_file_minor_ver() < 3) {
|
||||
// In bam versions before 3.3, this function does nothing (since
|
||||
// the arcs are completely responsible for adding themselves to
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ protected:
|
|||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &plist,
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
static TypedWritable *make_Node(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -902,7 +902,7 @@ write_datagram(BamWriter *manager, Datagram &me)
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int NodeRelation::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader *manager) {
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
nassertr(p_list[0] != TypedWritable::Null &&
|
||||
p_list[1] != TypedWritable::Null, 0);
|
||||
_parent = DCAST(Node, p_list[0]);
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &plist,
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
static TypedWritable *make_NodeRelation(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#begin lib_target
|
||||
#define TARGET gsgbase
|
||||
#define LOCAL_LIBS \
|
||||
putil graph
|
||||
putil graph linmath
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "typedReferenceCount.h"
|
||||
#include "nodeTransitions.h"
|
||||
#include "luse.h"
|
||||
|
||||
// A handful of forward references.
|
||||
|
||||
|
|
@ -148,6 +149,13 @@ public:
|
|||
virtual void set_state_and_transform(const RenderState *state,
|
||||
const TransformState *transform)=0;
|
||||
|
||||
// This function may only be called during a render traversal; it
|
||||
// will compute the distance to the indicated point, assumed to be
|
||||
// in modelview coordinates, from the camera plane. This is a
|
||||
// virtual function because different GSG's may define the modelview
|
||||
// coordinate space differently.
|
||||
virtual float compute_distance_to(const LPoint3f &point) const=0;
|
||||
|
||||
// Defined here are some internal interface functions for the
|
||||
// GraphicsStateGuardian. These are here to support
|
||||
// double-dispatching from Geoms and NodeTransitions, and are
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#begin lib_target
|
||||
#define TARGET loader
|
||||
#define LOCAL_LIBS \
|
||||
event graph ipc putil express downloader
|
||||
event pgraph graph ipc putil express downloader
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
|
|
|
|||
|
|
@ -192,13 +192,7 @@ write_object(const TypedWritable *object) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// We'll go ahead and cast the const TypedWritable pointer to a
|
||||
// non-const for issuing the actual write. This allows
|
||||
// write_datagram to be defined in such a way that it can modify
|
||||
// itself in some minor way if it must; we assume that no class will
|
||||
// abuse this privilege and modify its contents significantly during
|
||||
// write_datagram().
|
||||
if (!_writer->write_object((TypedWritable *)object)) {
|
||||
if (!_writer->write_object(object)) {
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,3 +28,16 @@ load_sync(const Filename &filename) const {
|
|||
}
|
||||
return load_file(filename);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Loader::load_sync
|
||||
// Access: Public
|
||||
// Description: Loads the file immediately, waiting for it to complete.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(PandaNode) Loader::
|
||||
qpload_sync(const Filename &filename) const {
|
||||
if (!_file_types_loaded) {
|
||||
load_file_types();
|
||||
}
|
||||
return qpload_file(filename);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,22 +20,19 @@
|
|||
#include "loaderFileTypeRegistry.h"
|
||||
#include "config_loader.h"
|
||||
|
||||
#include <event.h>
|
||||
#include <pt_Event.h>
|
||||
#include <throw_event.h>
|
||||
#include <eventParameter.h>
|
||||
#include <circBuffer.h>
|
||||
#include <filename.h>
|
||||
#include <load_dso.h>
|
||||
#include "event.h"
|
||||
#include "pt_Event.h"
|
||||
#include "throw_event.h"
|
||||
#include "eventParameter.h"
|
||||
#include "circBuffer.h"
|
||||
#include "filename.h"
|
||||
#include "load_dso.h"
|
||||
|
||||
#include "plist.h"
|
||||
#include "pvector.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Defines
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Loader::_file_types_loaded = false;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -337,6 +334,51 @@ load_file(const Filename &filename) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Loader::load_file
|
||||
// Access: Private
|
||||
// Description: Loads a single scene graph file, if possible.
|
||||
// Returns the Node that is the root of the file, or
|
||||
// NULL if the file cannot be loaded.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PandaNode) Loader::
|
||||
qpload_file(const Filename &filename) const {
|
||||
string extension = filename.get_extension();
|
||||
|
||||
if (extension.empty()) {
|
||||
return qpload_unknown_file_type(filename);
|
||||
}
|
||||
|
||||
LoaderFileTypeRegistry *reg = LoaderFileTypeRegistry::get_ptr();
|
||||
LoaderFileType *requested_type =
|
||||
reg->get_type_from_extension(extension);
|
||||
|
||||
if (requested_type == (LoaderFileType *)NULL) {
|
||||
loader_cat.error()
|
||||
<< "Extension of file " << filename
|
||||
<< " is unrecognized; cannot load.\n";
|
||||
loader_cat.error(false)
|
||||
<< "Currently known scene file types are:\n";
|
||||
reg->write_types(loader_cat.error(false), 2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Filename requested_filename = filename;
|
||||
if (!requested_filename.is_fully_qualified()) {
|
||||
// Ask the loader type to look for the file along its paths.
|
||||
requested_type->resolve_filename(requested_filename);
|
||||
}
|
||||
|
||||
if (loader_cat.is_debug()) {
|
||||
loader_cat.debug()
|
||||
<< "Loading " << requested_type->get_name() << " file: "
|
||||
<< requested_filename << "\n";
|
||||
}
|
||||
|
||||
PT(PandaNode) result = requested_type->qpload_file(requested_filename, true);
|
||||
return result;
|
||||
}
|
||||
|
||||
class LoaderConsiderFile {
|
||||
public:
|
||||
Filename _path;
|
||||
|
|
@ -436,6 +478,94 @@ load_unknown_file_type(const Filename &filename) const {
|
|||
return (Node *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Loader::load_unknown_file_type
|
||||
// Access: Private
|
||||
// Description: Attempts to guess which file is meant when a file
|
||||
// with no extension is given. Looks around for a file
|
||||
// with a suitable extension for each of our known file
|
||||
// types, and loads the most recent file available of
|
||||
// any file type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PandaNode) Loader::
|
||||
qpload_unknown_file_type(const Filename &filename) const {
|
||||
typedef pvector<LoaderConsiderFile> Files;
|
||||
Files files;
|
||||
|
||||
// First, build up a list of all of the possible files it could be.
|
||||
LoaderFileTypeRegistry *reg = LoaderFileTypeRegistry::get_ptr();
|
||||
int num_types = reg->get_num_types();
|
||||
|
||||
if (num_types == 0) {
|
||||
loader_cat.error()
|
||||
<< "Can't load file " << filename
|
||||
<< "; no scene file types are known.\n";
|
||||
return (PandaNode *)NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_types; i++) {
|
||||
LoaderConsiderFile consider;
|
||||
consider._type = reg->get_type(i);
|
||||
consider._path = filename;
|
||||
consider._path.set_extension(consider._type->get_extension());
|
||||
|
||||
if (!consider._path.is_fully_qualified()) {
|
||||
// Ask the loader type to look for the file along its paths.
|
||||
consider._type->resolve_filename(consider._path);
|
||||
}
|
||||
|
||||
if (consider._path.exists()) {
|
||||
files.push_back(consider);
|
||||
}
|
||||
}
|
||||
|
||||
if (files.empty()) {
|
||||
loader_cat.error()
|
||||
<< "Couldn't find file " << filename << " as:\n";
|
||||
for (int i = 0; i < num_types; i++) {
|
||||
Filename p = filename;
|
||||
p.set_extension(reg->get_type(i)->get_extension());
|
||||
loader_cat.error(false)
|
||||
<< " " << p << "\n";
|
||||
}
|
||||
return (PandaNode *)NULL;
|
||||
}
|
||||
|
||||
// Now sort the list into order by timestamp, from newest to oldest.
|
||||
sort(files.begin(), files.end());
|
||||
|
||||
// And try to load each file one at a time.
|
||||
Files::const_iterator fi;
|
||||
|
||||
if (loader_cat.is_debug()) {
|
||||
loader_cat.debug()
|
||||
<< "Loading " << filename << ", one of " << files.size()
|
||||
<< " possible types:\n";
|
||||
for (fi = files.begin(); fi != files.end(); ++fi) {
|
||||
loader_cat.debug(false)
|
||||
<< " " << (*fi)._path << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
for (fi = files.begin(); fi != files.end(); ++fi) {
|
||||
const LoaderConsiderFile &consider = (*fi);
|
||||
PT(PandaNode) result = consider._type->qpload_file(consider._path, false);
|
||||
if (result != (PandaNode *)NULL) {
|
||||
return result;
|
||||
}
|
||||
if (loader_cat.is_debug()) {
|
||||
loader_cat.debug()
|
||||
<< "Couldn't read " << consider._type->get_name()
|
||||
<< " file " << consider._path << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
loader_cat.error()
|
||||
<< "Cannot read " << files.front()._path << "\n";
|
||||
|
||||
return (PandaNode *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Loader::resolve_unknown_file_type
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -17,18 +17,16 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
#ifndef LOADER_H
|
||||
#define LOADER_H
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include <pandabase.h>
|
||||
|
||||
#include <notify.h>
|
||||
#include <node.h>
|
||||
#include <pt_Node.h>
|
||||
#include <filename.h>
|
||||
#include <tokenBoard.h>
|
||||
#include <asyncUtility.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "notify.h"
|
||||
#include "node.h"
|
||||
#include "pt_Node.h"
|
||||
#include "pandaNode.h"
|
||||
#include "filename.h"
|
||||
#include "tokenBoard.h"
|
||||
#include "asyncUtility.h"
|
||||
|
||||
class LoaderToken;
|
||||
|
||||
|
|
@ -45,6 +43,7 @@ PUBLISHED:
|
|||
void resolve_filename(Filename &filename) const;
|
||||
|
||||
INLINE PT_Node load_sync(const Filename &filename) const;
|
||||
INLINE PT(PandaNode) qpload_sync(const Filename &filename) const;
|
||||
|
||||
uint request_load(const Filename &filename, const string &event_name);
|
||||
bool check_load(uint id);
|
||||
|
|
@ -57,6 +56,8 @@ private:
|
|||
virtual bool process_request(void);
|
||||
PT_Node load_file(const Filename &filename) const;
|
||||
PT_Node load_unknown_file_type(const Filename &filename) const;
|
||||
PT(PandaNode) qpload_file(const Filename &filename) const;
|
||||
PT(PandaNode) qpload_unknown_file_type(const Filename &filename) const;
|
||||
void resolve_unknown_file_type(Filename &filename) const;
|
||||
|
||||
typedef TokenBoard<LoaderToken> LoaderTokenBoard;
|
||||
|
|
|
|||
|
|
@ -51,3 +51,16 @@ LoaderFileType::
|
|||
void LoaderFileType::
|
||||
resolve_filename(Filename &) const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LoaderFileType::load_file
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PandaNode) LoaderFileType::
|
||||
qpload_file(const Filename &path, bool report_errors) const
|
||||
{
|
||||
loader_cat.error()
|
||||
<< get_type() << " cannot read PandaNode objects.\n";
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@
|
|||
#ifndef LOADERFILETYPE_H
|
||||
#define LOADERFILETYPE_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#include <typedObject.h>
|
||||
#include <node.h>
|
||||
#include <pt_Node.h>
|
||||
#include <filename.h>
|
||||
#include "typedObject.h"
|
||||
#include "node.h"
|
||||
#include "pt_Node.h"
|
||||
#include "filename.h"
|
||||
#include "pandaNode.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : LoaderFileType
|
||||
|
|
@ -45,6 +47,7 @@ public:
|
|||
|
||||
virtual void resolve_filename(Filename &path) const;
|
||||
virtual PT_Node load_file(const Filename &path, bool report_errors) const=0;
|
||||
virtual PT(PandaNode) qpload_file(const Filename &path, bool report_errors) const;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
|
|
@ -121,3 +121,53 @@ load_file(const Filename &path, bool report_errors) const
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LoaderFileTypeBam::load_file
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PandaNode) LoaderFileTypeBam::
|
||||
qpload_file(const Filename &path, bool report_errors) const {
|
||||
BamFile bam_file;
|
||||
if (!bam_file.open_read(path, report_errors)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PT(PandaNode) result;
|
||||
|
||||
TypedWritable *object = bam_file.read_object();
|
||||
if (object == TypedWritable::Null) {
|
||||
if (report_errors) {
|
||||
loader_cat.error() << "Bam file " << path << " is empty.\n";
|
||||
}
|
||||
|
||||
} else if (!object->is_of_type(PandaNode::get_class_type())) {
|
||||
if (report_errors) {
|
||||
loader_cat.error()
|
||||
<< "Bam file " << path
|
||||
<< " contains a " << object->get_type() << ", not a PandaNode.\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
result = DCAST(PandaNode, object);
|
||||
|
||||
if (report_errors) {
|
||||
bam_file.read_object();
|
||||
if (!bam_file.is_eof()) {
|
||||
loader_cat.warning()
|
||||
<< "Ignoring extra objects in " << path << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bam_file.resolve()) {
|
||||
if (report_errors) {
|
||||
loader_cat.error()
|
||||
<< "Unable to resolve Bam file.\n";
|
||||
result = (PandaNode *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@
|
|||
#ifndef LOADERFILETYPEBAM_H
|
||||
#define LOADERFILETYPEBAM_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "loaderFileType.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : LoaderFileTypeEgg
|
||||
// Description : This defines the Loader interface to read Egg files.
|
||||
// Class : LoaderFileTypeBam
|
||||
// Description : This defines the Loader interface to read Bam files.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA LoaderFileTypeBam : public LoaderFileType {
|
||||
public:
|
||||
|
|
@ -36,6 +36,7 @@ public:
|
|||
|
||||
virtual void resolve_filename(Filename &path) const;
|
||||
virtual PT_Node load_file(const Filename &path, bool report_errors) const;
|
||||
virtual PT(PandaNode) qpload_file(const Filename &path, bool report_errors) const;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
|
|
@ -625,11 +625,9 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PiecewiseCurve::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader *manager) {
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int used = ParametricCurve::complete_pointers(p_list, manager);
|
||||
|
||||
nassertr(used + _segs.size() <= p_list.size(), used);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < _segs.size(); i++) {
|
||||
_segs[i]._curve = DCAST(ParametricCurve, p_list[used + i]);
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ protected:
|
|||
protected:
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &me);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
virtual int complete_pointers(vector_typedWritable &plist,
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -220,6 +220,16 @@ register_with_read_factory() {
|
|||
void BillboardAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
|
||||
dg.add_bool(_off);
|
||||
_up_vector.write_datagram(dg);
|
||||
dg.add_bool(_eye_relative);
|
||||
dg.add_bool(_axial_rotate);
|
||||
dg.add_float32(_offset);
|
||||
_look_at_point.write_datagram(dg);
|
||||
|
||||
// *** We don't write out the _look_at NodeChain right now. Maybe
|
||||
// we should.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -239,7 +249,7 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return new_from_bam(attrib, manager);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -252,4 +262,11 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
void BillboardAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
|
||||
_off = scan.get_bool();
|
||||
_up_vector.read_datagram(scan);
|
||||
_eye_relative = scan.get_bool();
|
||||
_axial_rotate = scan.get_bool();
|
||||
_offset = scan.get_float32();
|
||||
_look_at_point.read_datagram(scan);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,6 +165,9 @@ register_with_read_factory() {
|
|||
void ColorAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
|
||||
dg.add_int8(_type);
|
||||
_color.write_datagram(dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -184,7 +187,7 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return new_from_bam(attrib, manager);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -197,4 +200,7 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
void ColorAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
|
||||
_type = (Type)scan.get_int8();
|
||||
_color.read_datagram(scan);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ init_libpgraph() {
|
|||
|
||||
BillboardAttrib::register_with_read_factory();
|
||||
ColorAttrib::register_with_read_factory();
|
||||
CullBinAttrib::register_with_read_factory();
|
||||
CullFaceAttrib::register_with_read_factory();
|
||||
qpGeomNode::register_with_read_factory();
|
||||
PandaNode::register_with_read_factory();
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ register_with_read_factory() {
|
|||
void CullBinAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
|
||||
dg.add_string(_bin_name);
|
||||
dg.add_int32(_draw_order);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -135,7 +138,7 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return new_from_bam(attrib, manager);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -148,4 +151,7 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
void CullBinAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
|
||||
_bin_name = scan.get_string();
|
||||
_draw_order = scan.get_int32();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,6 +137,8 @@ register_with_read_factory() {
|
|||
void CullFaceAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
|
||||
dg.add_int8(_mode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -156,7 +158,7 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return new_from_bam(attrib, manager);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -169,4 +171,6 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
void CullFaceAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
|
||||
_mode = (Mode)scan.get_int8();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ make_copy() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *PandaNode::
|
||||
copy_subgraph() const {
|
||||
//*** Do something here.
|
||||
// *** Do something here.
|
||||
nassertr(false, (PandaNode *)NULL);
|
||||
return (PandaNode *)NULL;
|
||||
}
|
||||
|
|
@ -903,6 +903,57 @@ register_with_read_factory() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
dg.add_string(get_name());
|
||||
manager->write_pointer(dg, cdata->_state);
|
||||
manager->write_pointer(dg, cdata->_transform);
|
||||
|
||||
// When we write a PandaNode, we write out its list of child nodes,
|
||||
// but not its parent nodes--so that writing out a node implicitly
|
||||
// writes out all of the nodes in the subgraph below, but not the
|
||||
// nodes above as well.
|
||||
|
||||
int num_children = cdata->_down.size();
|
||||
nassertv(num_children == (int)(PN_uint16)num_children);
|
||||
dg.add_uint16(num_children);
|
||||
|
||||
// **** We should smarten up the writing of the sort number--most of
|
||||
// the time these will all be zero.
|
||||
Down::const_iterator ci;
|
||||
for (ci = cdata->_down.begin(); ci != cdata->_down.end(); ++ci) {
|
||||
PandaNode *child = (*ci).get_child();
|
||||
int sort = (*ci).get_sort();
|
||||
manager->write_pointer(dg, child);
|
||||
dg.add_int32(sort);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::complete_pointers
|
||||
// Access: Public, Virtual
|
||||
// Description: Receives an array of pointers, one for each time
|
||||
// manager->read_pointer() was called in fillin().
|
||||
// Returns the number of pointers processed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PandaNode::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
CDWriter cdata(_cycler);
|
||||
int pi = TypedWritable::complete_pointers(p_list, manager);
|
||||
|
||||
// Get the state and transform pointers.
|
||||
cdata->_state = DCAST(RenderState, p_list[pi++]);
|
||||
cdata->_transform = DCAST(TransformState, p_list[pi++]);
|
||||
|
||||
// Get the child pointers.
|
||||
Down::iterator ci;
|
||||
for (ci = cdata->_down.begin(); ci != cdata->_down.end(); ++ci) {
|
||||
int sort = (*ci).get_sort();
|
||||
PT(PandaNode) node = DCAST(PandaNode, p_list[pi++]);
|
||||
(*ci) = DownConnection(node, sort);
|
||||
}
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -934,4 +985,23 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
TypedWritable::fillin(scan, manager);
|
||||
|
||||
string name = scan.get_string();
|
||||
set_name(name);
|
||||
|
||||
// Read the state and transform pointers.
|
||||
manager->read_pointer(scan, this);
|
||||
manager->read_pointer(scan, this);
|
||||
|
||||
int num_children = scan.get_uint16();
|
||||
// Read the list of child nodes. Push back a NULL for each one.
|
||||
cdata->_down.reserve(num_children);
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
manager->read_pointer(scan, this);
|
||||
int sort = scan.get_int32();
|
||||
cdata->_down.push_back(DownConnection(NULL, sort));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,6 +235,8 @@ public:
|
|||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ r_traverse(PandaNode *node,
|
|||
if (node->is_final()) {
|
||||
// The bounding volume is partially, but not completely,
|
||||
// within the viewing frustum. Normally we'd keep testing
|
||||
// child bounded volumes as we continue down. But this node
|
||||
// child bounding volumes as we continue down. But this node
|
||||
// has the "final" flag, so the user is claiming that there is
|
||||
// some important reason we should consider everything visible
|
||||
// at this point. So be it.
|
||||
|
|
|
|||
|
|
@ -212,6 +212,42 @@ register_with_read_factory() {
|
|||
void qpGeomNode::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
PandaNode::write_datagram(manager, dg);
|
||||
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
int num_geoms = cdata->_geoms.size();
|
||||
nassertv(num_geoms == (int)(PN_uint16)num_geoms);
|
||||
dg.add_uint16(num_geoms);
|
||||
|
||||
Geoms::const_iterator gi;
|
||||
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||
const GeomEntry &entry = (*gi);
|
||||
manager->write_pointer(dg, entry._geom);
|
||||
manager->write_pointer(dg, entry._state);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomNode::complete_pointers
|
||||
// Access: Public, Virtual
|
||||
// Description: Receives an array of pointers, one for each time
|
||||
// manager->read_pointer() was called in fillin().
|
||||
// Returns the number of pointers processed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomNode::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
CDWriter cdata(_cycler);
|
||||
int pi = PandaNode::complete_pointers(p_list, manager);
|
||||
|
||||
// Get the geom and state pointers.
|
||||
Geoms::iterator gi;
|
||||
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||
GeomEntry &entry = (*gi);
|
||||
entry._geom = DCAST(Geom, p_list[pi++]);
|
||||
entry._state = DCAST(RenderState, p_list[pi++]);
|
||||
}
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -243,5 +279,16 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomNode::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
PandaNode::fillin(scan, manager);
|
||||
|
||||
int num_geoms = scan.get_uint16();
|
||||
// Read the list of geoms and states. Push back a NULL for each one.
|
||||
cdata->_geoms.reserve(num_geoms);
|
||||
for (int i = 0; i < num_geoms; i++) {
|
||||
manager->read_pointer(scan, this);
|
||||
manager->read_pointer(scan, this);
|
||||
cdata->_geoms.push_back(GeomEntry(NULL, NULL));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -218,7 +218,40 @@ make_default_impl() const {
|
|||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RenderAttrib::
|
||||
write_datagram(BamWriter *, Datagram &) {
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
TypedWritable::write_datagram(manager, dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::change_this
|
||||
// Access: Public, Static
|
||||
// Description: Called immediately after complete_pointers(), this
|
||||
// gives the object a chance to adjust its own pointer
|
||||
// if desired. Most objects don't change pointers after
|
||||
// completion, but some need to.
|
||||
//
|
||||
// Once this function has been called, the old pointer
|
||||
// will no longer be accessed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *RenderAttrib::
|
||||
change_this(TypedWritable *old_ptr, BamReader *manager) {
|
||||
// First, uniquify the pointer.
|
||||
RenderAttrib *attrib = DCAST(RenderAttrib, old_ptr);
|
||||
CPT(RenderAttrib) pointer = return_new(attrib);
|
||||
|
||||
// But now we have a problem, since we have to hold the reference
|
||||
// count and there's no way to return a TypedWritable while still
|
||||
// holding the reference count! We work around this by explicitly
|
||||
// upping the count, and also setting a finalize() callback to down
|
||||
// it later.
|
||||
if (pointer == attrib) {
|
||||
pointer->ref();
|
||||
manager->register_finalize(attrib);
|
||||
}
|
||||
|
||||
// We have to cast the pointer back to non-const, because the bam
|
||||
// reader expects that.
|
||||
return (RenderAttrib *)pointer.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -240,33 +273,6 @@ finalize() {
|
|||
nassertv(get_ref_count() != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::new_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: Uniquifies the pointer for a RenderAttrib object just
|
||||
// created from a bam file, and preserves its reference
|
||||
// count correctly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *RenderAttrib::
|
||||
new_from_bam(RenderAttrib *attrib, BamReader *manager) {
|
||||
// First, uniquify the pointer.
|
||||
CPT(RenderAttrib) pointer = return_new(attrib);
|
||||
|
||||
// But now we have a problem, since we have to hold the reference
|
||||
// count and there's no way to return a TypedWritable while still
|
||||
// holding the reference count! We work around this by explicitly
|
||||
// upping the count, and also setting a finalize() callback to down
|
||||
// it later.
|
||||
if (pointer == attrib) {
|
||||
pointer->ref();
|
||||
manager->register_finalize(attrib);
|
||||
}
|
||||
|
||||
// We have to cast the pointer back to non-const, because the bam
|
||||
// reader expects that.
|
||||
return (RenderAttrib *)pointer.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderAttrib::fillin
|
||||
// Access: Protected
|
||||
|
|
@ -276,4 +282,5 @@ new_from_bam(RenderAttrib *attrib, BamReader *manager) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
TypedWritable::fillin(scan, manager);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ private:
|
|||
|
||||
public:
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
|
||||
virtual void finalize();
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -30,6 +30,19 @@ Attribute(const RenderAttrib *attrib, int override) :
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::Attribute::Constructor
|
||||
// Access: Public
|
||||
// Description: This constructor is only used when reading the
|
||||
// RenderState from a bam file. At this point, the
|
||||
// attribute pointer is unknown.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE RenderState::Attribute::
|
||||
Attribute(int override) :
|
||||
_override(override)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::Attribute::Constructor
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -929,13 +929,91 @@ register_with_read_factory() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
TypedWritable::write_datagram(manager, dg);
|
||||
|
||||
int num_attribs = _attributes.size();
|
||||
nassertv(num_attribs == (int)(PN_uint16)num_attribs);
|
||||
dg.add_uint16(num_attribs);
|
||||
|
||||
// **** We should smarten up the writing of the override
|
||||
// number--most of the time these will all be zero.
|
||||
Attributes::const_iterator ai;
|
||||
for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) {
|
||||
const Attribute &attribute = (*ai);
|
||||
|
||||
manager->write_pointer(dg, attribute._attrib);
|
||||
dg.add_int32(attribute._override);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::complete_pointers
|
||||
// Access: Public, Virtual
|
||||
// Description: Receives an array of pointers, one for each time
|
||||
// manager->read_pointer() was called in fillin().
|
||||
// Returns the number of pointers processed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int RenderState::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = TypedWritable::complete_pointers(p_list, manager);
|
||||
|
||||
// Get the attribute pointers.
|
||||
Attributes::iterator ai;
|
||||
for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) {
|
||||
Attribute &attribute = (*ai);
|
||||
|
||||
attribute._attrib = DCAST(RenderAttrib, p_list[pi++]);
|
||||
nassertr(attribute._attrib != (RenderAttrib *)NULL, pi);
|
||||
attribute._type = attribute._attrib->get_type();
|
||||
}
|
||||
|
||||
// Now make sure the array is properly sorted. (It won't
|
||||
// necessarily preserve its correct sort after being read from bam,
|
||||
// because the sort is based on TypeHandle indices, which can change
|
||||
// from session to session.)
|
||||
_attributes.sort();
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::change_this
|
||||
// Access: Public, Static
|
||||
// Description: Called immediately after complete_pointers(), this
|
||||
// gives the object a chance to adjust its own pointer
|
||||
// if desired. Most objects don't change pointers after
|
||||
// completion, but some need to.
|
||||
//
|
||||
// Once this function has been called, the old pointer
|
||||
// will no longer be accessed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *RenderState::
|
||||
change_this(TypedWritable *old_ptr, BamReader *manager) {
|
||||
// First, uniquify the pointer.
|
||||
RenderState *state = DCAST(RenderState, old_ptr);
|
||||
CPT(RenderState) pointer = return_new(state);
|
||||
|
||||
// But now we have a problem, since we have to hold the reference
|
||||
// count and there's no way to return a TypedWritable while still
|
||||
// holding the reference count! We work around this by explicitly
|
||||
// upping the count, and also setting a finalize() callback to down
|
||||
// it later.
|
||||
if (pointer == state) {
|
||||
pointer->ref();
|
||||
manager->register_finalize(state);
|
||||
}
|
||||
|
||||
// We have to cast the pointer back to non-const, because the bam
|
||||
// reader expects that.
|
||||
return (RenderState *)pointer.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::finalize
|
||||
// Access: Public, Virtual
|
||||
// Description: Method to ensure that any necessary clean up tasks
|
||||
// that have to be performed by this object are performed
|
||||
// Description: Called by the BamReader to perform any final actions
|
||||
// needed for setting up the object after all objects
|
||||
// have been read and all pointers have been completed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
finalize() {
|
||||
|
|
@ -966,35 +1044,9 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
|
||||
parse_params(params, scan, manager);
|
||||
state->fillin(scan, manager);
|
||||
manager->register_change_this(change_this, state);
|
||||
|
||||
return new_from_bam(state, manager);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::new_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: Uniquifies the pointer for a RenderState object just
|
||||
// created from a bam file, and preserves its reference
|
||||
// count correctly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *RenderState::
|
||||
new_from_bam(RenderState *state, BamReader *manager) {
|
||||
// First, uniquify the pointer.
|
||||
CPT(RenderState) pointer = return_new(state);
|
||||
|
||||
// But now we have a problem, since we have to hold the reference
|
||||
// count and there's no way to return a TypedWritable while still
|
||||
// holding the reference count! We work around this by explicitly
|
||||
// upping the count, and also setting a finalize() callback to down
|
||||
// it later.
|
||||
if (pointer == state) {
|
||||
pointer->ref();
|
||||
manager->register_finalize(state);
|
||||
}
|
||||
|
||||
// We have to cast the pointer back to non-const, because the bam
|
||||
// reader expects that.
|
||||
return (RenderState *)pointer.p();
|
||||
return state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1006,4 +1058,16 @@ new_from_bam(RenderState *state, BamReader *manager) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void RenderState::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
TypedWritable::fillin(scan, manager);
|
||||
|
||||
int num_attribs = scan.get_uint16();
|
||||
|
||||
// Push back a NULL pointer for each attribute for now, until we get
|
||||
// the actual list of pointers later in complete_pointers().
|
||||
_attributes.reserve(num_attribs);
|
||||
for (int i = 0; i < num_attribs; i++) {
|
||||
manager->read_pointer(scan, this);
|
||||
int override = scan.get_int32();
|
||||
_attributes.push_back(Attribute(override));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ private:
|
|||
class Attribute {
|
||||
public:
|
||||
INLINE Attribute(const RenderAttrib *attrib, int override);
|
||||
INLINE Attribute(int override);
|
||||
INLINE Attribute(TypeHandle type);
|
||||
INLINE Attribute(const Attribute ©);
|
||||
INLINE void operator = (const Attribute ©);
|
||||
|
|
@ -173,11 +174,12 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
|
||||
static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
|
||||
virtual void finalize();
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
static TypedWritable *new_from_bam(RenderState *state, BamReader *manager);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -137,6 +137,27 @@ register_with_read_factory() {
|
|||
void TextureAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
|
||||
manager->write_pointer(dg, _texture);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureAttrib::complete_pointers
|
||||
// Access: Public, Virtual
|
||||
// Description: Receives an array of pointers, one for each time
|
||||
// manager->read_pointer() was called in fillin().
|
||||
// Returns the number of pointers processed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int TextureAttrib::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = RenderAttrib::complete_pointers(p_list, manager);
|
||||
|
||||
TypedWritable *texture = p_list[pi++];
|
||||
if (texture != (TypedWritable *)NULL) {
|
||||
_texture = DCAST(Texture, texture);
|
||||
}
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -156,7 +177,7 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return new_from_bam(attrib, manager);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -169,4 +190,7 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
void TextureAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
|
||||
// Read the _texture pointer.
|
||||
manager->read_pointer(scan, this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -577,13 +577,69 @@ register_with_read_factory() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TransformState::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
TypedWritable::write_datagram(manager, dg);
|
||||
|
||||
if ((_flags & F_is_identity) != 0) {
|
||||
// Identity, nothing much to that.
|
||||
int flags = F_is_identity | F_singular_known;
|
||||
dg.add_uint16(flags);
|
||||
|
||||
} else if ((_flags & F_components_given) != 0) {
|
||||
// A component-based transform.
|
||||
int flags = F_components_given | F_components_known | F_has_components;
|
||||
dg.add_uint16(flags);
|
||||
|
||||
_pos.write_datagram(dg);
|
||||
_hpr.write_datagram(dg);
|
||||
_scale.write_datagram(dg);
|
||||
|
||||
} else {
|
||||
// A general matrix.
|
||||
nassertv((_flags & F_mat_known) != 0);
|
||||
int flags = F_mat_known;
|
||||
dg.add_uint16(flags);
|
||||
_mat.write_datagram(dg);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::change_this
|
||||
// Access: Public, Static
|
||||
// Description: Called immediately after complete_pointers(), this
|
||||
// gives the object a chance to adjust its own pointer
|
||||
// if desired. Most objects don't change pointers after
|
||||
// completion, but some need to.
|
||||
//
|
||||
// Once this function has been called, the old pointer
|
||||
// will no longer be accessed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *TransformState::
|
||||
change_this(TypedWritable *old_ptr, BamReader *manager) {
|
||||
// First, uniquify the pointer.
|
||||
TransformState *state = DCAST(TransformState, old_ptr);
|
||||
CPT(TransformState) pointer = return_new(state);
|
||||
|
||||
// But now we have a problem, since we have to hold the reference
|
||||
// count and there's no way to return a TypedWritable while still
|
||||
// holding the reference count! We work around this by explicitly
|
||||
// upping the count, and also setting a finalize() callback to down
|
||||
// it later.
|
||||
if (pointer == state) {
|
||||
pointer->ref();
|
||||
manager->register_finalize(state);
|
||||
}
|
||||
|
||||
// We have to cast the pointer back to non-const, because the bam
|
||||
// reader expects that.
|
||||
return (TransformState *)pointer.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::finalize
|
||||
// Access: Public, Virtual
|
||||
// Description: Method to ensure that any necessary clean up tasks
|
||||
// that have to be performed by this object are performed
|
||||
// Description: Called by the BamReader to perform any final actions
|
||||
// needed for setting up the object after all objects
|
||||
// have been read and all pointers have been completed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TransformState::
|
||||
finalize() {
|
||||
|
|
@ -614,35 +670,9 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
|
||||
parse_params(params, scan, manager);
|
||||
state->fillin(scan, manager);
|
||||
manager->register_change_this(change_this, state);
|
||||
|
||||
return new_from_bam(state, manager);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::new_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: Uniquifies the pointer for a TransformState object just
|
||||
// created from a bam file, and preserves its reference
|
||||
// count correctly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *TransformState::
|
||||
new_from_bam(TransformState *state, BamReader *manager) {
|
||||
// First, uniquify the pointer.
|
||||
CPT(TransformState) pointer = return_new(state);
|
||||
|
||||
// But now we have a problem, since we have to hold the reference
|
||||
// count and there's no way to return a TypedWritable while still
|
||||
// holding the reference count! We work around this by explicitly
|
||||
// upping the count, and also setting a finalize() callback to down
|
||||
// it later.
|
||||
if (pointer == state) {
|
||||
pointer->ref();
|
||||
manager->register_finalize(state);
|
||||
}
|
||||
|
||||
// We have to cast the pointer back to non-const, because the bam
|
||||
// reader expects that.
|
||||
return (TransformState *)pointer.p();
|
||||
return state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -654,4 +684,19 @@ new_from_bam(TransformState *state, BamReader *manager) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TransformState::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
TypedWritable::fillin(scan, manager);
|
||||
|
||||
_flags = scan.get_uint16();
|
||||
|
||||
if ((_flags & F_components_known) != 0) {
|
||||
// Componentwise transform.
|
||||
_pos.read_datagram(scan);
|
||||
_hpr.read_datagram(scan);
|
||||
_scale.read_datagram(scan);
|
||||
}
|
||||
|
||||
if ((_flags & F_mat_known) != 0) {
|
||||
// General matrix.
|
||||
_mat.read_datagram(scan);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,11 +151,11 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
|
||||
virtual void finalize();
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
static TypedWritable *new_from_bam(TransformState *state, BamReader *manager);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -142,6 +142,8 @@ register_with_read_factory() {
|
|||
void TransparencyAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
|
||||
dg.add_int8(_mode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -161,7 +163,7 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return new_from_bam(attrib, manager);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -174,4 +176,6 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
void TransparencyAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
|
||||
_mode = (Mode)scan.get_int8();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ BamReader(DatagramGenerator *generator)
|
|||
: _source(generator)
|
||||
{
|
||||
_num_extra_objects = 0;
|
||||
_now_creating = _created_objs.end();
|
||||
_pta_id = -1;
|
||||
}
|
||||
|
||||
|
|
@ -177,7 +178,8 @@ read_object() {
|
|||
return (TypedWritable *)NULL;
|
||||
|
||||
} else {
|
||||
TypedWritable *object = (*oi).second;
|
||||
CreatedObj &created_obj = (*oi).second;
|
||||
TypedWritable *object = created_obj._ptr;
|
||||
|
||||
if (bam_cat.is_spam()) {
|
||||
if (object != (TypedWritable *)NULL) {
|
||||
|
|
@ -185,6 +187,11 @@ read_object() {
|
|||
<< "Returning object of type " << object->get_type() << "\n";
|
||||
}
|
||||
}
|
||||
if (created_obj._change_this != NULL) {
|
||||
bam_cat.warning()
|
||||
<< "Returning pointer to " << object->get_type()
|
||||
<< " that might change.\n";
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
|
@ -210,68 +217,116 @@ read_object() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool BamReader::
|
||||
resolve() {
|
||||
bool all_completed = true;
|
||||
bool all_completed;
|
||||
bool any_completed_this_pass;
|
||||
|
||||
// Walk through all the objects that still have outstanding pointers.
|
||||
Requests::iterator ri;
|
||||
ri = _deferred_pointers.begin();
|
||||
while (ri != _deferred_pointers.end()) {
|
||||
TypedWritable *whom = (*ri).first;
|
||||
const vector_ushort &pointers = (*ri).second;
|
||||
do {
|
||||
all_completed = true;
|
||||
any_completed_this_pass = false;
|
||||
|
||||
// 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_typedWritable 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((TypedWritable *)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;
|
||||
// Walk through all the objects that still have outstanding pointers.
|
||||
Requests::iterator ri;
|
||||
ri = _deferred_pointers.begin();
|
||||
while (ri != _deferred_pointers.end()) {
|
||||
int object_id = (*ri).first;
|
||||
const vector_int &children = (*ri).second;
|
||||
|
||||
CreatedObjs::iterator ci = _created_objs.find(object_id);
|
||||
nassertr(ci != _created_objs.end(), false);
|
||||
CreatedObj &created_obj = (*ci).second;
|
||||
|
||||
TypedWritable *object_ptr = created_obj._ptr;
|
||||
|
||||
// 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_typedWritable references;
|
||||
|
||||
vector_int::const_iterator pi;
|
||||
for (pi = children.begin(); pi != children.end() && is_complete; ++pi) {
|
||||
int child_id = (*pi);
|
||||
|
||||
if (child_id == 0) {
|
||||
// A NULL pointer is a NULL pointer.
|
||||
references.push_back((TypedWritable *)NULL);
|
||||
|
||||
} else {
|
||||
// Yes, it's ready.
|
||||
references.push_back((*oi).second);
|
||||
// See if we have the pointer available now.
|
||||
CreatedObjs::const_iterator oi = _created_objs.find(child_id);
|
||||
if (oi == _created_objs.end()) {
|
||||
// No, too bad.
|
||||
is_complete = false;
|
||||
|
||||
} else {
|
||||
const CreatedObj &child_obj = (*oi).second;
|
||||
if (child_obj._change_this != NULL) {
|
||||
// It's been created, but the pointer might still change.
|
||||
is_complete = false;
|
||||
|
||||
} else {
|
||||
// Yes, it's ready.
|
||||
references.push_back(child_obj._ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_complete) {
|
||||
// Okay, here's the complete list of pointers for you!
|
||||
int num_completed = object_ptr->complete_pointers(&references[0], this);
|
||||
if (num_completed != (int)references.size()) {
|
||||
bam_cat.warning()
|
||||
<< object_ptr->get_type() << " completed " << num_completed
|
||||
<< " of " << references.size() << " pointers.\n";
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Does the pointer need to change?
|
||||
if (created_obj._change_this != NULL) {
|
||||
created_obj._ptr = created_obj._change_this(object_ptr, this);
|
||||
created_obj._change_this = NULL;
|
||||
}
|
||||
any_completed_this_pass = true;
|
||||
|
||||
} else {
|
||||
// Couldn't complete this object yet; it'll wait for next time.
|
||||
++ri;
|
||||
all_completed = false;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
} while (!all_completed && any_completed_this_pass);
|
||||
|
||||
if (all_completed) {
|
||||
finalize();
|
||||
} else {
|
||||
// Report all the uncompleted objects for no good reason. This
|
||||
// will probably have to come out later when we have cases in
|
||||
// which some objects might legitimately be uncompleted after
|
||||
// calling resolve(), but for now we expect resolve() to always
|
||||
// succeed.
|
||||
Requests::const_iterator ri;
|
||||
for (ri = _deferred_pointers.begin();
|
||||
ri != _deferred_pointers.end();
|
||||
++ri) {
|
||||
int object_id = (*ri).first;
|
||||
CreatedObjs::iterator ci = _created_objs.find(object_id);
|
||||
nassertr(ci != _created_objs.end(), false);
|
||||
CreatedObj &created_obj = (*ci).second;
|
||||
TypedWritable *object_ptr = created_obj._ptr;
|
||||
|
||||
bam_cat.warning()
|
||||
<< "Unable to complete " << object_ptr->get_type() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return all_completed;
|
||||
|
|
@ -381,9 +436,26 @@ read_handle(DatagramIterator &scan) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void BamReader::
|
||||
read_pointer(DatagramIterator &scan, TypedWritable *for_whom) {
|
||||
nassertv(_now_creating != _created_objs.end());
|
||||
int requestor_id = (*_now_creating).first;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// A bit of sanity checking here: we look up the object ID, and
|
||||
// assign the "this" pointer into the record if it's not there
|
||||
// already. Then we can verify the "this" pointer later.
|
||||
CreatedObj &created_obj = (*_now_creating).second;
|
||||
if (created_obj._ptr == (TypedWritable *)NULL) {
|
||||
created_obj._ptr = for_whom;
|
||||
} else {
|
||||
// We've previously assigned this pointer, and we should have
|
||||
// assigned it to the same this pointer we have now.
|
||||
nassertv(created_obj._ptr == for_whom);
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
// 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);
|
||||
_deferred_pointers[requestor_id].push_back(object_id);
|
||||
|
||||
// If the object ID is zero (which indicates a NULL pointer), we
|
||||
// don't have to do anything else.
|
||||
|
|
@ -447,6 +519,44 @@ register_finalize(TypedWritable *whom) {
|
|||
_finalize_list.insert(whom);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamReader::register_change_this
|
||||
// Access: Public
|
||||
// Description: Called by an object reading itself from the bam file
|
||||
// to indicate that the object pointer that will be
|
||||
// returned is temporary, and will eventually need to be
|
||||
// replaced with another pointer.
|
||||
//
|
||||
// The supplied function pointer will later be called on
|
||||
// the object, immediately after complete_pointers() is
|
||||
// called; it should return the new and final pointer.
|
||||
//
|
||||
// We use a static function pointer instead of a virtual
|
||||
// function (as in finalize()), to allow the function to
|
||||
// destruct the old pointer if necessary. (It is
|
||||
// invalid to destruct the this pointer within a virtual
|
||||
// function.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BamReader::
|
||||
register_change_this(ChangeThisFunc func, TypedWritable *object) {
|
||||
nassertv(_now_creating != _created_objs.end());
|
||||
CreatedObj &created_obj = (*_now_creating).second;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Sanity check the pointer--it should always be the same pointer
|
||||
// after we set it the first time.
|
||||
if (created_obj._ptr == (TypedWritable *)NULL) {
|
||||
created_obj._ptr = object;
|
||||
} else {
|
||||
// We've previously assigned this pointer, and we should have
|
||||
// assigned it to the same this pointer we have now.
|
||||
nassertv(created_obj._ptr == object);
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
created_obj._change_this = func;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamReader::finalize_now
|
||||
// Access: Public
|
||||
|
|
@ -597,16 +707,43 @@ p_read_object() {
|
|||
// 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.
|
||||
// the object. For now, we give it a NULL pointer.
|
||||
CreatedObj new_created_obj;
|
||||
new_created_obj._ptr = NULL;
|
||||
new_created_obj._change_this = NULL;
|
||||
CreatedObjs::iterator oi =
|
||||
_created_objs.insert(CreatedObjs::value_type(object_id, NULL)).first;
|
||||
_created_objs.insert(CreatedObjs::value_type(object_id, new_created_obj)).first;
|
||||
CreatedObj &created_obj = (*oi).second;
|
||||
|
||||
// Now we can call the factory to create the object.
|
||||
// Now we can call the factory to create the object. Update
|
||||
// _now_creating during this call so if this function calls
|
||||
// read_pointer() or register_change_this() we'll match it up
|
||||
// properly. This might recursively call back into this
|
||||
// p_read_object(), so be sure to save and restore the original
|
||||
// value of _now_creating.
|
||||
CreatedObjs::iterator was_creating = _now_creating;
|
||||
_now_creating = oi;
|
||||
TypedWritable *object =
|
||||
_factory->make_instance_more_general(type, fparams);
|
||||
_now_creating = was_creating;
|
||||
|
||||
// And now we can store the new object pointer in the map.
|
||||
(*oi).second = object;
|
||||
nassertr(created_obj._ptr == object || created_obj._ptr == NULL, object_id);
|
||||
created_obj._ptr = object;
|
||||
|
||||
if (created_obj._change_this != NULL) {
|
||||
// If the pointer is scheduled to change after
|
||||
// complete_pointers(), but we have no entry in
|
||||
// _deferred_pointers for this object (and hence no plan to call
|
||||
// complete_pointers()), then just change the pointer
|
||||
// immediately.
|
||||
Requests::const_iterator ri = _deferred_pointers.find(object_id);
|
||||
if (ri == _deferred_pointers.end()) {
|
||||
object = created_obj._change_this(object, this);
|
||||
created_obj._ptr = object;
|
||||
created_obj._change_this = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//Just some sanity checks
|
||||
if (object == (TypedWritable *)NULL) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "datagramIterator.h"
|
||||
#include "bamReaderParam.h"
|
||||
#include "factory.h"
|
||||
#include "vector_ushort.h"
|
||||
#include "vector_int.h"
|
||||
#include "pset.h"
|
||||
#include "dcast.h"
|
||||
|
||||
|
|
@ -114,6 +114,9 @@ public:
|
|||
|
||||
void register_finalize(TypedWritable *whom);
|
||||
|
||||
typedef TypedWritable *(*ChangeThisFunc)(TypedWritable *object, BamReader *manager);
|
||||
void register_change_this(ChangeThisFunc func, TypedWritable *whom);
|
||||
|
||||
void finalize_now(TypedWritable *whom);
|
||||
|
||||
void *get_pta(DatagramIterator &scan);
|
||||
|
|
@ -143,13 +146,23 @@ private:
|
|||
|
||||
// This maps the object ID numbers encountered within the Bam file
|
||||
// to the actual pointers of the corresponding generated objects.
|
||||
typedef pmap<int, TypedWritable *> CreatedObjs;
|
||||
class CreatedObj {
|
||||
public:
|
||||
TypedWritable *_ptr;
|
||||
ChangeThisFunc _change_this;
|
||||
};
|
||||
typedef pmap<int, CreatedObj> CreatedObjs;
|
||||
CreatedObjs _created_objs;
|
||||
// This is the iterator into the above map for the object we are
|
||||
// currently reading in p_read_object(). It is carefully maintained
|
||||
// during recursion. We need this so we can associate
|
||||
// read_pointer() calls with the proper objects.
|
||||
CreatedObjs::iterator _now_creating;
|
||||
|
||||
// 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 pmap<TypedWritable *, vector_ushort> Requests;
|
||||
typedef pmap<int, vector_int> Requests;
|
||||
Requests _deferred_pointers;
|
||||
|
||||
// This is the number of extra objects that must still be read (and
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ init() {
|
|||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BamWriter::
|
||||
write_object(TypedWritable *object) {
|
||||
write_object(const TypedWritable *object) {
|
||||
nassertr(_object_queue.empty(), false);
|
||||
|
||||
int object_id = enqueue_object(object);
|
||||
|
|
@ -132,7 +132,14 @@ write_object(TypedWritable *object) {
|
|||
write_handle(dg, type);
|
||||
dg.add_uint16(object_id);
|
||||
|
||||
object->write_datagram(this, dg);
|
||||
// We cast the const pointer to non-const so that we may call
|
||||
// write_datagram() on it. Really, write_datagram() should be a
|
||||
// const method anyway, but there may be times when a class
|
||||
// object wants to update some transparent cache value during
|
||||
// writing or something like that, so it's more convenient to
|
||||
// cheat and define it as a non-const method.
|
||||
((TypedWritable *)object)->write_datagram(this, dg);
|
||||
|
||||
(*si).second._written = true;
|
||||
|
||||
} else {
|
||||
|
|
@ -170,10 +177,10 @@ write_object(TypedWritable *object) {
|
|||
// automatically be written.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BamWriter::
|
||||
write_pointer(Datagram &packet, TypedWritable *object) {
|
||||
write_pointer(Datagram &packet, const TypedWritable *object) {
|
||||
// If the pointer is NULL, we always simply write a zero for an
|
||||
// object ID and leave it at that.
|
||||
if (object == (TypedWritable *)NULL) {
|
||||
if (object == (const TypedWritable *)NULL) {
|
||||
packet.add_uint16(0);
|
||||
|
||||
} else {
|
||||
|
|
@ -211,8 +218,8 @@ write_pointer(Datagram &packet, TypedWritable *object) {
|
|||
// the work that must be done to write a PTA.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BamWriter::
|
||||
register_pta(Datagram &packet, void *ptr) {
|
||||
if (ptr == (void *)NULL) {
|
||||
register_pta(Datagram &packet, const void *ptr) {
|
||||
if (ptr == (const void *)NULL) {
|
||||
// A zero for the PTA ID indicates a NULL pointer. This is a
|
||||
// special case.
|
||||
packet.add_uint16(0);
|
||||
|
|
@ -313,7 +320,7 @@ write_handle(Datagram &packet, TypeHandle type) {
|
|||
// an error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int BamWriter::
|
||||
enqueue_object(TypedWritable *object) {
|
||||
enqueue_object(const TypedWritable *object) {
|
||||
Datagram dg;
|
||||
|
||||
nassertr(object != TypedWritable::Null, 0);
|
||||
|
|
|
|||
|
|
@ -77,17 +77,17 @@ public:
|
|||
// The primary interface for a caller.
|
||||
|
||||
bool init();
|
||||
bool write_object(TypedWritable *obj);
|
||||
bool write_object(const TypedWritable *obj);
|
||||
|
||||
public:
|
||||
// Functions to support classes that write themselves to the Bam.
|
||||
|
||||
void write_pointer(Datagram &packet, TypedWritable *dest);
|
||||
bool register_pta(Datagram &packet, void *ptr);
|
||||
void write_pointer(Datagram &packet, const TypedWritable *dest);
|
||||
bool register_pta(Datagram &packet, const void *ptr);
|
||||
void write_handle(Datagram &packet, TypeHandle type);
|
||||
|
||||
private:
|
||||
int enqueue_object(TypedWritable *object);
|
||||
int enqueue_object(const TypedWritable *object);
|
||||
|
||||
|
||||
// This is the set of all TypeHandles already written.
|
||||
|
|
@ -103,7 +103,7 @@ private:
|
|||
|
||||
StoreState(int object_id) : _object_id(object_id), _written(false) {}
|
||||
};
|
||||
typedef pmap<TypedWritable *, StoreState> StateMap;
|
||||
typedef pmap<const TypedWritable *, StoreState> StateMap;
|
||||
StateMap _state_map;
|
||||
|
||||
// This is the next object ID that will be assigned to a new object.
|
||||
|
|
@ -111,12 +111,12 @@ private:
|
|||
|
||||
// This is the queue of objects that need to be written when the
|
||||
// current object is finished.
|
||||
typedef pdeque<TypedWritable *> ObjectQueue;
|
||||
typedef pdeque<const TypedWritable *> ObjectQueue;
|
||||
ObjectQueue _object_queue;
|
||||
|
||||
// These are used by register_pta() to unify multiple references to
|
||||
// the same PointerToArray.
|
||||
typedef pmap<void *, int> PTAMap;
|
||||
typedef pmap<const void *, int> PTAMap;
|
||||
PTAMap _pta_map;
|
||||
int _next_pta_id;
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ fillin(Person* me, DatagramIterator& scan, BamReader* manager)
|
|||
}
|
||||
|
||||
int Person::
|
||||
complete_pointers(vector_typedWritable& p_list, BamReader *)
|
||||
complete_pointers(TypedWritable **p_list, BamReader *)
|
||||
{
|
||||
_bro = (p_list[0] == TypedWritable::Null) ? (Person*)NULL : DCAST(Person, p_list[0]);
|
||||
_sis = (p_list[1] == TypedWritable::Null) ? (Person*)NULL : DCAST(Person, p_list[1]);
|
||||
|
|
@ -127,7 +127,7 @@ fillin(Parent* me, DatagramIterator& scan, BamReader* manager)
|
|||
}
|
||||
|
||||
int Parent::
|
||||
complete_pointers(vector_typedWritable& p_list, BamReader *manager)
|
||||
complete_pointers(TypedWritable *p_list, BamReader *manager)
|
||||
{
|
||||
int start = Person::complete_pointers(p_list, manager);
|
||||
_son = (p_list[start] == TypedWritable::Null) ? (Child*)NULL : DCAST(Child, p_list[2]);
|
||||
|
|
@ -187,7 +187,7 @@ fillin(Child* me, DatagramIterator& scan, BamReader* manager)
|
|||
}
|
||||
|
||||
int Child::
|
||||
complete_pointers(vector_typedWritable& p_list, BamReader *manager)
|
||||
complete_pointers(TypedWritable ** p_list, BamReader *manager)
|
||||
{
|
||||
int start = Person::complete_pointers(p_list, manager);
|
||||
_dad = (p_list[start] == TypedWritable::Null) ? (Parent*)NULL : DCAST(Parent, p_list[2]);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public:
|
|||
void write_datagram(BamWriter*, Datagram&);
|
||||
|
||||
static TypedWritable *make_person(const FactoryParams ¶ms);
|
||||
virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
virtual int complete_pointers(TypedWritable **p_list,
|
||||
BamReader *manager);
|
||||
protected:
|
||||
void fillin(Person*,DatagramIterator&,BamReader*);
|
||||
|
|
@ -93,7 +93,7 @@ public:
|
|||
void write_datagram(BamWriter*, Datagram&);
|
||||
|
||||
static TypedWritable *make_parent(const FactoryParams ¶ms);
|
||||
virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
virtual int complete_pointers(TypedWritable *p_list,
|
||||
BamReader *manager);
|
||||
protected:
|
||||
void fillin(Parent*,DatagramIterator&,BamReader*);
|
||||
|
|
@ -139,7 +139,7 @@ public:
|
|||
void write_datagram(BamWriter*, Datagram&);
|
||||
|
||||
static TypedWritable *make_child(const FactoryParams ¶ms);
|
||||
virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
virtual int complete_pointers(TypedWritable **p_list,
|
||||
BamReader *manager);
|
||||
protected:
|
||||
void fillin(Child*,DatagramIterator&,BamReader*);
|
||||
|
|
|
|||
|
|
@ -26,20 +26,72 @@ TypedWritable* const TypedWritable::Null = (TypedWritable*)0L;
|
|||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable::~TypedWritable()
|
||||
{
|
||||
TypedWritable::~TypedWritable() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypedWritable::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TypedWritable::
|
||||
write_datagram(BamWriter *, Datagram &) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypedWritable::complete_pointers
|
||||
// Access: Public, Virtual
|
||||
// Description: Takes in a vector of pointers to TypedWritable
|
||||
// objects that correspond to all the requests for
|
||||
// pointers that this object made to BamReader.
|
||||
// Description: Receives an array of pointers, one for each time
|
||||
// manager->read_pointer() was called in fillin().
|
||||
// Returns the number of pointers processed.
|
||||
//
|
||||
// This is the callback function that is made by the
|
||||
// BamReader at some later point, after all of the
|
||||
// required pointers have been filled in. It is
|
||||
// necessary because there might be forward references
|
||||
// in a bam file; when we call read_pointer() in
|
||||
// fillin(), the object may not have been read from the
|
||||
// file yet, so we do not have a pointer available at
|
||||
// that time. Thus, instead of returning a pointer,
|
||||
// read_pointer() simply reserves a later callback.
|
||||
// This function provides that callback. The calling
|
||||
// object is responsible for keeping track of the number
|
||||
// of times it called read_pointer() and extracting the
|
||||
// same number of pointers out of the supplied vector,
|
||||
// and storing them appropriately within the object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int TypedWritable::
|
||||
complete_pointers(vector_typedWritable &, BamReader*)
|
||||
{
|
||||
complete_pointers(TypedWritable **, BamReader *) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypedWritable::finalize
|
||||
// Access: Public, Virtual
|
||||
// Description: Called by the BamReader to perform any final actions
|
||||
// needed for setting up the object after all objects
|
||||
// have been read and all pointers have been completed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TypedWritable::
|
||||
finalize() {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypedWritable::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is intended to be called by
|
||||
// each class's make_from_bam() method to read in all of
|
||||
// the relevant data from the BamFile for the new
|
||||
// object.
|
||||
//
|
||||
// It is defined at the TypedWritable level so that
|
||||
// derived classes may call up the inheritance chain
|
||||
// from their own fillin() method.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TypedWritable::
|
||||
fillin(DatagramIterator &, BamReader *) {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,20 +27,11 @@ class BamReader;
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : TypedWritable
|
||||
// Description : Convience class to not have to derive from TypedObject
|
||||
// and writable all the time
|
||||
//
|
||||
// Important : Every class derived from TypedWritable that is
|
||||
// not an abstract class, MUST define a factory method
|
||||
// for creating and object of that type. This method
|
||||
// must be static. This method must be of the form
|
||||
// static <class type*> make_<appropriate name>(const FactoryParams &)
|
||||
// Also, in the config file for each package, make sure
|
||||
// to add in code to the ConfigureFN to register the
|
||||
// creation function with BamReader's factory.
|
||||
// Description : Base class for objects that can be written to and
|
||||
// read from Bam files.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
class EXPCL_PANDA TypedWritable : public TypedObject, public Writable {
|
||||
class EXPCL_PANDA TypedWritable : public TypedObject {
|
||||
public:
|
||||
static TypedWritable* const Null;
|
||||
|
||||
|
|
@ -50,30 +41,14 @@ public:
|
|||
|
||||
virtual ~TypedWritable();
|
||||
|
||||
//The essential virtual function interface to define
|
||||
//how any writable object, writes itself to a datagram
|
||||
virtual void write_datagram(BamWriter *, Datagram &) = 0;
|
||||
virtual void write_datagram(BamWriter *, Datagram &);
|
||||
|
||||
//This function is the interface through which BamReader is
|
||||
//able to pass the completed object references into each
|
||||
//object that requested them.
|
||||
//In other words, if an object (when it is creating itself
|
||||
//from a datagram) requests BamReader to generate an object
|
||||
//that this object points to, this is the function that is
|
||||
//eventually called by BamReader to complete those references.
|
||||
//Return the number of pointers read. This is useful for when
|
||||
//a parent reads in a variable number of pointers, so the child
|
||||
//knows where to start reading from.
|
||||
virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
BamReader *manager);
|
||||
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager);
|
||||
|
||||
virtual void finalize();
|
||||
|
||||
protected:
|
||||
//This interface function is written here, as a suggestion
|
||||
//for a function to write in any class that will have children
|
||||
//that are also TypedWritable. To encourage code re-use
|
||||
|
||||
//virtual void fillin(TypedWritable*, DatagramIterator&, BamReader *);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
PUBLISHED:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
@ -82,6 +57,9 @@ PUBLISHED:
|
|||
|
||||
public:
|
||||
static void init_type() {
|
||||
// We no longer derive from Writable, but we continue to record
|
||||
// that derivation for now, just to keep bam files consistent
|
||||
// until we move to bam version 4.0.
|
||||
TypedObject::init_type();
|
||||
Writable::init_type();
|
||||
register_type(_type_handle, "TypedWritable",
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public:
|
|||
//Return the number of pointers read. This is useful for when
|
||||
//a parent reads in a variable number of pointers, so the child
|
||||
//knows where to start reading from.
|
||||
//virtual int complete_pointers(vector_typedWritable &p_list,
|
||||
//virtual int complete_pointers(TypedWritable **p_list,
|
||||
// BamReader *manager) {}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ write_datagram(BamWriter *manager, Datagram &me) {
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int MaterialTransition::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader *) {
|
||||
complete_pointers(TypedWritable **p_list, BamReader *) {
|
||||
if (p_list[0] == TypedWritable::Null) {
|
||||
if (sgattrib_cat.is_debug()) {
|
||||
sgattrib_cat->debug()
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &plist,
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ write_datagram(BamWriter *manager, Datagram &me) {
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int TextureTransition::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader *) {
|
||||
complete_pointers(TypedWritable **p_list, BamReader *) {
|
||||
if (p_list[0] == TypedWritable::Null) {
|
||||
if (sgattrib_cat.is_debug()) {
|
||||
sgattrib_cat->debug()
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &plist,
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ write_datagram(BamWriter *manager, Datagram &me)
|
|||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomNode::
|
||||
complete_pointers(vector_typedWritable &p_list, BamReader* manager)
|
||||
complete_pointers(TypedWritable **p_list, BamReader* manager)
|
||||
{
|
||||
int start = NamedNode::complete_pointers(p_list, manager);
|
||||
for(int i = start; i < _num_geoms+start; i++)
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ private:
|
|||
public:
|
||||
static void register_with_read_factory(void);
|
||||
virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
virtual int complete_pointers(vector_typedWritable &plist,
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
static TypedWritable *make_GeomNode(const FactoryParams ¶ms);
|
||||
|
|
|
|||
|
|
@ -26,14 +26,12 @@
|
|||
|
||||
#end bin_target
|
||||
|
||||
#begin test_bin_target
|
||||
#begin bin_target
|
||||
#define TARGET pview
|
||||
|
||||
#define SOURCES \
|
||||
pview.cxx
|
||||
|
||||
#define LOCAL_LIBS egg2pg pgraph $[LOCAL_LIBS]
|
||||
#end test_bin_target
|
||||
#end bin_target
|
||||
|
||||
#begin test_bin_target
|
||||
#define TARGET open_window
|
||||
|
|
|
|||
|
|
@ -32,10 +32,8 @@
|
|||
#include "geomTri.h"
|
||||
#include "texture.h"
|
||||
#include "texturePool.h"
|
||||
|
||||
// To load egg files directly.
|
||||
#include "qpload_egg_file.h"
|
||||
#include "eggData.h"
|
||||
#include "dSearchPath.h"
|
||||
#include "loader.h"
|
||||
|
||||
// These are in support of legacy data graph operations.
|
||||
#include "namedNode.h"
|
||||
|
|
@ -199,13 +197,20 @@ get_models(PandaNode *parent, int argc, char *argv[]) {
|
|||
make_default_geometry(parent);
|
||||
|
||||
} else {
|
||||
Loader loader;
|
||||
DSearchPath local_path(".");
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
Filename filename = argv[i];
|
||||
|
||||
cerr << "Loading " << filename << "\n";
|
||||
EggData::resolve_egg_filename(filename);
|
||||
PT(PandaNode) node = qpload_egg_file(filename);
|
||||
|
||||
// First, we always try to resolve a filename from the current
|
||||
// directory. This means a local filename will always be found
|
||||
// before the model path is searched.
|
||||
filename.resolve_filename(local_path);
|
||||
|
||||
PT(PandaNode) node = loader.qpload_sync(filename);
|
||||
if (node == (PandaNode *)NULL) {
|
||||
cerr << "Unable to load " << filename << "\n";
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue