23RecorderController::RecorderFactory *RecorderController::_factory =
nullptr;
35 _user_table =
new RecorderTable;
36 _user_table_modified =
false;
37 _file_table =
nullptr;
38 _active_table =
nullptr;
46~RecorderController() {
63 time(&_header._start_time);
65 if (!_dout.open(_filename)) {
66 recorder_cat.error() <<
"Unable to open " << _filename <<
"\n";
70 if (!_dout.write_header(_bam_header)) {
71 recorder_cat.error() <<
"Unable to write to " << _filename <<
"\n";
77 if (!_writer->init()) {
83 _writer->write_object(&_header);
85 _user_table_modified =
true;
88 _user_table->set_flags(RecorderBase::F_recording);
91 <<
"Recording session to " << _filename <<
"\n";
106 _filename = filename;
111 if (!_din.open(_filename)) {
112 recorder_cat.error() <<
"Unable to open " << _filename <<
"\n";
117 if (!_din.read_header(head, _bam_header.size()) || head != _bam_header) {
118 recorder_cat.error() <<
"Unable to read " << _filename <<
"\n";
123 if (!_reader->init()) {
128 _user_table_modified =
true;
135 if (
object ==
nullptr ||
136 !object->
is_of_type(RecorderHeader::get_class_type())) {
138 << _filename <<
" does not contain a recorded session.\n";
143 if (!_reader->resolve()) {
144 recorder_cat.warning()
145 <<
"Unable to resolve header data.\n";
149 _header = (*new_header);
153 _next_frame = read_frame();
154 if (_next_frame ==
nullptr) {
156 << _filename <<
" does not contain any frames.\n";
162 <<
"Playing back session from " << _filename <<
"\n";
172 if (_writer !=
nullptr) {
177 _user_table->clear_flags(RecorderBase::F_recording);
179 if (_reader !=
nullptr) {
184 _active_table->clear_flags(RecorderBase::F_playing);
189 if (_file_table !=
nullptr) {
191 _file_table =
nullptr;
194 if (_active_table !=
nullptr) {
195 delete _active_table;
196 _active_table =
nullptr;
211 RecorderFrame data(now, frame, _user_table_modified, _user_table);
212 _user_table_modified =
false;
214 _writer->write_object(&data);
234 while (_next_frame !=
nullptr) {
236 if (frame < _next_frame->_frame) {
248 _clock_offset = global_clock->
get_frame_time() - _next_frame->_timestamp;
251 if (now < _next_frame->_timestamp) {
260 if (_next_frame->_table_changed && _file_table != _next_frame->_table) {
262 _file_table = _next_frame->_table;
265 if (_next_frame->_table_changed || _user_table_modified) {
268 _active_table->clear_flags(RecorderBase::F_playing);
269 delete _active_table;
271 _active_table->merge_from(*_user_table);
272 _user_table_modified =
false;
275 _active_table->set_flags(RecorderBase::F_playing);
278 _next_frame->_table = _active_table;
279 _next_frame->play_frame(_reader);
282 _next_frame = read_frame();
285 if (_reader->is_eof()) {
287 <<
"End of recorded session.\n";
290 <<
"Unable to read datagram from recorded session.\n";
305 if (
object ==
nullptr ||
306 !object->
is_of_type(RecorderFrame::get_class_type())) {
310 if (!_reader->resolve()) {
311 recorder_cat.warning()
312 <<
"Unable to resolve frame data.\n";
315 return DCAST(RecorderFrame,
object);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
TypedWritable * read_object()
Reads a single object from the Bam file.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
A ClockObject keeps track of elapsed real time and discrete time.
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
get_frame_count
Returns the number of times tick() has been called since the ClockObject was created,...
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
The name of a file, such as a texture file or an Egg file.
bool begin_playback(const Filename &filename)
Begins playing back data from the indicated filename.
void record_frame()
Gets the next frame of data from all of the active recorders and adds it to the output file.
void play_frame()
Gets the next frame of data from all of the active recorders and adds it to the output file.
bool is_playing() const
Returns true if the controller has been opened for input, false otherwise.
bool begin_record(const Filename &filename)
Begins recording data to the indicated filename.
bool is_recording() const
Returns true if the controller has been opened for output, false otherwise.
void close()
Finishes recording data to the indicated filename.
This object represents one frame of data in the recorded session file.
This object is used by the RecorderController to write (and read) a record of the set of recorders in...
TypeHandle is the identifier used to differentiate C++ class types.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Base class for objects that can be written to and read from Bam files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.