Panda3D
 All Classes Functions Variables Enumerations
socketStreamRecorder.cxx
1 // Filename: socketStreamRecorder.cxx
2 // Created by: drose (28Jan04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "socketStreamRecorder.h"
16 #include "recorderController.h"
17 #include "bamReader.h"
18 #include "bamWriter.h"
19 
20 #ifdef HAVE_OPENSSL
21 
22 TypeHandle SocketStreamRecorder::_type_handle;
23 
24 ////////////////////////////////////////////////////////////////////
25 // Function: SocketStreamRecorder::receive_datagram
26 // Access: Public
27 // Description: Receives a datagram over the socket by expecting a
28 // little-endian 16-bit byte count as a prefix. If the
29 // socket stream is non-blocking, may return false if
30 // the data is not available; otherwise, returns false
31 // only if the socket closes.
32 ////////////////////////////////////////////////////////////////////
33 bool SocketStreamRecorder::
34 receive_datagram(Datagram &dg) {
35  if (is_playing()) {
36  // If we're playing back data, the datagrams come only from the
37  // queue, not from the live connection.
38  if (!_data.empty()) {
39  dg = _data.front();
40  _data.pop_front();
41  return true;
42  }
43 
44  return false;
45 
46  } else {
47  // If we're not in playback mode, forward the request to the
48  // connection.
49  bool got_data = false;
50  if (_stream != (SocketStream *)NULL) {
51  got_data = _stream->receive_datagram(dg);
52  }
53 
54  if (got_data && is_recording()) {
55  // If we're in recording mode, save the data.
56  _data.push_back(dg);
57  }
58 
59  return got_data;
60  }
61 }
62 
63 ////////////////////////////////////////////////////////////////////
64 // Function: SocketStreamRecorder::record_frame
65 // Access: Public, Virtual
66 // Description: Records the most recent data collected into the
67 // indicated datagram, and returns true if there is any
68 // interesting data worth recording, or false if the
69 // datagram is meaningless.
70 ////////////////////////////////////////////////////////////////////
71 void SocketStreamRecorder::
72 record_frame(BamWriter *manager, Datagram &dg) {
73  nassertv(is_recording());
74  dg.add_bool(_closed);
75  dg.add_uint16(_data.size());
76  for (Data::iterator di = _data.begin(); di != _data.end(); ++di) {
77  dg.add_string((*di).get_message());
78  }
79  _data.clear();
80 }
81 
82 
83 ////////////////////////////////////////////////////////////////////
84 // Function: SocketStreamRecorder::play_frame
85 // Access: Public, Virtual
86 // Description: Reloads the most recent data collected from the
87 // indicated datagram.
88 ////////////////////////////////////////////////////////////////////
89 void SocketStreamRecorder::
90 play_frame(DatagramIterator &scan, BamReader *manager) {
91  nassertv(is_playing());
92  _closed = scan.get_bool();
93 
94  int num_packets = scan.get_uint16();
95  for (int i = 0; i < num_packets; i++) {
96  string packet = scan.get_string();
97  _data.push_back(Datagram(packet));
98  }
99 }
100 
101 ////////////////////////////////////////////////////////////////////
102 // Function: SocketStreamRecorder::register_with_read_factory
103 // Access: Public, Static
104 // Description: Tells the BamReader how to create objects of type
105 // Lens.
106 ////////////////////////////////////////////////////////////////////
107 void SocketStreamRecorder::
108 register_with_read_factory() {
109  RecorderController::get_factory()->register_factory(get_class_type(), make_recorder);
110 }
111 
112 ////////////////////////////////////////////////////////////////////
113 // Function: SocketStreamRecorder::write_recorder
114 // Access: Public, Virtual
115 // Description: Writes the contents of this object to the datagram
116 // for encoding in the session file. This is very
117 // similar to write_datagram() for TypedWritable
118 // objects, but it is used specifically to write the
119 // Recorder object when generating the session file. In
120 // many cases, it will be the same as write_datagram().
121 ////////////////////////////////////////////////////////////////////
122 void SocketStreamRecorder::
123 write_recorder(BamWriter *manager, Datagram &dg) {
124  RecorderBase::write_recorder(manager, dg);
125 }
126 
127 ////////////////////////////////////////////////////////////////////
128 // Function: SocketStreamRecorder::make_recorder
129 // Access: Protected, Static
130 // Description: This is similar to make_from_bam(), but it is
131 // designed for loading the RecorderBase object from the
132 // session log created by a RecorderController.
133 ////////////////////////////////////////////////////////////////////
134 RecorderBase *SocketStreamRecorder::
135 make_recorder(const FactoryParams &params) {
136  SocketStreamRecorder *node = new SocketStreamRecorder;
137  DatagramIterator scan;
138  BamReader *manager;
139 
140  parse_params(params, scan, manager);
141  node->fillin_recorder(scan, manager);
142 
143  return node;
144 }
145 
146 ////////////////////////////////////////////////////////////////////
147 // Function: SocketStreamRecorder::fillin_recorder
148 // Access: Protected
149 // Description: This internal function is called by make_from_bam to
150 // read in all of the relevant data from the BamFile for
151 // the new SocketStreamRecorder.
152 ////////////////////////////////////////////////////////////////////
153 void SocketStreamRecorder::
154 fillin_recorder(DatagramIterator &scan, BamReader *manager) {
155  RecorderBase::fillin_recorder(scan, manager);
156 }
157 
158 #endif // HAVE_OPENSSL
bool get_bool()
Extracts a boolean value.
void add_string(const string &str)
Adds a variable-length string to the datagram.
Definition: datagram.I:351
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
static RecorderFactory * get_factory()
Returns the global RecorderFactory for generating TypedWritable objects.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
string get_string()
Extracts a variable-length string.
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:118
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
This is the base class to a number of objects that record particular kinds of user input (like a Mous...
Definition: recorderBase.h:55
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
void add_uint16(PN_uint16 value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:181
virtual void write_recorder(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for encoding in the session file.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43