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";
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...
bool is_eof() const
Returns true if the reader has reached end-of-file, false otherwise.
bool resolve()
This may be called at any time during processing of the Bam file to resolve all the known pointers so...
bool init()
Initializes the BamReader prior to reading any objects from its source.
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 ...
bool write_object(const TypedWritable *obj)
Writes a single object to the Bam file, so that the BamReader::read_object() can later correctly rest...
bool init()
Initializes the BamWriter prior to writing any objects to its output stream.
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.
bool open(const FileReference *file)
Opens the indicated filename for writing.
void close()
Closes the file.
bool write_header(const std::string &header)
Writes a sequence of bytes to the beginning of the datagram file.
A Factory can be used to create an instance of a particular subclass of some general base class.
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.
void play_frame(BamReader *manager)
Once the raw data has been read in from the session file, and the table has been decoded,...
This object is used by the RecorderController to write (and read) a record of the set of recorders in...
void merge_from(const RecorderTable &other)
Combines the data in the current table (presumably just read from disk, and matching exactly with the...
void set_flags(short flags)
Sets the given flags on all recorders.
void clear_flags(short flags)
Clears the given flags on all recorders.
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.