00001 // Filename: recorderFrame.cxx 00002 // Created by: drose (28Jan04) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "recorderFrame.h" 00016 #include "recorderTable.h" 00017 #include "bamReader.h" 00018 #include "bamWriter.h" 00019 #include "config_recorder.h" 00020 00021 TypeHandle RecorderFrame::_type_handle; 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Function: RecorderFrame::play_frame 00025 // Access: Public 00026 // Description: Once the raw data has been read in from the session 00027 // file, and the table has been decoded, decode the raw 00028 // data and call play_frame on each recorder. 00029 //////////////////////////////////////////////////////////////////// 00030 void RecorderFrame:: 00031 play_frame(BamReader *manager) { 00032 DatagramIterator scan(_data, _data_pos); 00033 00034 RecorderTable::Recorders::iterator ri; 00035 for (ri = _table->_recorders.begin(); 00036 ri != _table->_recorders.end(); 00037 ++ri) { 00038 RecorderBase *recorder = (*ri).second; 00039 recorder->play_frame(scan, manager); 00040 } 00041 00042 // We expect to use up all of the data in the datagram. 00043 nassertv(scan.get_remaining_size() == 0); 00044 } 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Function: RecorderFrame::register_with_read_factory 00048 // Access: Public, Static 00049 // Description: Tells the BamReader how to create objects of type 00050 // Lens. 00051 //////////////////////////////////////////////////////////////////// 00052 void RecorderFrame:: 00053 register_with_read_factory() { 00054 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00055 } 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: RecorderFrame::write_datagram 00059 // Access: Public, Virtual 00060 // Description: Writes the contents of this object to the datagram 00061 // for shipping out to a Bam file. 00062 //////////////////////////////////////////////////////////////////// 00063 void RecorderFrame:: 00064 write_datagram(BamWriter *manager, Datagram &dg) { 00065 TypedWritable::write_datagram(manager, dg); 00066 dg.add_float64(_timestamp); 00067 dg.add_uint32(_frame); 00068 00069 // Write the table out if it has changed. 00070 dg.add_bool(_table_changed); 00071 if (_table_changed) { 00072 // As a kludge, we create a new table pointer to write out. 00073 // Otherwise, the pointer won't change and it may not write out 00074 // the changes. Later, we need to add a facility to the bam 00075 // writer to detect when a TypedWritable has changed and should be 00076 // rewritten. 00077 _local_table = *_table; 00078 manager->write_pointer(dg, &_local_table); 00079 } 00080 00081 RecorderTable::Recorders::iterator ri; 00082 for (ri = _table->_recorders.begin(); 00083 ri != _table->_recorders.end(); 00084 ++ri) { 00085 RecorderBase *recorder = (*ri).second; 00086 recorder->record_frame(manager, dg); 00087 } 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: RecorderFrame::complete_pointers 00092 // Access: Public, Virtual 00093 // Description: Receives an array of pointers, one for each time 00094 // manager->read_pointer() was called in fillin(). 00095 // Returns the number of pointers processed. 00096 // 00097 // This is the callback function that is made by the 00098 // BamReader at some later point, after all of the 00099 // required pointers have been filled in. It is 00100 // necessary because there might be forward references 00101 // in a bam file; when we call read_pointer() in 00102 // fillin(), the object may not have been read from the 00103 // file yet, so we do not have a pointer available at 00104 // that time. Thus, instead of returning a pointer, 00105 // read_pointer() simply reserves a later callback. 00106 // This function provides that callback. The calling 00107 // object is responsible for keeping track of the number 00108 // of times it called read_pointer() and extracting the 00109 // same number of pointers out of the supplied vector, 00110 // and storing them appropriately within the object. 00111 //////////////////////////////////////////////////////////////////// 00112 int RecorderFrame:: 00113 complete_pointers(TypedWritable **p_list, BamReader *manager) { 00114 int pi = TypedWritable::complete_pointers(p_list, manager); 00115 00116 if (_table_changed) { 00117 _table = DCAST(RecorderTable, p_list[pi++]); 00118 } 00119 00120 return pi; 00121 } 00122 00123 //////////////////////////////////////////////////////////////////// 00124 // Function: RecorderFrame::make_from_bam 00125 // Access: Protected, Static 00126 // Description: This function is called by the BamReader's factory 00127 // when a new object of type Lens is encountered 00128 // in the Bam file. It should create the Lens 00129 // and extract its information from the file. 00130 //////////////////////////////////////////////////////////////////// 00131 TypedWritable *RecorderFrame:: 00132 make_from_bam(const FactoryParams ¶ms) { 00133 RecorderFrame *frame = new RecorderFrame; 00134 DatagramIterator scan; 00135 BamReader *manager; 00136 00137 parse_params(params, scan, manager); 00138 frame->fillin(scan, manager); 00139 00140 return frame; 00141 } 00142 00143 //////////////////////////////////////////////////////////////////// 00144 // Function: RecorderFrame::fillin 00145 // Access: Protected 00146 // Description: This internal function is called by make_from_bam to 00147 // read in all of the relevant data from the BamFile for 00148 // the new RecorderFrame. 00149 //////////////////////////////////////////////////////////////////// 00150 void RecorderFrame:: 00151 fillin(DatagramIterator &scan, BamReader *manager) { 00152 TypedWritable::fillin(scan, manager); 00153 00154 _timestamp = scan.get_float64(); 00155 _frame = scan.get_uint32(); 00156 _table_changed = scan.get_bool(); 00157 _table = (RecorderTable *)NULL; 00158 if (_table_changed) { 00159 manager->read_pointer(scan); 00160 } 00161 00162 // We can't decode the data in the frame until we have (a) gotten 00163 // back the table pointer, or (b) been told who our owning 00164 // RecorderController is. So we'll just save the raw data for now 00165 // and come back to it. 00166 _data = scan.get_datagram(); 00167 _data_pos = scan.get_current_index(); 00168 }