00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "recorderController.h"
00016 #include "recorderFrame.h"
00017 #include "bamReader.h"
00018 #include "bamWriter.h"
00019 #include "config_recorder.h"
00020 #include "bam.h"
00021 #include "clockObject.h"
00022
00023 TypeHandle RecorderController::_type_handle;
00024 RecorderController::RecorderFactory *RecorderController::_factory = NULL;
00025
00026
00027
00028
00029
00030
00031 RecorderController::
00032 RecorderController() {
00033 _clock_offset = 0.0;
00034 _frame_offset = 0;
00035 _writer = (BamWriter *)NULL;
00036 _reader = (BamReader *)NULL;
00037 _frame_tie = true;
00038 _user_table = new RecorderTable;
00039 _user_table_modified = false;
00040 _file_table = NULL;
00041 _active_table = NULL;
00042 _eof = false;
00043 }
00044
00045
00046
00047
00048
00049
00050 RecorderController::
00051 ~RecorderController() {
00052 close();
00053 delete _user_table;
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063 bool RecorderController::
00064 begin_record(const Filename &filename) {
00065 close();
00066 _filename = filename;
00067 ClockObject *global_clock = ClockObject::get_global_clock();
00068 _clock_offset = global_clock->get_frame_time();
00069 _frame_offset = global_clock->get_frame_count();
00070
00071 time(&_header._start_time);
00072
00073 if (!_dout.open(_filename)) {
00074 recorder_cat.error() << "Unable to open " << _filename << "\n";
00075 return false;
00076 }
00077
00078 if (!_dout.write_header(_bam_header)) {
00079 recorder_cat.error() << "Unable to write to " << _filename << "\n";
00080 return false;
00081 }
00082
00083 _writer = new BamWriter(&_dout);
00084
00085 if (!_writer->init()) {
00086 close();
00087 return false;
00088 }
00089
00090
00091 _writer->write_object(&_header);
00092
00093 _user_table_modified = true;
00094
00095
00096 RecorderTable::Recorders::iterator ri;
00097 for (ri = _user_table->_recorders.begin();
00098 ri != _user_table->_recorders.end();
00099 ++ri) {
00100 RecorderBase *recorder = (*ri).second;
00101 recorder->_flags |= RecorderBase::F_recording;
00102 }
00103
00104 recorder_cat.info()
00105 << "Recording session to " << _filename << "\n";
00106
00107 return true;
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 bool RecorderController::
00122 begin_playback(const Filename &filename) {
00123 close();
00124 _filename = filename;
00125 ClockObject *global_clock = ClockObject::get_global_clock();
00126 _clock_offset = global_clock->get_frame_time();
00127 _frame_offset = global_clock->get_frame_count();
00128
00129 if (!_din.open(_filename)) {
00130 recorder_cat.error() << "Unable to open " << _filename << "\n";
00131 return false;
00132 }
00133
00134 string head;
00135 if (!_din.read_header(head, _bam_header.size()) || head != _bam_header) {
00136 recorder_cat.error() << "Unable to read " << _filename << "\n";
00137 return false;
00138 }
00139
00140 _reader = new BamReader(&_din);
00141 if (!_reader->init()) {
00142 close();
00143 return false;
00144 }
00145
00146 _user_table_modified = true;
00147 _active_table = new RecorderTable;
00148 _eof = false;
00149
00150
00151 TypedWritable *object = _reader->read_object();
00152
00153 if (object == (TypedWritable *)NULL ||
00154 !object->is_of_type(RecorderHeader::get_class_type())) {
00155 recorder_cat.error()
00156 << _filename << " does not contain a recorded session.\n";
00157 close();
00158 return false;
00159 }
00160
00161 if (!_reader->resolve()) {
00162 recorder_cat.warning()
00163 << "Unable to resolve header data.\n";
00164 }
00165
00166 RecorderHeader *new_header = DCAST(RecorderHeader, object);
00167 _header = (*new_header);
00168 delete new_header;
00169
00170
00171 _next_frame = read_frame();
00172 if (_next_frame == (RecorderFrame *)NULL) {
00173 recorder_cat.error()
00174 << _filename << " does not contain any frames.\n";
00175 close();
00176 return false;
00177 }
00178
00179 recorder_cat.info()
00180 << "Playing back session from " << _filename << "\n";
00181
00182 return true;
00183 }
00184
00185
00186
00187
00188
00189
00190 void RecorderController::
00191 close() {
00192 if (_writer != (BamWriter *)NULL) {
00193 delete _writer;
00194 _writer = NULL;
00195
00196
00197 RecorderTable::Recorders::iterator ri;
00198 for (ri = _user_table->_recorders.begin();
00199 ri != _user_table->_recorders.end();
00200 ++ri) {
00201 RecorderBase *recorder = (*ri).second;
00202 recorder->_flags &= ~RecorderBase::F_recording;
00203 }
00204 }
00205 if (_reader != (BamReader *)NULL) {
00206 delete _reader;
00207 _reader = NULL;
00208
00209
00210 RecorderTable::Recorders::iterator ri;
00211 for (ri = _active_table->_recorders.begin();
00212 ri != _active_table->_recorders.end();
00213 ++ri) {
00214 RecorderBase *recorder = (*ri).second;
00215 recorder->_flags &= ~RecorderBase::F_playing;
00216 }
00217 }
00218 _dout.close();
00219 _din.close();
00220
00221 if (_file_table != (RecorderTable *)NULL) {
00222 delete _file_table;
00223 _file_table = (RecorderTable *)NULL;
00224 }
00225
00226 if (_active_table != (RecorderTable *)NULL) {
00227 delete _active_table;
00228 _active_table = (RecorderTable *)NULL;
00229 }
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 void RecorderController::
00239 record_frame() {
00240 if (is_recording()) {
00241 ClockObject *global_clock = ClockObject::get_global_clock();
00242 double now = global_clock->get_frame_time() - _clock_offset;
00243 int frame = global_clock->get_frame_count() - _frame_offset;
00244
00245 RecorderFrame data(now, frame, _user_table_modified, _user_table);
00246 _user_table_modified = false;
00247
00248 _writer->write_object(&data);
00249 }
00250 }
00251
00252
00253
00254
00255
00256
00257
00258 void RecorderController::
00259 play_frame() {
00260 if (is_playing()) {
00261 if (_eof) {
00262 close();
00263 return;
00264 }
00265
00266 ClockObject *global_clock = ClockObject::get_global_clock();
00267 double now = global_clock->get_frame_time() - _clock_offset;
00268 int frame = global_clock->get_frame_count() - _frame_offset;
00269
00270 while (_next_frame != (RecorderFrame *)NULL) {
00271 if (_frame_tie) {
00272 if (frame < _next_frame->_frame) {
00273
00274 return;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283 _clock_offset = global_clock->get_frame_time() - _next_frame->_timestamp;
00284
00285 } else {
00286 if (now < _next_frame->_timestamp) {
00287
00288 return;
00289 }
00290
00291
00292 _frame_offset = global_clock->get_frame_count() - _next_frame->_frame;
00293 }
00294
00295 if (_next_frame->_table_changed && _file_table != _next_frame->_table) {
00296 delete _file_table;
00297 _file_table = _next_frame->_table;
00298 }
00299
00300 if (_next_frame->_table_changed || _user_table_modified) {
00301
00302
00303 RecorderTable::Recorders::iterator ri;
00304 for (ri = _active_table->_recorders.begin();
00305 ri != _active_table->_recorders.end();
00306 ++ri) {
00307 RecorderBase *recorder = (*ri).second;
00308 recorder->_flags &= ~RecorderBase::F_playing;
00309 }
00310
00311 delete _active_table;
00312 _active_table = new RecorderTable(*_file_table);
00313 _active_table->merge_from(*_user_table);
00314 _user_table_modified = false;
00315
00316
00317
00318 for (ri = _active_table->_recorders.begin();
00319 ri != _active_table->_recorders.end();
00320 ++ri) {
00321 RecorderBase *recorder = (*ri).second;
00322 recorder->_flags |= RecorderBase::F_playing;
00323 }
00324 }
00325
00326 _next_frame->_table = _active_table;
00327 _next_frame->play_frame(_reader);
00328
00329 delete _next_frame;
00330 _next_frame = read_frame();
00331 }
00332
00333 if (_reader->is_eof()) {
00334 recorder_cat.info()
00335 << "End of recorded session.\n";
00336 } else {
00337 recorder_cat.error()
00338 << "Unable to read datagram from recorded session.\n";
00339 }
00340 _eof = true;
00341 }
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 RecorderFrame *RecorderController::
00353 read_frame() {
00354 TypedWritable *object = _reader->read_object();
00355
00356 if (object == (TypedWritable *)NULL ||
00357 !object->is_of_type(RecorderFrame::get_class_type())) {
00358 return NULL;
00359 }
00360
00361 if (!_reader->resolve()) {
00362 recorder_cat.warning()
00363 << "Unable to resolve frame data.\n";
00364 }
00365
00366 return DCAST(RecorderFrame, object);
00367 }