Panda3D
 All Classes Functions Variables Enumerations
bamWriter.h
1 // Filename: bamWriter.h
2 // Created by: jason (08Jun00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef __BAM_WRITER_
16 #define __BAM_WRITER_
17 
18 #include "pandabase.h"
19 #include "pnotify.h"
20 #include "bamEnums.h"
21 #include "typedWritable.h"
22 #include "datagramSink.h"
23 #include "pdeque.h"
24 #include "pset.h"
25 #include "pmap.h"
26 #include "vector_int.h"
27 #include "pipelineCyclerBase.h"
28 
29 
30 // A handy macro for writing PointerToArrays.
31 #define WRITE_PTA(Manager, dest, Write_func, array) \
32  if (!Manager->register_pta(dest, array.p())) \
33  { \
34  Write_func(Manager, dest, array); \
35  } \
36 
37 
38 ////////////////////////////////////////////////////////////////////
39 // Class : BamWriter
40 // Description : This is the fundamental interface for writing binary
41 // objects to a Bam file, to be extracted later by a
42 // BamReader.
43 //
44 // A Bam file can be thought of as a linear collection
45 // of objects. Each object is an instance of a class
46 // that inherits, directly or indirectly, from
47 // TypedWritable. The objects may include pointers to
48 // other objects; the BamWriter automatically manages
49 // these (with help from code within each class) and
50 // writes all referenced objects to the file in such a
51 // way that the pointers may be correctly restored
52 // later.
53 //
54 // This is the abstract interface and does not
55 // specifically deal with disk files, but rather with a
56 // DatagramSink of some kind, which simply accepts a
57 // linear stream of Datagrams. It is probably written
58 // to a disk file, but it might conceivably be streamed
59 // directly to a network or some such nonsense.
60 //
61 // Bam files are most often used to store scene graphs
62 // or subgraphs, and by convention they are given
63 // filenames ending in the extension ".bam" when they
64 // are used for this purpose. However, a Bam file may
65 // store any arbitrary list of TypedWritable objects;
66 // in this more general usage, they are given filenames
67 // ending in ".boo" to differentiate them from the more
68 // common scene graph files.
69 //
70 // See also BamFile, which defines a higher-level
71 // interface to read and write Bam files on disk.
72 ////////////////////////////////////////////////////////////////////
73 class EXPCL_PANDA_PUTIL BamWriter : public BamEnums {
74 PUBLISHED:
75  BamWriter(DatagramSink *target = NULL);
76  ~BamWriter();
77 
78  void set_target(DatagramSink *target);
79  INLINE DatagramSink *get_target();
80 
81  bool init();
82  INLINE const Filename &get_filename() const;
83  bool write_object(const TypedWritable *obj);
84  bool has_object(const TypedWritable *obj) const;
85  void flush();
86 
87  INLINE BamEndian get_file_endian() const;
88  INLINE bool get_file_stdfloat_double() const;
89 
90  INLINE BamTextureMode get_file_texture_mode() const;
91  INLINE void set_file_texture_mode(BamTextureMode file_texture_mode);
92 
93 public:
94  // Functions to support classes that write themselves to the Bam.
95 
96  void consider_update(const TypedWritable *obj);
97 
98  void write_pointer(Datagram &packet, const TypedWritable *dest);
99 
100  void write_file_data(SubfileInfo &result, const Filename &filename);
101  void write_file_data(SubfileInfo &result, const SubfileInfo &source);
102 
103  void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler);
104  void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler,
105  void *extra_data);
106  bool register_pta(Datagram &packet, const void *ptr);
107  void write_handle(Datagram &packet, TypeHandle type);
108 
109 private:
110  void object_destructs(TypedWritable *object);
111 
112  void write_object_id(Datagram &dg, int object_id);
113  void write_pta_id(Datagram &dg, int pta_id);
114  int enqueue_object(const TypedWritable *object);
115  bool flush_queue();
116 
117  BamEndian _file_endian;
118  bool _file_stdfloat_double;
119  BamTextureMode _file_texture_mode;
120 
121  // This is the set of all TypeHandles already written.
122  pset<int, int_hash> _types_written;
123 
124  // This keeps track of all of the objects we have written out
125  // already (or are about to write out), and associates a unique
126  // object ID number to each one.
127  class StoreState {
128  public:
129  int _object_id;
130  UpdateSeq _written_seq;
131  UpdateSeq _modified;
132 
133  StoreState(int object_id) : _object_id(object_id) {}
134  };
135  typedef phash_map<const TypedWritable *, StoreState, pointer_hash> StateMap;
136  StateMap _state_map;
137 
138  // This seq number is incremented each time we write a new object
139  // using the top-level write_object() call. It indicates the
140  // current sequence number we are writing, which is updated in the
141  // StoreState, above, and used to keep track of which objects may
142  // need to be checked for internal updates.
143  UpdateSeq _writing_seq;
144 
145  // This is initialized to BOC_push in write_object(), then cleared
146  // to BOC_adjunct as each object is written, so that only the first
147  // object gets written with BOC_push.
148  BamObjectCode _next_boc;
149 
150  // This is the next object ID that will be assigned to a new object.
151  int _next_object_id;
152  bool _long_object_id;
153 
154  // This is the queue of objects that need to be written when the
155  // current object is finished.
157  ObjectQueue _object_queue;
158 
159  // This is the set of object_id's that we won't be using any more;
160  // we'll encode this set into the bam stream so the BamReader will
161  // be able to clean up its internal structures.
162  typedef vector_int FreedObjectIds;
163  FreedObjectIds _freed_object_ids;
164 
165  // These are used by register_pta() to unify multiple references to
166  // the same PointerToArray.
167  typedef phash_map<const void *, int, pointer_hash> PTAMap;
168  PTAMap _pta_map;
169  int _next_pta_id;
170  bool _long_pta_id;
171 
172  // The destination to write all the output to.
173  DatagramSink *_target;
174  bool _needs_init;
175 
176  friend class TypedWritable;
177 };
178 
179 #include "bamWriter.I"
180 
181 #endif
182 
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
This is the trivial, non-threaded implementation of PipelineCyclerBase.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
This class defines the abstract interface to sending datagrams to any target, whether it be into a fi...
Definition: datagramSink.h:32
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
This class records a particular byte sub-range within an existing file on disk.
Definition: subfileInfo.h:29
This is our own Panda specialization on the default STL set.
Definition: pset.h:52
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
This is a sequence number that increments monotonically.
Definition: updateSeq.h:43
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
This class exists just to provide scoping for the enums shared by BamReader and BamWriter.
Definition: bamEnums.h:25