Panda3D
Loading...
Searching...
No Matches
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
90public:
91 EXTENSION(PyObject *get_file_version() const);
92
93PUBLISHED:
94 MAKE_PROPERTY(target, get_target, set_target);
95 MAKE_PROPERTY(filename, get_filename);
96 MAKE_PROPERTY(file_version, get_file_version);
97 MAKE_PROPERTY(file_endian, get_file_endian);
98 MAKE_PROPERTY(file_stdfloat_double, get_file_stdfloat_double);
99 MAKE_PROPERTY(file_texture_mode, get_file_texture_mode);
100 MAKE_PROPERTY(root_node, get_root_node, set_root_node);
101
102public:
103 // Functions to support classes that write themselves to the Bam.
104
105 void consider_update(const TypedWritable *obj);
106
107 void write_pointer(Datagram &packet, const TypedWritable *dest);
108
109 void write_file_data(SubfileInfo &result, const Filename &filename);
110 void write_file_data(SubfileInfo &result, const SubfileInfo &source);
111
112 void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler);
113 void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler,
114 void *extra_data);
115 bool register_pta(Datagram &packet, const void *ptr);
116 void write_handle(Datagram &packet, TypeHandle type);
117
118 static std::string get_obsolete_type_name(TypeHandle type, int major, int minor);
119 static void record_obsolete_type_name(TypeHandle type, std::string name,
120 int before_major, int before_minor);
121
122private:
123 void object_destructs(TypedWritable *object);
124
125 void write_object_id(Datagram &dg, int object_id);
126 void write_pta_id(Datagram &dg, int pta_id);
127 int enqueue_object(const TypedWritable *object);
128 bool flush_queue();
129
130 int _file_major, _file_minor;
131 BamEndian _file_endian;
132 bool _file_stdfloat_double;
133 BamTextureMode _file_texture_mode;
134
135 // Stores the PandaNode representing the root of the node hierarchy we are
136 // currently writing, if any, for the purpose of writing NodePaths. This is
137 // a TypedWritable since PandaNode is defined in pgraph.
138 TypedWritable *_root_node;
139
140 // This is the set of all TypeHandles already written.
141 pset<int, int_hash> _types_written;
142
143 // This keeps track of all of the objects we have written out already (or
144 // are about to write out), and associates a unique object ID number to each
145 // one.
146 class StoreState {
147 public:
148 int _object_id;
149 UpdateSeq _written_seq;
150 UpdateSeq _modified;
151 const ReferenceCount *_refcount;
152
153 StoreState(int object_id) : _object_id(object_id), _refcount(nullptr) {}
154 };
155 typedef phash_map<const TypedWritable *, StoreState, pointer_hash> StateMap;
156 StateMap _state_map;
157
158 // This seq number is incremented each time we write a new object using the
159 // top-level write_object() call. It indicates the current sequence number
160 // we are writing, which is updated in the StoreState, above, and used to
161 // keep track of which objects may need to be checked for internal updates.
162 UpdateSeq _writing_seq;
163
164 // This is initialized to BOC_push in write_object(), then cleared to
165 // BOC_adjunct as each object is written, so that only the first object gets
166 // written with BOC_push.
167 BamObjectCode _next_boc;
168
169 // This is the next object ID that will be assigned to a new object.
170 int _next_object_id;
171 bool _long_object_id;
172
173 // This is the queue of objects that need to be written when the current
174 // object is finished.
175 typedef pdeque<const TypedWritable *> ObjectQueue;
176 ObjectQueue _object_queue;
177
178 // This is the set of object_id's that we won't be using any more; we'll
179 // encode this set into the bam stream so the BamReader will be able to
180 // clean up its internal structures.
181 typedef vector_int FreedObjectIds;
182 FreedObjectIds _freed_object_ids;
183
184 // These are used by register_pta() to unify multiple references to the same
185 // PointerToArray.
186 typedef phash_map<const void *, int, pointer_hash> PTAMap;
187 PTAMap _pta_map;
188 int _next_pta_id;
189 bool _long_pta_id;
190
191 // The destination to write all the output to.
192 DatagramSink *_target;
193 bool _needs_init;
194
195 friend class TypedWritable;
196};
197
198#include "bamWriter.I"
199
200#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...
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:44
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.
This is a sequence number that increments monotonically.
Definition updateSeq.h:37
This is our own Panda specialization on the default STL deque.
Definition pdeque.h:36
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.