Panda3D
|
00001 // Filename: recorderTable.cxx 00002 // Created by: drose (27Jan04) 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 "recorderTable.h" 00016 #include "bamReader.h" 00017 #include "bamWriter.h" 00018 #include "config_recorder.h" 00019 #include "recorderController.h" 00020 #include "indent.h" 00021 00022 TypeHandle RecorderTable::_type_handle; 00023 00024 //////////////////////////////////////////////////////////////////// 00025 // Function: RecorderTable::merge_from 00026 // Access: Public 00027 // Description: Combines the data in the current table (presumably 00028 // just read from disk, and matching exactly with the 00029 // disk data) with the data in the indicated table, 00030 // specified by the user (which may not exactly match 00031 // the disk data). 00032 //////////////////////////////////////////////////////////////////// 00033 void RecorderTable:: 00034 merge_from(const RecorderTable &other) { 00035 Recorders::const_iterator ori; 00036 for (ori = other._recorders.begin(); ori != other._recorders.end(); ++ori) { 00037 const string &name = (*ori).first; 00038 RecorderBase *recorder = (*ori).second; 00039 00040 Recorders::iterator ri = _recorders.find(name); 00041 if (ri == _recorders.end()) { 00042 // This may not be an error, since maybe the data isn't here 00043 // yet, but it'll be along later. 00044 recorder_cat.debug() 00045 << "No data for " << name << " in session.\n"; 00046 00047 } else if ((*ri).second->get_type() == recorder->get_type()) { 00048 // If we already had a recorder by that name with the same type, 00049 // throw it away (otherwise, keep the one we had before). 00050 (*ri).second = recorder; 00051 00052 } else { 00053 recorder_cat.warning() 00054 << "Keeping recorder " << name << " of type " 00055 << (*ri).second->get_type() << " instead of recorder of type " 00056 << recorder->get_type() << "\n"; 00057 } 00058 } 00059 00060 // Now report any recorders in the session file that weren't 00061 // specified by the user. 00062 Recorders::const_iterator ri; 00063 for (ri = _recorders.begin(); ri != _recorders.end(); ++ri) { 00064 const string &name = (*ri).first; 00065 ori = other._recorders.find(name); 00066 if (ori == other._recorders.end()) { 00067 recorder_cat.warning() 00068 << "Ignoring " << name << " in session.\n"; 00069 } 00070 } 00071 } 00072 00073 //////////////////////////////////////////////////////////////////// 00074 // Function: RecorderTable::add_recorder 00075 // Access: Published 00076 // Description: Adds the named recorder to the set of recorders. 00077 //////////////////////////////////////////////////////////////////// 00078 void RecorderTable:: 00079 add_recorder(const string &name, RecorderBase *recorder) { 00080 _recorders[name] = recorder; 00081 } 00082 00083 //////////////////////////////////////////////////////////////////// 00084 // Function: RecorderTable::get_recorder 00085 // Access: Published 00086 // Description: Returns the recorder with the indicated name, or NULL 00087 // if there is no such recorder. 00088 //////////////////////////////////////////////////////////////////// 00089 RecorderBase *RecorderTable:: 00090 get_recorder(const string &name) const { 00091 Recorders::const_iterator ri = _recorders.find(name); 00092 if (ri != _recorders.end()) { 00093 return (*ri).second; 00094 } 00095 return NULL; 00096 } 00097 00098 //////////////////////////////////////////////////////////////////// 00099 // Function: RecorderTable::remove_recorder 00100 // Access: Published 00101 // Description: Removes the named recorder from the table. Returns 00102 // true if successful, false if there was no such 00103 // recorder. 00104 //////////////////////////////////////////////////////////////////// 00105 bool RecorderTable:: 00106 remove_recorder(const string &name) { 00107 Recorders::iterator ri = _recorders.find(name); 00108 if (ri != _recorders.end()) { 00109 _recorders.erase(ri); 00110 return true; 00111 } 00112 return false; 00113 } 00114 00115 //////////////////////////////////////////////////////////////////// 00116 // Function: RecorderTable::write 00117 // Access: Published 00118 // Description: 00119 //////////////////////////////////////////////////////////////////// 00120 void RecorderTable:: 00121 write(ostream &out, int indent_level) const { 00122 indent(out, indent_level) 00123 << "RecorderTable:\n"; 00124 00125 Recorders::const_iterator ri; 00126 for (ri = _recorders.begin(); ri != _recorders.end(); ++ri) { 00127 const string &name = (*ri).first; 00128 RecorderBase *recorder = (*ri).second; 00129 indent(out, indent_level + 2) 00130 << name << " : " << recorder->get_type() << "\n"; 00131 } 00132 } 00133 00134 //////////////////////////////////////////////////////////////////// 00135 // Function: RecorderTable::register_with_read_factory 00136 // Access: Public, Static 00137 // Description: Tells the BamReader how to create objects of type 00138 // Lens. 00139 //////////////////////////////////////////////////////////////////// 00140 void RecorderTable:: 00141 register_with_read_factory() { 00142 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00143 } 00144 00145 //////////////////////////////////////////////////////////////////// 00146 // Function: RecorderTable::write_datagram 00147 // Access: Public, Virtual 00148 // Description: Writes the contents of this object to the datagram 00149 // for shipping out to a Bam file. 00150 //////////////////////////////////////////////////////////////////// 00151 void RecorderTable:: 00152 write_datagram(BamWriter *manager, Datagram &dg) { 00153 TypedWritable::write_datagram(manager, dg); 00154 00155 dg.add_uint16(_recorders.size()); 00156 Recorders::const_iterator ri; 00157 for (ri = _recorders.begin(); ri != _recorders.end(); ++ri) { 00158 const string &name = (*ri).first; 00159 RecorderBase *recorder = (*ri).second; 00160 dg.add_string(name); 00161 manager->write_handle(dg, recorder->get_type()); 00162 recorder->write_recorder(manager, dg); 00163 } 00164 } 00165 00166 //////////////////////////////////////////////////////////////////// 00167 // Function: RecorderTable::make_from_bam 00168 // Access: Protected, Static 00169 // Description: This function is called by the BamReader's factory 00170 // when a new object of type Lens is encountered 00171 // in the Bam file. It should create the Lens 00172 // and extract its information from the file. 00173 //////////////////////////////////////////////////////////////////// 00174 TypedWritable *RecorderTable:: 00175 make_from_bam(const FactoryParams ¶ms) { 00176 RecorderTable *table = new RecorderTable; 00177 DatagramIterator scan; 00178 BamReader *manager; 00179 00180 parse_params(params, scan, manager); 00181 table->fillin(scan, manager); 00182 00183 return table; 00184 } 00185 00186 //////////////////////////////////////////////////////////////////// 00187 // Function: RecorderTable::fillin 00188 // Access: Protected 00189 // Description: This internal function is called by make_from_bam to 00190 // read in all of the relevant data from the BamFile for 00191 // the new RecorderTable. 00192 //////////////////////////////////////////////////////////////////// 00193 void RecorderTable:: 00194 fillin(DatagramIterator &scan, BamReader *manager) { 00195 TypedWritable::fillin(scan, manager); 00196 00197 int num_recorders = scan.get_uint16(); 00198 for (int i = 0; i < num_recorders; i++) { 00199 string name = scan.get_string(); 00200 TypeHandle type = manager->read_handle(scan); 00201 00202 // Use the Factory to create a new recorder of the indicated type. 00203 FactoryParams fparams; 00204 fparams.add_param(new BamReaderParam(scan, manager)); 00205 00206 PT(RecorderBase) recorder = 00207 RecorderController::get_factory()->make_instance_more_general(type, fparams); 00208 if (recorder == (RecorderBase *)NULL) { 00209 recorder_cat.error() 00210 << "Unable to create Recorder of type " << type << "\n"; 00211 _error = true; 00212 00213 } else { 00214 bool inserted = 00215 _recorders.insert(Recorders::value_type(name, recorder)).second; 00216 nassertv(inserted); 00217 } 00218 } 00219 }