Panda3D
 All Classes Functions Variables Enumerations
socketStreamRecorder.cxx
00001 // Filename: socketStreamRecorder.cxx
00002 // Created by:  drose (28Jan04)
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 "socketStreamRecorder.h"
00016 #include "recorderController.h"
00017 #include "bamReader.h"
00018 #include "bamWriter.h"
00019 
00020 #ifdef HAVE_OPENSSL
00021 
00022 TypeHandle SocketStreamRecorder::_type_handle;
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: SocketStreamRecorder::receive_datagram
00026 //       Access: Public
00027 //  Description: Receives a datagram over the socket by expecting a
00028 //               little-endian 16-bit byte count as a prefix.  If the
00029 //               socket stream is non-blocking, may return false if
00030 //               the data is not available; otherwise, returns false
00031 //               only if the socket closes.
00032 ////////////////////////////////////////////////////////////////////
00033 bool SocketStreamRecorder::
00034 receive_datagram(Datagram &dg) {
00035   if (is_playing()) {
00036     // If we're playing back data, the datagrams come only from the
00037     // queue, not from the live connection.
00038     if (!_data.empty()) {
00039       dg = _data.front();
00040       _data.pop_front();
00041       return true;
00042     }
00043 
00044     return false;
00045 
00046   } else {
00047     // If we're not in playback mode, forward the request to the
00048     // connection.
00049     bool got_data = false;
00050     if (_stream != (SocketStream *)NULL) {
00051       got_data = _stream->receive_datagram(dg);
00052     }
00053 
00054     if (got_data && is_recording()) {
00055       // If we're in recording mode, save the data.
00056       _data.push_back(dg);
00057     }
00058 
00059     return got_data;
00060   }
00061 }
00062 
00063 ////////////////////////////////////////////////////////////////////
00064 //     Function: SocketStreamRecorder::record_frame
00065 //       Access: Public, Virtual
00066 //  Description: Records the most recent data collected into the
00067 //               indicated datagram, and returns true if there is any
00068 //               interesting data worth recording, or false if the
00069 //               datagram is meaningless.
00070 ////////////////////////////////////////////////////////////////////
00071 void SocketStreamRecorder::
00072 record_frame(BamWriter *manager, Datagram &dg) {
00073   nassertv(is_recording());
00074   dg.add_bool(_closed);
00075   dg.add_uint16(_data.size());
00076   for (Data::iterator di = _data.begin(); di != _data.end(); ++di) {
00077     dg.add_string((*di).get_message());
00078   }
00079   _data.clear();
00080 }
00081 
00082 
00083 ////////////////////////////////////////////////////////////////////
00084 //     Function: SocketStreamRecorder::play_frame
00085 //       Access: Public, Virtual
00086 //  Description: Reloads the most recent data collected from the
00087 //               indicated datagram.
00088 ////////////////////////////////////////////////////////////////////
00089 void SocketStreamRecorder::
00090 play_frame(DatagramIterator &scan, BamReader *manager) {
00091   nassertv(is_playing());
00092   _closed = scan.get_bool();
00093 
00094   int num_packets = scan.get_uint16();
00095   for (int i = 0; i < num_packets; i++) {
00096     string packet = scan.get_string();
00097     _data.push_back(Datagram(packet));
00098   }
00099 }
00100 
00101 ////////////////////////////////////////////////////////////////////
00102 //     Function: SocketStreamRecorder::register_with_read_factory
00103 //       Access: Public, Static
00104 //  Description: Tells the BamReader how to create objects of type
00105 //               Lens.
00106 ////////////////////////////////////////////////////////////////////
00107 void SocketStreamRecorder::
00108 register_with_read_factory() {
00109   RecorderController::get_factory()->register_factory(get_class_type(), make_recorder);
00110 }
00111 
00112 ////////////////////////////////////////////////////////////////////
00113 //     Function: SocketStreamRecorder::write_recorder
00114 //       Access: Public, Virtual
00115 //  Description: Writes the contents of this object to the datagram
00116 //               for encoding in the session file.  This is very
00117 //               similar to write_datagram() for TypedWritable
00118 //               objects, but it is used specifically to write the
00119 //               Recorder object when generating the session file.  In
00120 //               many cases, it will be the same as write_datagram().
00121 ////////////////////////////////////////////////////////////////////
00122 void SocketStreamRecorder::
00123 write_recorder(BamWriter *manager, Datagram &dg) {
00124   RecorderBase::write_recorder(manager, dg);
00125 }
00126 
00127 ////////////////////////////////////////////////////////////////////
00128 //     Function: SocketStreamRecorder::make_recorder
00129 //       Access: Protected, Static
00130 //  Description: This is similar to make_from_bam(), but it is
00131 //               designed for loading the RecorderBase object from the
00132 //               session log created by a RecorderController.
00133 ////////////////////////////////////////////////////////////////////
00134 RecorderBase *SocketStreamRecorder::
00135 make_recorder(const FactoryParams &params) {
00136   SocketStreamRecorder *node = new SocketStreamRecorder;
00137   DatagramIterator scan;
00138   BamReader *manager;
00139 
00140   parse_params(params, scan, manager);
00141   node->fillin_recorder(scan, manager);
00142 
00143   return node;
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: SocketStreamRecorder::fillin_recorder
00148 //       Access: Protected
00149 //  Description: This internal function is called by make_from_bam to
00150 //               read in all of the relevant data from the BamFile for
00151 //               the new SocketStreamRecorder.
00152 ////////////////////////////////////////////////////////////////////
00153 void SocketStreamRecorder::
00154 fillin_recorder(DatagramIterator &scan, BamReader *manager) {
00155   RecorderBase::fillin_recorder(scan, manager);
00156 }
00157 
00158 #endif  // HAVE_OPENSSL
 All Classes Functions Variables Enumerations