29 RecorderController() {
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";
71 recorder_cat.error() <<
"Unable to write to " << _filename <<
"\n";
77 if (!_writer->
init()) {
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";
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;
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;
272 _user_table_modified =
false;
275 _active_table->
set_flags(RecorderBase::F_playing);
278 _next_frame->_table = _active_table;
282 _next_frame = read_frame();
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())) {
311 recorder_cat.warning()
312 <<
"Unable to resolve frame data.\n";
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
bool begin_playback(const Filename &filename)
Begins playing back data from the indicated filename.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A Factory can be used to create an instance of a particular subclass of some general base class.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
bool resolve()
This may be called at any time during processing of the Bam file to resolve all the known pointers so...
TypedWritable * read_object()
Reads a single object from the Bam file.
bool is_recording() const
Returns true if the controller has been opened for output, false otherwise.
Base class for objects that can be written to and read from Bam files.
bool write_header(const std::string &header)
Writes a sequence of bytes to the beginning of the datagram file.
void close()
Finishes recording data to the indicated filename.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool open(const FileReference *file)
Opens the indicated filename for writing.
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(BamReader *manager)
Once the raw data has been read in from the session file, and the table has been decoded,...
bool init()
Initializes the BamReader prior to reading any objects from its source.
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
This object is used by the RecorderController to write (and read) a record of the set of recorders in...
get_frame_count
Returns the number of times tick() has been called since the ClockObject was created,...
The name of a file, such as a texture file or an Egg file.
A ClockObject keeps track of elapsed real time and discrete time.
bool write_object(const TypedWritable *obj)
Writes a single object to the Bam file, so that the BamReader::read_object() can later correctly rest...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear_flags(short flags)
Clears the given flags on all recorders.
void merge_from(const RecorderTable &other)
Combines the data in the current table (presumably just read from disk, and matching exactly with the...
bool begin_record(const Filename &filename)
Begins recording data to the indicated filename.
This object represents one frame of data in the recorded session 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_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
bool is_playing() const
Returns true if the controller has been opened for input, false otherwise.
TypeHandle is the identifier used to differentiate C++ class types.
void set_flags(short flags)
Sets the given flags on all recorders.
void close()
Closes the file.
bool init()
Initializes the BamWriter prior to writing any objects to its output stream.
bool is_eof() const
Returns true if the reader has reached end-of-file, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.