00001 // Filename: bamWriter.h 00002 // Created by: jason (08Jun00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #ifndef __BAM_WRITER_ 00020 #define __BAM_WRITER_ 00021 00022 #include "pandabase.h" 00023 #include "notify.h" 00024 00025 #include "typedWritable.h" 00026 #include "datagramSink.h" 00027 #include "pdeque.h" 00028 00029 struct PipelineCyclerBase; 00030 00031 // A handy macro for writing PointerToArrays. 00032 #define WRITE_PTA(Manager, dest, Write_func, array) \ 00033 if (!Manager->register_pta(dest, array.p())) \ 00034 { \ 00035 Write_func(dest, array); \ 00036 } \ 00037 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Class : BamWriter 00041 // Description : This is the fundamental interface for writing binary 00042 // objects to a Bam file, to be extracted later by a 00043 // BamReader. 00044 // 00045 // A Bam file can be thought of as a linear collection 00046 // of objects. Each object is an instance of a class 00047 // that inherits, directly or indirectly, from 00048 // TypedWritable. The objects may include pointers to 00049 // other objects; the BamWriter automatically manages 00050 // these (with help from code within each class) and 00051 // writes all referenced objects to the file in such a 00052 // way that the pointers may be correctly restored 00053 // later. 00054 // 00055 // This is the abstract interface and does not 00056 // specifically deal with disk files, but rather with a 00057 // DatagramSink of some kind, which simply accepts a 00058 // linear stream of Datagrams. It is probably written 00059 // to a disk file, but it might conceivably be streamed 00060 // directly to a network or some such nonsense. 00061 // 00062 // Bam files are most often used to store scene graphs 00063 // or subgraphs, and by convention they are given 00064 // filenames ending in the extension ".bam" when they 00065 // are used for this purpose. However, a Bam file may 00066 // store any arbitrary list of TypedWritable objects; 00067 // in this more general usage, they are given filenames 00068 // ending in ".boo" to differentiate them from the more 00069 // common scene graph files. 00070 // 00071 // See also BamFile, which defines a higher-level 00072 // interface to read and write Bam files on disk. 00073 //////////////////////////////////////////////////////////////////// 00074 class EXPCL_PANDA BamWriter{ 00075 public: 00076 BamWriter(DatagramSink *sink); 00077 ~BamWriter(); 00078 00079 // The primary interface for a caller. 00080 00081 bool init(); 00082 bool write_object(const TypedWritable *obj); 00083 bool has_object(const TypedWritable *obj) const; 00084 00085 public: 00086 // Functions to support classes that write themselves to the Bam. 00087 00088 void write_pointer(Datagram &packet, const TypedWritable *dest); 00089 void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler); 00090 bool register_pta(Datagram &packet, const void *ptr); 00091 void write_handle(Datagram &packet, TypeHandle type); 00092 00093 00094 00095 private: 00096 int enqueue_object(const TypedWritable *object); 00097 00098 00099 // This is the set of all TypeHandles already written. 00100 pset<int> _types_written; 00101 00102 // This keeps track of all of the objects we have written out 00103 // already (or are about to write out), and associates a unique 00104 // object ID number to each one. 00105 class StoreState { 00106 public: 00107 int _object_id; 00108 bool _written; 00109 00110 StoreState(int object_id) : _object_id(object_id), _written(false) {} 00111 }; 00112 typedef pmap<const TypedWritable *, StoreState> StateMap; 00113 StateMap _state_map; 00114 00115 // This is the next object ID that will be assigned to a new object. 00116 int _next_object_id; 00117 00118 // This is the queue of objects that need to be written when the 00119 // current object is finished. 00120 typedef pdeque<const TypedWritable *> ObjectQueue; 00121 ObjectQueue _object_queue; 00122 00123 // These are used by register_pta() to unify multiple references to 00124 // the same PointerToArray. 00125 typedef pmap<const void *, int> PTAMap; 00126 PTAMap _pta_map; 00127 int _next_pta_id; 00128 00129 // The destination to write all the output to. 00130 DatagramSink *_target; 00131 }; 00132 00133 #include "bamWriter.I" 00134 00135 #endif 00136