Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
FileSystemDataSource.hGo to the documentation of this file.00001 //-*-c++-*- 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 <list> 00009 #include <iostream> 00010 00011 class LoggedDataDriver; 00012 00013 //! Manages the loading of a series of files from disk 00014 /*! Can handle an index file listing other data files and their timestamps, 00015 * a directory holding a set of files, or a single explicit file. */ 00016 class FileSystemDataSource : public virtual DataSource, public virtual plist::Dictionary, public virtual plist::PrimitiveListener { 00017 public: 00018 //! constructor 00019 FileSystemDataSource(LoggedDataDriver& p, const std::string& filter) 00020 : DataSource(), plist::Dictionary(), PrimitiveListener(), path(), filenameFilter(filter), loop(true), files(), curfile(files.begin()), 00021 initialDelay(0), nextTime(0), indexed(true), sn(0), freezeTime(), parent(p), actualLoopTime(0), naturalLoopTime(0) 00022 { 00023 setLoadSavePolicy(FIXED,SYNC); 00024 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."); 00025 addEntry("FileFilter",filenameFilter,"If Source is a directory or index file, only files matching the filter will be loaded from it."); 00026 addEntry("Loop",loop,"If true, restart file list at the beginning when the end is reached; otherwise just stop loading data"); 00027 } 00028 00029 //! destructor 00030 ~FileSystemDataSource(); 00031 00032 virtual unsigned int nextTimestamp(); 00033 virtual const std::string& nextName(); 00034 virtual unsigned int getData(const char *& payload, unsigned int& payloadSize, unsigned int& timestamp, std::string& name); 00035 virtual void setDataSourceThread(LoadDataThread* th); 00036 virtual void setDataSourceFramerate(float fr); 00037 00038 //! sets the next frame to be sent (e.g. pass 0 to reset to the first frame) 00039 /*! prepares (pre-loads) @a numPreload frames from the new #curfile onward */ 00040 virtual void setFrame(unsigned int f, unsigned int numPreload=2); 00041 00042 //! increments #curfile to the next frame, preparing (pre-loads) @a numPreload frames from the new #curfile onward 00043 virtual void nextFrame(unsigned int numPreload=2); 00044 00045 //! returns the total time taken to loop over the files 00046 /*! @param actual if false, will return the "natural" time of a loop, ignoring setLoopTime() effects */ 00047 virtual float getLoopTime(bool actual=true) const { return actual ? actualLoopTime : naturalLoopTime; } 00048 virtual void setLoopTime(float t); //!< adds time to the final frame to increase total sequence time to @a t milliseconds 00049 00050 virtual bool usingIndexFile() const { return indexed; } //!< returns #indexed 00051 00052 //! empties #files 00053 void clearFiles(); 00054 00055 virtual void plistValueChanged(const plist::PrimitiveBase& pl); 00056 00057 virtual void loadXML(xmlNode* node); 00058 00059 //! returns the target path, either #path, or parent.path if #path is empty 00060 virtual const std::string& getUsedPath() const; 00061 00062 //! call this to (re)load the list of available file names from disk 00063 /*! If @a clearCurrent is set, then the current file list will be cleared; 00064 * otherwise, the loaded files will be appended to the current queue */ 00065 virtual void loadFileList(bool clearCurrent=true, bool reportMissing=true); 00066 00067 //! The directory, data file, or index file from which to load via call to loadFileListFromDirectory(), loadSingleFile(), or loadFileListFromIndex() 00068 /*! A single file can be either a single data file (e.g. sensor or camera image), or an index file as output by VisionGUI, or in the format 'filename <tab> time', where 'filename' is an absolute path or relative to the directory containing the index file, and 'time' is in milliseconds, relative to the time at which the index file is loaded.\n In the future, this could also be network addresses for teleoperation and remote processing. */ 00069 plist::Primitive<std::string> path; 00070 00071 //! a regular expression (POSIX.2 extended format) to select which files to load from #path, if #path is a directory or index file 00072 plist::Primitive<std::string> filenameFilter; 00073 00074 //! controls whether to restart #curfile at the beginning of #files when it reaches the end 00075 plist::Primitive<bool> loop; 00076 00077 protected: 00078 virtual void doFreeze() { freezeTime=get_time(); } 00079 virtual void doUnfreeze() { nextTime+=get_time()-freezeTime; } 00080 00081 //! if thread is NULL, mark all outputs as ignored, and if thread is non-NULL, mark them all as provided 00082 virtual void updateProvidingOutputs(); 00083 00084 //! load a single file 00085 virtual void loadSingleFile(const std::string& file); 00086 //! load a list of files from a directory specified by #path 00087 virtual void loadFileListFromDirectory(); 00088 //! load a list of files from an index file specified by #path 00089 /*! This supports either the format produced by VisionGUI, or a simplier '<code>filename [<tab> time]\\n</code>' format, 00090 * where if @c time is unspecified, the frame's time is incremented by the #framerate from the previously listed file. 00091 * Filenames should either be either absolute paths or relative to the directory which contains the index file.*/ 00092 virtual bool loadFileListFromIndex(); 00093 00094 //! adds up the lifetime of all #files, plus #initialDelay 00095 virtual float calcLoopTime() const; 00096 00097 //! does the actual work of loading and processing data from disk, subclasses should override this if they want to decompress/pre-parse the data 00098 /*! This implementation merely loads the data directly into memory with no processing or parsing. 00099 * @param[in] file full path of file to load 00100 * @return pointer to the data, or NULL if error */ 00101 virtual char* loadData(const std::string& file); 00102 00103 //! stores basic information regarding each file in the queue, including routines for loading to and from disk 00104 struct FileInfo { 00105 //! default constructor 00106 FileInfo() : filename(), lifetime(0), data(NULL), size(0), prepared(false) {} 00107 //! basic constructor, provide name and lifetime, data and size are left empty until later prepare() is called 00108 FileInfo(const std::string& name, float time) : filename(name), lifetime(time), data(NULL), size(0), prepared(false) {} 00109 //! shallow copy constructor -- doesn't copy #data (have to call prepare() to reload) 00110 FileInfo(const FileInfo& fi) : filename(fi.filename), lifetime(fi.lifetime), data(NULL), size(0), prepared(false) { } 00111 //! shallow assignment -- doesn't copy #data (have to call prepare() to reload) 00112 FileInfo& operator=(const FileInfo& fi) { release(); filename=fi.filename; lifetime=fi.lifetime; return *this; } 00113 //! destructor 00114 virtual ~FileInfo() { release(); } 00115 00116 virtual void prepare(); //!< make sure data is in physical memory for imminent usage 00117 virtual void done(); //!< we can let the data out of memory if needed 00118 virtual void release(); //!< if data is in an allocated region, free it 00119 00120 std::string filename; //!< the path to the file to load 00121 float lifetime; //!< time for which this frame is "current", before next frame should be sent 00122 char* data; //!< loaded/parsed contents of #filename, all ready to send, just need to copy into message 00123 unsigned int size; //!< size of buffer pointed to by #data (may be decompressed/processed, different than file size...) 00124 bool prepared; //!< true if prepare() has been called 00125 }; 00126 00127 //! creates a new entry on #files, virtual to allow subclasses to use a FileInfo subclass with more meta data (e.g. see FileSystemImageSource::ImageInfo) 00128 virtual void enqueueFile(const std::string& name, float lifetime) { files.push_back(new FileInfo(name,lifetime)); } 00129 00130 static const unsigned int MAX_LOAD=4000; //!< maximum number of data elements to try to keep 'active'. If there's more than this in #files, we'll only load one at time, and immediately release it afterward 00131 typedef std::list<FileInfo*> files_t; //!< type of #files, the list of files to load 00132 files_t files; // collection of FileInfo entries 00133 files_t::iterator curfile; //!< an iterator referencing #files -- indicates next file to send 00134 float initialDelay; //!< milliseconds to wait before sending first frame 00135 float nextTime; //!< timestamp that #curfile should be sent 00136 bool indexed; //!< true if the file list was specified by an index file 00137 unsigned int sn; //!< frame serial number, incremented by getData() 00138 unsigned int freezeTime; //!< time at which doFreeze was called 00139 LoggedDataDriver& parent; //!< device driver this is a member of 00140 float actualLoopTime; //!< time it would take to run through all of the loaded frames 00141 float naturalLoopTime; //!< time it would take to run through all of the frames as set immediately after load (i.e. no setLoopTime()) 00142 }; 00143 00144 /*! @file 00145 * @brief 00146 * @author Ethan Tira-Thompson (ejt) (Creator) 00147 * 00148 * $Author: ejt $ 00149 * $Name: tekkotsu-4_0 $ 00150 * $Revision: 1.5 $ 00151 * $State: Exp $ 00152 * $Date: 2007/11/10 22:58:12 $ 00153 */ 00154 00155 #endif |
Tekkotsu Hardware Abstraction Layer 4.0 |
Generated Thu Nov 22 01:00:53 2007 by Doxygen 1.5.4 |