src/qvcore/qvapplication.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #include <QDebug>
00026 #include <QMetaType>
00027 #include <QSet>
00028 
00029 #include <qvcore/qvapplication.h>
00030 #include <qvgui/qvgui.h>
00031 #include <qvcore/qvpropertycontainer.h>
00032 
00033 QVApplication::QVApplication (int &argc,char **argv, QString infoString,bool GUIenabled) : QApplication(argc,argv,GUIenabled), info(infoString), unusedArguments(), qvps(), visionInterface(NULL), isRunningFlag(FALSE), workerCount(0), terminateOnLastWorker(TRUE)
00034         {
00035 
00036     if (GUIenabled and not QGLFormat::hasOpenGL() ) {
00037         qFatal("This system has no OpenGL support, and QVision GUI needs it. Exiting.");
00038     }
00039         qRegisterMetaType< QVariant >("QVariant");
00040         qRegisterMetaType< QVCamera::TCameraStatus >("QVCamera::TCameraStatus");
00041         qRegisterMetaType< QVWorker::TWorkerStatus >("QVWorker::TWorkerStatus");
00042         qRegisterMetaType< QVImage<uChar,1> >("QVImage<uChar,1>");
00043         qRegisterMetaType< QVImage<sShort,1> >("QVImage<sShort,1>");
00044         qRegisterMetaType< QVImage<sFloat,1> >("QVImage<sFloat,1>");
00045         qRegisterMetaType< QVImage<uChar,3> >("QVImage<uChar,3>");
00046         qRegisterMetaType< QVImage<sShort,3> >("QVImage<sShort,3>");
00047         qRegisterMetaType< QVImage<sFloat,3> >("QVImage<sFloat,3>");
00048 
00049         unusedArguments = arguments();
00050         unusedArguments.removeAt(0); // Application name removed.
00051         }
00052 
00053 int QVApplication::exec()
00054         {
00055         qDebug() << "QVApplication::exec()";
00056 
00057         // If --help parameter was given, show help and exit:
00058         if(unusedArguments.contains("--help")) 
00059                 {
00060                 printHelp();
00061                 return 0;
00062                 }
00063 
00064         // An initialization error of any QVPropertyContainer aborts execution:
00065         QSetIterator<QVPropertyContainer *> iq(qvps);
00066         while (iq.hasNext())
00067                 {
00068                 QVPropertyContainer* qvp = iq.next();
00069                 QString lastError;
00070                 if((lastError = qvp->getLastError()) != QString())
00071                         {
00072                         std::cerr << "Error initializing QVApplication: "
00073                                           << qPrintable(lastError) << std::endl;
00074                         return -1;
00075                         }
00076                 }
00077 
00078         // If there are unused arguments, show error and exit
00079         if(not unusedArguments.isEmpty())
00080                 {
00081                 QListIterator<QString> i(unusedArguments);
00082                 while (i.hasNext())
00083                         std::cerr << "Error initializing QVApplication: "
00084                                           << "unknown command line parameter: "
00085                                           << qPrintable(i.next()) << std::endl;
00086                 return -1;
00087                 }
00088 
00089         // Now we will open all cameras:
00090         iq.toFront();
00091         while (iq.hasNext())
00092                 {
00093                 QVPropertyContainer* qvp = iq.next();
00094                 QVCamera* camera;
00095                 if((camera = dynamic_cast<QVCamera*>(qvp)) != NULL)
00096                         if(camera->isClosed())
00097                                 if(not camera->openCam())
00098                                         {
00099                                         std::cerr << "Error initializing QVApplication: "
00100                                                           << "could not open camera: "
00101                                                           << qPrintable(camera->getName()) << std::endl;
00102                                         return -1;
00103                                         }
00104                 }
00105 
00106         qDebug() << "QVApplication::exec(): cameras opened";
00107 
00108         // Connect and send an initial signal for the QVThreads to start running
00109         // later, once the GUI is up and running (the initWorkers() slot will be
00110         // lately called by the exec() method):
00111         connect(this,SIGNAL(inited()),this,SLOT(initWorkers()));
00112         emit inited();
00113 
00114         qDebug() << "Entering in QApplication::exec()";
00115         isRunningFlag = TRUE;
00116         int returnvalue = QApplication::exec();
00117         qDebug() << "Back from QApplication::exec()";
00118 
00119         qDebug() << "QVApplication::exec() <- return";
00120         return returnvalue;
00121 }
00122 
00123 QStringList QVApplication::getUnusedArguments()
00124         { return unusedArguments; }
00125 
00126 void QVApplication::setArgumentAsUsed(QString argument)
00127         {
00128         qDebug() << "QVApplication::setArgumentAsUsed(QString,bool)";
00129         int index = unusedArguments.indexOf(argument);
00130         if(index != -1)
00131                 unusedArguments.removeAt(index);
00132         qDebug() << "QVApplication::setArgumentAsUsed(QString,bool) <- return";
00133         }
00134 
00135 void QVApplication::registerQVPropertyContainer(QVPropertyContainer *qvp)
00136         {
00137         qDebug() << "QVApplication::registerQVPropertyContainer(" << qvp->getName() << ")";
00138         qvps.insert(qvp);
00139         qDebug() << "QVApplication::registerQVPropertyContainer(" << qvp->getName() << ") -> return";
00140         }
00141 
00142 void QVApplication::deregisterQVPropertyContainer(QVPropertyContainer *qvp)
00143         {
00144         qDebug() << "QVApplication::registerQVPropertyContainer(" << qvp->getName() << ")";
00145         qvps.remove(qvp);
00146         qDebug() << "QVApplication::registerQVPropertyContainer(" << qvp->getName() << ") -> return";
00147         }
00148 
00149 void QVApplication::registerGUI(QVGUI *visionInterface) 
00150         {
00151         this->visionInterface = visionInterface;
00152         }
00153 
00154 void QVApplication::printHelp() const
00155         {
00156         qDebug() << "QVApplication::printHelp()";
00157 
00158         std::cout << "Usage: " << qPrintable(arguments().first())
00159                           << " [OPTIONS]" << std::endl;
00160         if (info != QString())
00161                 std::cout << qPrintable(info) << std::endl;
00162         std::cout << std::endl;
00163         QSetIterator<QVPropertyContainer *> iq(qvps);
00164         while (iq.hasNext())
00165                 {
00166                 QString infoHolder = iq.next()->infoInputProperties();
00167                 if(infoHolder != QString() )
00168                         std::cout << qPrintable(infoHolder) << std::endl;
00169                 }
00170         qDebug() << "QVApplication::printHelp() <~ return";
00171         }
00172 
00173 void QVApplication::quit()
00174         {
00175         qDebug() << "QVApplication::quit()";
00176         // We order all workers to finish...
00177         QSetIterator<QVPropertyContainer *> iq(qvps);
00178         while (iq.hasNext())
00179                 {
00180                 QVPropertyContainer* qvp = iq.next();
00181                 QVWorker* worker;
00182                 if((worker = dynamic_cast<QVWorker*>(qvp)) != NULL)
00183                         worker->finish();
00184                 }
00185         iq.toFront();
00186         // ... and then wait for all of them (Warning, it won't work if we try to
00187         // finish and wait in the same loop).
00188         while (iq.hasNext())
00189                 {
00190                 QVPropertyContainer* qvp = iq.next();
00191                 QVWorker* worker;
00192                 if((worker = dynamic_cast<QVWorker*>(qvp)) != NULL)
00193                         // Needed to treat possible pending Qt::BlockingQueuedConnection
00194                         // signals from qvpropertycontainer.h:
00195                         while(not worker->wait(10/*ms*/)) processEvents();
00196                 }
00197         qDebug() << "QVApplication::quit(): workers finished";
00198 
00199         // Now we will close all cameras:
00200         iq.toFront();
00201         while (iq.hasNext())
00202                 {
00203                 QVPropertyContainer* qvp = iq.next();
00204                 QVCamera* camera;
00205                 if((camera = dynamic_cast<QVCamera*>(qvp)) != NULL)
00206                         if(!camera->isClosed())
00207                                 camera->closeCam();
00208                 }
00209         qDebug() << "QVApplication::finish(): cameras closed";
00210 
00211         this->exit(0);
00212         }
00213 
00214 
00215 void QVApplication::workerFinished()
00216 {
00217         workerCount--;
00218         if(workerCount == 0)
00219                 if(terminateOnLastWorker)
00220                         quit();
00221 }
00222 
00223 void QVApplication::initWorkers()
00224 {
00225         qDebug() << "QVApplication::initWorkers()";
00226         QSetIterator<QVPropertyContainer *> iq(qvps);
00227         while (iq.hasNext())
00228                 {
00229                 QVPropertyContainer* qvp = iq.next();
00230                 QVWorker* worker;
00231                 if((worker = dynamic_cast<QVWorker*>(qvp)) != NULL)
00232                         {
00233                                 workerCount++;
00234                                 worker->moveToThread(worker);
00235                                 connect(worker,SIGNAL(finished()),this,SLOT(workerFinished()));
00236                                 worker->start();
00237                         }
00238                 }
00239         qDebug() << "QVApplication::initWorkers() <~ return";
00240 }

Generated on Thu Mar 13 19:18:16 2008 for QVision by  doxygen 1.5.3