SpikeStream Application Library  0.2
ArchivePlayerThread.cpp
Go to the documentation of this file.
00001 //SpikeStream includes
00002 #include "ArchivePlayerThread.h"
00003 #include "Globals.h"
00004 #include "SpikeStreamException.h"
00005 #include "Util.h"
00006 using namespace spikestream;
00007 
00008 //Qt includes
00009 #include <QTime>
00010 #include <QStringList>
00011 #include <QMutexLocker>
00012 
00015 ArchivePlayerThread::ArchivePlayerThread(DBInfo archiveDBInfo) {
00016     this->archiveDBInfo = archiveDBInfo;
00017     archiveDao = NULL;
00018     archiveID = 0;
00019     updateInterval_ms = 1000;
00020     stepMode = false;
00021 }
00022 
00023 
00025 ArchivePlayerThread::~ArchivePlayerThread(){
00026 }
00027 
00028 
00029 /*----------------------------------------------------------*/
00030 /*-----                 PUBLIC METHODS                 -----*/
00031 /*----------------------------------------------------------*/
00032 
00034 QString ArchivePlayerThread::getErrorMessage(){
00035     return errorMessage;
00036 }
00037 
00038 
00040 bool ArchivePlayerThread::isError(){
00041     return error;
00042 }
00043 
00044 
00046 void ArchivePlayerThread::play(unsigned int startTimeStep, unsigned int archiveID, unsigned int frameRate){
00047     stepMode = false;
00048     this->startTimeStep = startTimeStep;
00049     this->archiveID = archiveID;
00050     this->setFrameRate(frameRate);
00051     start();
00052 }
00053 
00054 
00056 void ArchivePlayerThread::step(unsigned int startTimeStep, unsigned int archiveID){
00057     stepMode = true;
00058     this->startTimeStep = startTimeStep;
00059     this->archiveID = archiveID;
00060     start();
00061 }
00062 
00063 
00066 void ArchivePlayerThread::setFrameRate(unsigned int frameRate){
00067     QMutexLocker locker(&mutex);
00068     this->updateInterval_ms = 1000 / frameRate;
00069 }
00070 
00071 
00073 void ArchivePlayerThread::stop(){
00074     stopThread = true;
00075     stepMode = false;
00076 }
00077 
00078 
00079 /*----------------------------------------------------------*/
00080 /*-----                  PRIVATE SLOTS                 -----*/
00081 /*----------------------------------------------------------*/
00082 
00084 void ArchivePlayerThread::run(){
00085     stopThread = false;
00086     clearError();
00087 
00088     //Check archive has been set
00089     if(archiveID == 0){
00090                 setError("No archive set.");
00091                 return;
00092     }
00093 
00094     //Connect to the database
00095     archiveDao = new ArchiveDao(archiveDBInfo);
00096 
00097     //Initialise variables
00098     unsigned int timeStep = startTimeStep;
00099     QTime startTime;
00100     unsigned int elapsedTime_ms;
00101 
00102     //Get the maximum time step so we know when to stop
00103     unsigned int lastTimeStep = archiveDao->getMaxTimeStep(archiveID);
00104 
00105     if(timeStep > lastTimeStep){
00106                 setError("Play time step is greater than the maximum time step.");
00107     }
00108 
00109     Globals::setArchivePlaying(true);
00110 
00111     while(!stopThread){
00112                 //Record the current time
00113                 startTime = QTime::currentTime();
00114 
00115                 try{
00116                         //Get string list of firing neuron ids
00117                         QList<unsigned> neuronIDList = archiveDao->getFiringNeuronIDs(archiveID, timeStep);
00118 
00119                         //Set flag to true so that thread waits for graphics update before moving to next time step
00120                         waitForGraphics = true;
00121 
00122                         //Inform other classes that time step has changed
00123                         emit timeStepChanged(timeStep, neuronIDList);
00124 
00125                         //Increase time step and quit if we are at the maximum
00126                         ++timeStep;
00127                         if(timeStep > lastTimeStep){
00128                                 stopThread = true;
00129                         }
00130                         //Only display one time step in step mode
00131                         else if (stepMode){
00132                                 stopThread = true;
00133                                 stepMode = false;
00134                         }
00135                         //Sleep until the next time step
00136                         else {
00137                                 //Lock mutex so that update time interval cannot change during this calculation
00138                                 mutex.lock();
00139 
00140                                 //Sleep if task was completed in less than the prescribed interval
00141                                 elapsedTime_ms = startTime.msecsTo(QTime::currentTime());
00142                                 if(elapsedTime_ms < updateInterval_ms){
00143                                         //Sleep for remaning time
00144                                         usleep(1000 * (updateInterval_ms - elapsedTime_ms));
00145                                 }
00146 
00147                                 //Unlock mutex
00148                                 mutex.unlock();
00149 
00150                                 //Wait for graphics to update
00151                                 while(!stopThread && waitForGraphics)
00152                                         usleep(1000);
00153                         }
00154                 }
00155                 catch(SpikeStreamException &ex){
00156                         setError(ex.getMessage());
00157                 }
00158     }
00159 
00160     Globals::setArchivePlaying(false);
00161 
00162     //Clear archive dao
00163     delete archiveDao;
00164     archiveDao = NULL;
00165 }
00166 
00167 
00168 /*----------------------------------------------------------*/
00169 /*-----                PRIVATE METHODS                 -----*/
00170 /*----------------------------------------------------------*/
00171 
00173 void ArchivePlayerThread::clearError(){
00174     error = false;
00175     errorMessage = "";
00176 }
00177 
00178 
00180 void ArchivePlayerThread::setError(const QString& errMsg){
00181     error = true;
00182     stopThread = true;
00183     errorMessage = errMsg;
00184 }
00185 
 All Classes Files Functions Variables Typedefs Friends Defines