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