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