Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

DataStreamDriver.cc

Go to the documentation of this file.
00001 #include "DataStreamDriver.h"
00002 
00003 using namespace std; 
00004 
00005 unsigned int DataStreamDriver::nextTimestamp() {
00006   CommPort * comm = getComm(commName);
00007   if(comm==NULL || !comm->isReadable() || srcFrameRate<=0)
00008     return -1U;
00009   return static_cast<unsigned int>(timestamp + 1000/srcFrameRate + 0.5f);
00010 }
00011 
00012 bool DataStreamDriver::advance() {
00013   ASSERTRETVAL(!isStarted(), "DataStreamDriver::advance() called in realtime mode",false);
00014   
00015   CommPort * comm = getComm(commName);
00016   if(comm==NULL || !comm->isReadable() || srcFrameRate<=0)
00017     return false;
00018   
00019   MarkScope autolock(*comm);
00020   std::istream is(&comm->getReadStreambuf());
00021   is.exceptions(ios_base::badbit);
00022   // make sure we have data... might cancel out while we're waiting for an image to come
00023   char firstByte;
00024   std::streamsize numread = is.readsome(&firstByte,1);
00025   if(!is)
00026     return false;
00027   if(numread==0) { // no data
00028     if(requestFrame(*comm) || getTimeScale()<=0) { // maybe we need to ask for it (subclass hook)
00029       // returned true, wait for image
00030       is.get(firstByte);
00031       if(!is)
00032         return false;
00033     } else {
00034       // just block on the next image
00035       is.read(&firstByte,1);
00036       testCancel();
00037       if(!is) { // still no data, return to allow heartbeat on previous image
00038         timestamp = get_time();
00039         return false;
00040       }
00041     }
00042   }
00043   
00044   is.putback(firstByte);
00045   return readData(is);
00046 }
00047 
00048 void DataStreamDriver::registerSource() {
00049   registered=true;
00050   connect(getComm(commName));
00051 }
00052 
00053 void DataStreamDriver::deregisterSource() {
00054   registered=false;
00055   disconnect(getComm(commName));
00056 }
00057 
00058 void DataStreamDriver::doUnfreeze() {
00059   realtime=true;
00060   srcFrameRate.addPrimitiveListener(this);
00061   ASSERTRET(!isStarted(),"DataStreamDriver was already running on call to enteringRealtime()");
00062   if(srcFrameRate>0)
00063     start();
00064 }
00065 
00066 void DataStreamDriver::doFreeze() {
00067   realtime=false;
00068   if(isStarted())
00069     stop().join();
00070   srcFrameRate.removePrimitiveListener(this);
00071 }
00072 
00073 void DataStreamDriver::plistValueChanged(const plist::PrimitiveBase& pl) {
00074   if(&pl==&commName) {
00075     // if here, then setDataSourceThread has been called, thus when commName changes,
00076     // need to close old one and reopen new one
00077     disconnect(getComm(commName.getPreviousValue()));
00078     connect(getComm(commName));
00079   } else if(&pl==&srcFrameRate) {
00080     if(srcFrameRate>0 && realtime && !isStarted())
00081       start();
00082     else if(srcFrameRate<=0 && isStarted())
00083       stop();
00084   } else {
00085     std::cerr << "Unhandled value change in " << getClassName() << ": " << pl.get() << std::endl;
00086   }
00087 }
00088 
00089 void* DataStreamDriver::run() {
00090   while(true) {
00091     CommPort * comm = getComm(commName);
00092     if(comm==NULL || srcFrameRate<=0)
00093       return NULL;
00094     
00095     testCancel();
00096     if(!comm->isReadable()) {
00097       usleep(500*1000);
00098       continue;
00099     }
00100     MarkScope autolock(*comm);
00101     std::istream is(&comm->getReadStreambuf());
00102     is.exceptions(ios_base::badbit);
00103     readData(is);
00104     if(is && paceInput) {
00105       unsigned int next = nextTimestamp();
00106       unsigned int cur = get_time();
00107       if(next>cur)
00108         usleep(static_cast<useconds_t>((next-cur)*1000/getTimeScale()+.5));
00109     }
00110   }
00111 }
00112 
00113 void DataStreamDriver::connect(CommPort* comm) {
00114   if(comm!=NULL) {
00115     MarkScope autolock(*comm);
00116     comm->open();
00117     if(getTimeScale>0 && realtime)
00118       start();
00119   }
00120   commName.addPrimitiveListener(this);
00121   srcFrameRate.addPrimitiveListener(this);
00122 }
00123 
00124 void DataStreamDriver::disconnect(CommPort* comm) {
00125   if(comm!=NULL) {
00126     if(isStarted())
00127       stop().join();
00128     MarkScope autolock(*comm);
00129     comm->close();
00130   }
00131   commName.removePrimitiveListener(this);
00132   srcFrameRate.removePrimitiveListener(this);
00133 }
00134 
00135 
00136 /*! @file
00137  * @brief 
00138  * @author Ethan Tira-Thompson (ejt) (Creator)
00139  */

Tekkotsu Hardware Abstraction Layer 5.1CVS
Generated Mon May 9 05:01:38 2016 by Doxygen 1.6.3