Panda3D
 All Classes Functions Variables Enumerations
recorderTable.cxx
1 // Filename: recorderTable.cxx
2 // Created by: drose (27Jan04)
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 #include "recorderTable.h"
16 #include "bamReader.h"
17 #include "bamWriter.h"
18 #include "config_recorder.h"
19 #include "recorderController.h"
20 #include "indent.h"
21 
22 TypeHandle RecorderTable::_type_handle;
23 
24 ////////////////////////////////////////////////////////////////////
25 // Function: RecorderTable::Destructor
26 // Access: Published
27 // Description:
28 ////////////////////////////////////////////////////////////////////
29 RecorderTable::
30 ~RecorderTable() {
31  Recorders::iterator ri;
32  for (ri = _recorders.begin(); ri != _recorders.end(); ++ri) {
33  unref_delete(ri->second);
34  }
35 }
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function: RecorderTable::merge_from
39 // Access: Public
40 // Description: Combines the data in the current table (presumably
41 // just read from disk, and matching exactly with the
42 // disk data) with the data in the indicated table,
43 // specified by the user (which may not exactly match
44 // the disk data).
45 ////////////////////////////////////////////////////////////////////
46 void RecorderTable::
47 merge_from(const RecorderTable &other) {
48  Recorders::const_iterator ori;
49  for (ori = other._recorders.begin(); ori != other._recorders.end(); ++ori) {
50  const string &name = (*ori).first;
51  RecorderBase *recorder = (*ori).second;
52 
53  Recorders::iterator ri = _recorders.find(name);
54  if (ri == _recorders.end()) {
55  // This may not be an error, since maybe the data isn't here
56  // yet, but it'll be along later.
57  recorder_cat.debug()
58  << "No data for " << name << " in session.\n";
59 
60  } else if ((*ri).second->get_type() == recorder->get_type()) {
61  // If we already had a recorder by that name with the same type,
62  // throw it away (otherwise, keep the one we had before).
63  if ((*ri).second != recorder) {
64  recorder->ref();
65  unref_delete((*ri).second);
66  (*ri).second = recorder;
67  }
68 
69  } else {
70  recorder_cat.warning()
71  << "Keeping recorder " << name << " of type "
72  << (*ri).second->get_type() << " instead of recorder of type "
73  << recorder->get_type() << "\n";
74  }
75  }
76 
77  // Now report any recorders in the session file that weren't
78  // specified by the user.
79  Recorders::const_iterator ri;
80  for (ri = _recorders.begin(); ri != _recorders.end(); ++ri) {
81  const string &name = (*ri).first;
82  ori = other._recorders.find(name);
83  if (ori == other._recorders.end()) {
84  recorder_cat.warning()
85  << "Ignoring " << name << " in session.\n";
86  }
87  }
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: RecorderTable::record_frame
92 // Access: Published
93 // Description: Calls record_frame on all recorders.
94 ////////////////////////////////////////////////////////////////////
95 void RecorderTable::
97  Recorders::iterator ri;
98  for (ri = _recorders.begin();
99  ri != _recorders.end();
100  ++ri) {
101  RecorderBase *recorder = (*ri).second;
102  recorder->record_frame(manager, dg);
103  }
104 }
105 
106 ////////////////////////////////////////////////////////////////////
107 // Function: RecorderTable::play_frame
108 // Access: Published
109 // Description: Calls play_frame on all recorders.
110 ////////////////////////////////////////////////////////////////////
111 void RecorderTable::
113  Recorders::iterator ri;
114  for (ri = _recorders.begin();
115  ri != _recorders.end();
116  ++ri) {
117  RecorderBase *recorder = (*ri).second;
118  recorder->play_frame(scan, manager);
119  }
120 }
121 
122 ////////////////////////////////////////////////////////////////////
123 // Function: RecorderTable::set_flags
124 // Access: Published
125 // Description: Sets the given flags on all recorders.
126 ////////////////////////////////////////////////////////////////////
127 void RecorderTable::
128 set_flags(short flags) {
129  Recorders::iterator ri;
130  for (ri = _recorders.begin();
131  ri != _recorders.end();
132  ++ri) {
133  RecorderBase *recorder = (*ri).second;
134  recorder->_flags |= flags;
135  }
136 }
137 
138 ////////////////////////////////////////////////////////////////////
139 // Function: RecorderTable::clear_flags
140 // Access: Published
141 // Description: Clears the given flags on all recorders.
142 ////////////////////////////////////////////////////////////////////
143 void RecorderTable::
144 clear_flags(short flags) {
145  Recorders::iterator ri;
146  for (ri = _recorders.begin();
147  ri != _recorders.end();
148  ++ri) {
149  RecorderBase *recorder = (*ri).second;
150  recorder->_flags &= ~flags;
151  }
152 }
153 
154 ////////////////////////////////////////////////////////////////////
155 // Function: RecorderTable::write
156 // Access: Published
157 // Description:
158 ////////////////////////////////////////////////////////////////////
159 void RecorderTable::
160 write(ostream &out, int indent_level) const {
161  indent(out, indent_level)
162  << "RecorderTable:\n";
163 
164  Recorders::const_iterator ri;
165  for (ri = _recorders.begin(); ri != _recorders.end(); ++ri) {
166  const string &name = (*ri).first;
167  RecorderBase *recorder = (*ri).second;
168  indent(out, indent_level + 2)
169  << name << " : " << recorder->get_type() << "\n";
170  }
171 }
172 
173 ////////////////////////////////////////////////////////////////////
174 // Function: RecorderTable::register_with_read_factory
175 // Access: Public, Static
176 // Description: Tells the BamReader how to create objects of type
177 // Lens.
178 ////////////////////////////////////////////////////////////////////
179 void RecorderTable::
181  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
182 }
183 
184 ////////////////////////////////////////////////////////////////////
185 // Function: RecorderTable::write_datagram
186 // Access: Public, Virtual
187 // Description: Writes the contents of this object to the datagram
188 // for shipping out to a Bam file.
189 ////////////////////////////////////////////////////////////////////
190 void RecorderTable::
192  TypedWritable::write_datagram(manager, dg);
193 
194  dg.add_uint16(_recorders.size());
195  Recorders::const_iterator ri;
196  for (ri = _recorders.begin(); ri != _recorders.end(); ++ri) {
197  const string &name = (*ri).first;
198  RecorderBase *recorder = (*ri).second;
199  dg.add_string(name);
200  manager->write_handle(dg, recorder->get_type());
201  recorder->write_recorder(manager, dg);
202  }
203 }
204 
205 ////////////////////////////////////////////////////////////////////
206 // Function: RecorderTable::make_from_bam
207 // Access: Protected, Static
208 // Description: This function is called by the BamReader's factory
209 // when a new object of type Lens is encountered
210 // in the Bam file. It should create the Lens
211 // and extract its information from the file.
212 ////////////////////////////////////////////////////////////////////
213 TypedWritable *RecorderTable::
214 make_from_bam(const FactoryParams &params) {
215  RecorderTable *table = new RecorderTable;
216  DatagramIterator scan;
217  BamReader *manager;
218 
219  parse_params(params, scan, manager);
220  table->fillin(scan, manager);
221 
222  return table;
223 }
224 
225 ////////////////////////////////////////////////////////////////////
226 // Function: RecorderTable::fillin
227 // Access: Protected
228 // Description: This internal function is called by make_from_bam to
229 // read in all of the relevant data from the BamFile for
230 // the new RecorderTable.
231 ////////////////////////////////////////////////////////////////////
232 void RecorderTable::
233 fillin(DatagramIterator &scan, BamReader *manager) {
234  TypedWritable::fillin(scan, manager);
235 
236  int num_recorders = scan.get_uint16();
237  for (int i = 0; i < num_recorders; i++) {
238  string name = scan.get_string();
239  TypeHandle type = manager->read_handle(scan);
240 
241  // Use the Factory to create a new recorder of the indicated type.
242  FactoryParams fparams;
243  fparams.add_param(new BamReaderParam(scan, manager));
244 
245  RecorderBase *recorder =
247  if (recorder == (RecorderBase *)NULL) {
248  recorder_cat.error()
249  << "Unable to create Recorder of type " << type << "\n";
250  _error = true;
251 
252  } else {
253  recorder->ref();
254  bool inserted =
255  _recorders.insert(Recorders::value_type(name, recorder)).second;
256  nassertv(inserted);
257  }
258  }
259 }
void add_string(const string &str)
Adds a variable-length string to the datagram.
Definition: datagram.I:351
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
virtual void play_frame(DatagramIterator &scan, BamReader *manager)
Reloads the most recent data collected from the indicated datagram.
Type * make_instance_more_general(TypeHandle handle, const FactoryParams &params=FactoryParams())
Attempts to create an instance of the type requested, or some base type of the type requested...
Definition: factory.I:59
static RecorderFactory * get_factory()
Returns the global RecorderFactory for generating TypedWritable objects.
void record_frame(BamWriter *manager, Datagram &dg)
Calls record_frame on all recorders.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
static void register_with_read_factory()
Tells the BamReader how to create objects of type Lens.
void play_frame(DatagramIterator &scan, BamReader *manager)
Calls play_frame on all recorders.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
string get_string()
Extracts a variable-length string.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class&#39;s make_from_bam() method to read in all...
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
void write_handle(Datagram &packet, TypeHandle type)
Writes a TypeHandle to the file in such a way that the BamReader can read the same TypeHandle later v...
Definition: bamWriter.cxx:487
virtual void record_frame(BamWriter *manager, Datagram &dg)
Records the most recent data collected into the indicated datagram.
This object is used by the RecorderController to write (and read) a record of the set of recorders in...
Definition: recorderTable.h:35
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
This is the base class to a number of objects that record particular kinds of user input (like a Mous...
Definition: recorderBase.h:55
void clear_flags(short flags)
Clears the given flags on all recorders.
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
void add_uint16(PN_uint16 value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:181
virtual void write_recorder(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for encoding in the session file.
void merge_from(const RecorderTable &other)
Combines the data in the current table (presumably just read from disk, and matching exactly with the...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
The parameters that are passed through the Factory to any object constructing itself from a Bam file...
void set_flags(short flags)
Sets the given flags on all recorders.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
TypeHandle read_handle(DatagramIterator &scan)
Reads a TypeHandle out of the Datagram.
Definition: bamReader.cxx:549