Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "../common/consts.h"
00022 #include "../msg/msg.h"
00023 #include "../utils/utils.h"
00024 #include <dashel/dashel.h>
00025 #include "../transport/dashel_plugins/dashel-plugins.h"
00026 #include <time.h>
00027 #include <iostream>
00028 #include <cstring>
00029 #include <string>
00030 #include <deque>
00031
00032 namespace Aseba
00033 {
00034 using namespace Dashel;
00035 using namespace std;
00036
00041
00044 class Player : public Hub
00045 {
00046 private:
00047 typedef deque<string> StringList;
00048
00049 bool respectTimings;
00050 int speedFactor;
00051 Stream* in;
00052 string line;
00053 UnifiedTime lastTimeStamp;
00054 UnifiedTime lastEventTime;
00055
00056 public:
00057 Player(const char* inputFile, bool respectTimings, int speedFactor) :
00058 respectTimings(respectTimings),
00059 speedFactor(speedFactor),
00060 lastTimeStamp(0)
00061 {
00062 if (inputFile)
00063 in = connect("file:" + string(inputFile) + ";mode=read");
00064 else
00065 in = connect("stdin:");
00066 }
00067
00068 StringList tokenize(const string& input)
00069 {
00070 StringList list;
00071 const size_t inputSize(input.size());
00072
00073 size_t pos(0);
00074 while ((pos != string::npos) && (pos < inputSize))
00075 {
00076 const size_t next = input.find(' ', pos);
00077 string word;
00078 if (next != string::npos)
00079 word = input.substr(pos, next-pos);
00080 else
00081 word = input.substr(pos);
00082 if (!word.empty())
00083 list.push_back(word);
00084 pos = next + 1;
00085 }
00086
00087 return list;
00088 }
00089
00090 void sendLine()
00091 {
00092
00093 UserMessage userMessage;
00094
00095 StringList tokenizedLine(tokenize(line));
00096
00097 UnifiedTime timeStamp(UnifiedTime::fromRawTimeString(tokenizedLine.front()));
00098 tokenizedLine.pop_front();
00099
00100 userMessage.source = atoi(tokenizedLine.front().c_str());
00101 tokenizedLine.pop_front();
00102
00103 userMessage.type = atoi(tokenizedLine.front().c_str());
00104 tokenizedLine.pop_front();
00105
00106 userMessage.data.reserve(size_t(atoi(tokenizedLine.front().c_str())));
00107 tokenizedLine.pop_front();
00108
00109 while (!tokenizedLine.empty())
00110 {
00111 userMessage.data.push_back(atoi(tokenizedLine.front().c_str()));
00112 tokenizedLine.pop_front();
00113 }
00114
00115
00116 if ((respectTimings) && (lastTimeStamp.value != 0))
00117 {
00118 const UnifiedTime lostTime(UnifiedTime() - lastEventTime);
00119 const UnifiedTime deltaTimeStamp(timeStamp - lastTimeStamp);
00120 if (lostTime < deltaTimeStamp)
00121 {
00122 UnifiedTime waitTime(deltaTimeStamp - lostTime);
00123 waitTime /= speedFactor;
00124 waitTime.sleep();
00125 }
00126 }
00127
00128
00129 for (StreamsSet::iterator it = dataStreams.begin(); it != dataStreams.end();++it)
00130 {
00131 Stream* destStream(*it);
00132 if (destStream != in)
00133 {
00134 userMessage.serialize(destStream);
00135 destStream->flush();
00136 }
00137 }
00138
00139 lastEventTime = UnifiedTime();
00140 lastTimeStamp = timeStamp;
00141
00142 line.clear();
00143 }
00144
00145 protected:
00146
00147 void connectionCreated(Stream *stream)
00148 {
00149
00150 }
00151
00152 void incomingData(Stream *stream)
00153 {
00154 char c(stream->read<char>());
00155 if (stream == in)
00156 {
00157 if (c == '\n')
00158 sendLine();
00159 else
00160 line += c;
00161 }
00162 }
00163
00164 void connectionClosed(Stream *stream, bool abnormal)
00165 {
00166 if (stream == in)
00167 stop();
00168 }
00169 };
00170
00172 }
00173
00174
00176 void dumpHelp(std::ostream &stream, const char *programName)
00177 {
00178 stream << "Aseba play, play recorded user messages from a file or stdin, usage:\n";
00179 stream << programName << " [options] [targets]*\n";
00180 stream << "Options:\n";
00181 stream << "--fast : replay messages twice the speed of real time\n";
00182 stream << "--faster : replay messages four times the speed of real time\n";
00183 stream << "--fastest : replay messages as fast as possible\n";
00184 stream << "-f INPUT_FILE : open INPUT_FILE instead of stdin\n";
00185 stream << "-h, --help : shows this help\n";
00186 stream << "-V, --version : shows the version number\n";
00187 stream << "Targets are any valid Dashel targets." << std::endl;
00188 stream << "Report bugs to: aseba-dev@gna.org" << std::endl;
00189 }
00190
00192 void dumpVersion(std::ostream &stream)
00193 {
00194 stream << "Aseba play " << ASEBA_VERSION << std::endl;
00195 stream << "Aseba protocol " << ASEBA_PROTOCOL_VERSION << std::endl;
00196 stream << "Licence LGPLv3: GNU LGPL version 3 <http://www.gnu.org/licenses/lgpl.html>\n";
00197 }
00198
00199 int main(int argc, char *argv[])
00200 {
00201 Dashel::initPlugins();
00202 bool respectTimings = true;
00203 int speedFactor = 1;
00204 std::vector<std::string> targets;
00205 const char* inputFile = 0;
00206
00207 int argCounter = 1;
00208
00209 while (argCounter < argc)
00210 {
00211 const char *arg = argv[argCounter];
00212
00213 if (strcmp(arg, "--fastest") == 0)
00214 {
00215 respectTimings = false;
00216 }
00217 else if (strcmp(arg, "--fast") == 0)
00218 {
00219 speedFactor = 2;
00220 }
00221 else if (strcmp(arg, "--faster") == 0)
00222 {
00223 speedFactor = 4;
00224 }
00225 else if ((strcmp(arg, "-h") == 0) || (strcmp(arg, "--help") == 0))
00226 {
00227 dumpHelp(std::cout, argv[0]);
00228 return 0;
00229 }
00230 else if ((strcmp(arg, "-V") == 0) || (strcmp(arg, "--version") == 0))
00231 {
00232 dumpVersion(std::cout);
00233 return 0;
00234 }
00235 else if (strcmp(arg, "-f") == 0)
00236 {
00237 argCounter++;
00238 if (argCounter >= argc)
00239 {
00240 dumpHelp(std::cout, argv[0]);
00241 return 1;
00242 }
00243 else
00244 inputFile = argv[argCounter];
00245 }
00246 else
00247 {
00248 targets.push_back(argv[argCounter]);
00249 }
00250 argCounter++;
00251 }
00252
00253 if (targets.empty())
00254 targets.push_back(ASEBA_DEFAULT_TARGET);
00255
00256 try
00257 {
00258 Aseba::Player player(inputFile, respectTimings, speedFactor);
00259 for (size_t i = 0; i < targets.size(); i++)
00260 player.connect(targets[i]);
00261 player.run();
00262 }
00263 catch(Dashel::DashelException e)
00264 {
00265 std::cerr << e.what() << std::endl;
00266 }
00267
00268 return 0;
00269 }