00001
00002 #ifndef INCLUDED_FileSystemDataSource_h_
00003 #define INCLUDED_FileSystemDataSource_h_
00004
00005 #include "local/DataSource.h"
00006 #include "Shared/plist.h"
00007 #include "Shared/get_time.h"
00008 #include "IPC/Thread.h"
00009 #include <list>
00010 #include <iostream>
00011
00012 class LoggedDataDriver;
00013
00014
00015
00016
00017 class FileSystemDataSource : public virtual DataSource, public virtual plist::Dictionary, public virtual plist::PrimitiveListener {
00018 public:
00019
00020 FileSystemDataSource(LoggedDataDriver& p, const std::string& filter)
00021 : DataSource(), plist::Dictionary(), PrimitiveListener(), path(), filenameFilter(filter), loop(true), framerate(1000.f/(FrameTime*NumFrames)), verbose(0),
00022 poller(*this), files(), curfile(files.begin()),
00023 initialDelay(0), nextTime(0), indexed(true), freezeTime(), timeScale(NULL), parent(p), actualLoopTime(0), naturalLoopTime(0), lock(), registered(false)
00024 {
00025 setLoadSavePolicy(FIXED,SYNC);
00026 addEntry("Path",path,"If set, overrides the common LoggedData driver path. In addition to directory or index file, can also be set to a single input data file.");
00027 addEntry("FileFilter",filenameFilter,"If Source is a directory or index file, only files matching the filter will be loaded from it.");
00028 addEntry("Loop",loop,"If true, restart file list at the beginning when the end is reached; otherwise just stop loading data");
00029 addEntry("Framerate",framerate,"The sensors updates per second which should be loaded.\nNote this is limited by the global Sensors.Framerate setting");
00030 addEntry("Verbose",verbose,"Controls how much feedback to give on the console regarding progress\n 0 - none\n 1 - report when messages are dropped\n 2 - also report when a message is sent\n 3 - also report when loop occurs\n 4 - also report when each message is preloaded");
00031 }
00032
00033
00034 ~FileSystemDataSource();
00035
00036 virtual unsigned int nextTimestamp();
00037 virtual const std::string& nextName();
00038 virtual bool advance();
00039 virtual void registerSource();
00040 virtual bool isRegistered() const { return registered; }
00041 virtual void deregisterSource();
00042 virtual void enteringRealtime(const plist::Primitive<double>& simTimeScale);
00043 virtual void leavingRealtime(bool );
00044
00045
00046
00047 virtual void setFrame(unsigned int f, unsigned int numPreload=2);
00048
00049
00050 virtual void nextFrame(unsigned int numPreload=2);
00051
00052
00053
00054 virtual double getLoopTime(bool actual=true) const { return actual ? actualLoopTime : naturalLoopTime; }
00055 virtual void setLoopTime(double t);
00056
00057 virtual bool usingIndexFile() const { return indexed; }
00058
00059
00060 void clearFiles();
00061
00062 virtual void plistValueTouched(const plist::PrimitiveBase& pl);
00063 virtual void plistValueChanged(const plist::PrimitiveBase& pl);
00064
00065 virtual void loadXML(xmlNode* node);
00066
00067
00068 virtual const std::string& getUsedPath() const;
00069
00070
00071
00072
00073 virtual bool loadFileList(bool clearCurrent=true, bool reportMissing=true);
00074
00075
00076
00077 plist::Primitive<std::string> path;
00078
00079
00080 plist::Primitive<std::string> filenameFilter;
00081
00082
00083 plist::Primitive<bool> loop;
00084
00085
00086 plist::Primitive<float> framerate;
00087
00088
00089
00090
00091
00092
00093
00094 plist::Primitive<int> verbose;
00095
00096 protected:
00097 static const unsigned int MAX_LOAD=4000;
00098 struct FileInfo;
00099 typedef std::list<FileInfo*> files_t;
00100
00101 struct DataThread : public Thread {
00102 DataThread(FileSystemDataSource& p) : parent(p) {}
00103 virtual void* run();
00104 FileSystemDataSource& parent;
00105 } poller;
00106
00107
00108 virtual bool sendData()=0;
00109
00110 virtual void doFreeze();
00111 virtual void doUnfreeze();
00112 virtual void resetPoller();
00113
00114
00115 virtual void loadSingleFile(const std::string& file);
00116
00117 virtual void loadFileListFromDirectory();
00118
00119
00120
00121
00122 virtual bool loadFileListFromIndex();
00123
00124
00125 virtual double calcLoopTime() const;
00126
00127
00128 struct FileInfo {
00129
00130 FileInfo() : filename(), lifetime(0), data(NULL), size(0), refcount(NULL), prepared(false) { }
00131
00132 FileInfo(const std::string& name, double time) : filename(name), lifetime(time), data(NULL), size(0), refcount(NULL), prepared(false) { }
00133
00134 FileInfo(const FileInfo& o) : filename(o.filename), lifetime(o.lifetime), data(o.data), size(o.size), refcount(o.refcount), prepared(false) { if(refcount!=NULL) ++(*refcount); }
00135
00136 FileInfo& operator=(const FileInfo& o) {
00137 release();
00138 filename=o.filename; lifetime=o.lifetime; data=o.data; size=o.size; refcount=o.refcount;
00139 if(refcount!=NULL)
00140 ++(*refcount);
00141 return *this;
00142 }
00143
00144 virtual ~FileInfo() { release(); }
00145
00146 virtual void prepare();
00147 virtual void done();
00148 virtual void release();
00149
00150 const char* getData() const { return data; }
00151 size_t getSize() const { return size; }
00152 void setData(char* d, size_t s) { release(); data=d; size=s; refcount=new unsigned int; *refcount=1; }
00153 bool isPrepared() const { return prepared; }
00154
00155 std::string filename;
00156 double lifetime;
00157 protected:
00158 char* data;
00159 size_t size;
00160 unsigned int* refcount;
00161 bool prepared;
00162 };
00163
00164
00165 virtual void preprepare(const FileSystemDataSource::files_t::iterator& fi);
00166
00167
00168 virtual void enqueueFile(const std::string& name, double lifetime) { files.push_back(new FileInfo(name,lifetime)); }
00169
00170 files_t files;
00171 files_t::iterator curfile;
00172 double initialDelay;
00173 double nextTime;
00174 bool indexed;
00175 unsigned int freezeTime;
00176 const plist::Primitive<double>* timeScale;
00177 LoggedDataDriver& parent;
00178 double actualLoopTime;
00179 double naturalLoopTime;
00180 Thread::Lock lock;
00181 bool registered;
00182
00183 private:
00184 FileSystemDataSource(const FileSystemDataSource&);
00185 FileSystemDataSource& operator=(const FileSystemDataSource&);
00186 };
00187
00188
00189
00190
00191
00192
00193 #endif