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         qRegisterMetaType< QVariant >("QVariant");
00036         qRegisterMetaType< QVCamera::TCameraStatus >("QVCamera::TCameraStatus");
00037         qRegisterMetaType< QVWorker::TWorkerStatus >("QVWorker::TWorkerStatus");
00038         qRegisterMetaType< QVImage<uChar,1> >("QVImage<uChar,1>");
00039         qRegisterMetaType< QVImage<sShort,1> >("QVImage<sShort,1>");
00040         qRegisterMetaType< QVImage<sFloat,1> >("QVImage<sFloat,1>");
00041         qRegisterMetaType< QVImage<uChar,3> >("QVImage<uChar,3>");
00042         qRegisterMetaType< QVImage<sShort,3> >("QVImage<sShort,3>");
00043         qRegisterMetaType< QVImage<sFloat,3> >("QVImage<sFloat,3>");
00044 
00045         unusedArguments = arguments();
00046         unusedArguments.removeAt(0); // Application name removed.
00047         }
00048 
00049 int QVApplication::exec()
00050         {
00051         qDebug() << "QVApplication::exec()";
00052 
00053         // If --help parameter was given, show help and exit:
00054         if(unusedArguments.contains("--help")) 
00055                 {
00056                 printHelp();
00057                 return 0;
00058                 }
00059 
00060         // An initialization error of any QVPropertyContainer aborts execution:
00061         QSetIterator<QVPropertyContainer *> iq(qvps);
00062         while (iq.hasNext())
00063                 {
00064                 QVPropertyContainer* qvp = iq.next();
00065                 QString lastError;
00066                 if((lastError = qvp->getLastError()) != QString())
00067                         {
00068                         std::cerr << "Error initializing QVApplication: "
00069                                           << qPrintable(lastError) << std::endl;
00070                         return -1;
00071                         }
00072                 }
00073 
00074         // If there are unused arguments, show error and exit
00075         if(not unusedArguments.isEmpty())
00076                 {
00077                 QListIterator<QString> i(unusedArguments);
00078                 while (i.hasNext())
00079                         std::cerr << "Error initializing QVApplication: "
00080                                           << "unknown command line parameter: "
00081                                           << qPrintable(i.next()) << std::endl;
00082                 return -1;
00083                 }
00084 
00085         // Now we will open all cameras:
00086         iq.toFront();
00087         while (iq.hasNext())
00088                 {
00089                 QVPropertyContainer* qvp = iq.next();
00090                 QVCamera* camera;
00091                 if((camera = dynamic_cast<QVCamera*>(qvp)) != NULL)
00092                         if(camera->isClosed())
00093                                 if(not camera->openCam())
00094                                         {
00095                                         std::cerr << "Error initializing QVApplication: "
00096                                                           << "could not open camera: "
00097                                                           << qPrintable(camera->getName()) << std::endl;
00098                                         return -1;
00099                                         }
00100                 }
00101 
00102         qDebug() << "QVApplication::exec(): cameras opened";
00103 
00104         // Connect and send an initial signal for the QVThreads to start running
00105         // later, once the GUI is up and running (the initWorkers() slot will be
00106         // lately called by the exec() method):
00107         connect(this,SIGNAL(inited()),this,SLOT(initWorkers()));
00108         emit inited();
00109 
00110         qDebug() << "Entering in QApplication::exec()";
00111         isRunningFlag = TRUE;
00112         int returnvalue = QApplication::exec();
00113         qDebug() << "Back from QApplication::exec()";
00114 
00115         qDebug() << "QVApplication::exec() <- return";
00116         return returnvalue;
00117 }
00118 
00119 QStringList QVApplication::getUnusedArguments()
00120         { return unusedArguments; }
00121 
00122 void QVApplication::setArgumentAsUsed(QString argument)
00123         {
00124         qDebug() << "QVApplication::setArgumentAsUsed(QString,bool)";
00125         int index = unusedArguments.indexOf(argument);
00126         if(index != -1)
00127                 unusedArguments.removeAt(index);
00128         qDebug() << "QVApplication::setArgumentAsUsed(QString,bool) <- return";
00129         }
00130 
00131 void QVApplication::registerQVPropertyContainer(QVPropertyContainer *qvp)
00132         {
00133         qDebug() << "QVApplication::registerQVPropertyContainer(" << qvp->getName() << ")";
00134         qvps.insert(qvp);
00135         qDebug() << "QVApplication::registerQVPropertyContainer(" << qvp->getName() << ") -> return";
00136         }
00137 
00138 void QVApplication::deregisterQVPropertyContainer(QVPropertyContainer *qvp)
00139         {
00140         qDebug() << "QVApplication::registerQVPropertyContainer(" << qvp->getName() << ")";
00141         qvps.remove(qvp);
00142         qDebug() << "QVApplication::registerQVPropertyContainer(" << qvp->getName() << ") -> return";
00143         }
00144 
00145 void QVApplication::registerGUI(QVGUI *visionInterface) 
00146         {
00147         this->visionInterface = visionInterface;
00148         }
00149 
00150 void QVApplication::printHelp() const
00151         {
00152         qDebug() << "QVApplication::printHelp()";
00153 
00154         std::cout << "Usage: " << qPrintable(arguments().first())
00155                           << " [OPTIONS]" << std::endl;
00156         if (info != QString())
00157                 std::cout << qPrintable(info) << std::endl;
00158         std::cout << std::endl;
00159         QSetIterator<QVPropertyContainer *> iq(qvps);
00160         while (iq.hasNext())
00161                 {
00162                 QString infoHolder = iq.next()->infoInputProperties();
00163                 if(infoHolder != QString() )
00164                         std::cout << qPrintable(infoHolder) << std::endl;
00165                 }
00166         qDebug() << "QVApplication::printHelp() <~ return";
00167         }
00168 
00169 void QVApplication::quit()
00170         {
00171         qDebug() << "QVApplication::quit()";
00172         // We order all workers to finish...
00173         QSetIterator<QVPropertyContainer *> iq(qvps);
00174         while (iq.hasNext())
00175                 {
00176                 QVPropertyContainer* qvp = iq.next();
00177                 QVWorker* worker;
00178                 if((worker = dynamic_cast<QVWorker*>(qvp)) != NULL)
00179                         worker->finish();
00180                 }
00181         iq.toFront();
00182         // ... and then wait for all of them (Warning, it won't work if we try to
00183         // finish and wait in the same loop).
00184         while (iq.hasNext())
00185                 {
00186                 QVPropertyContainer* qvp = iq.next();
00187                 QVWorker* worker;
00188                 if((worker = dynamic_cast<QVWorker*>(qvp)) != NULL)
00189                         // Needed to treat possible pending Qt::BlockingQueuedConnection
00190                         // signals from qvpropertycontainer.h:
00191                         while(not worker->wait(10/*ms*/)) processEvents();
00192                 }
00193         qDebug() << "QVApplication::quit(): workers finished";
00194 
00195         // Now we will close all cameras:
00196         iq.toFront();
00197         while (iq.hasNext())
00198                 {
00199                 QVPropertyContainer* qvp = iq.next();
00200                 QVCamera* camera;
00201                 if((camera = dynamic_cast<QVCamera*>(qvp)) != NULL)
00202                         if(!camera->isClosed())
00203                                 camera->closeCam();
00204                 }
00205         qDebug() << "QVApplication::finish(): cameras closed";
00206 
00207         this->exit(0);
00208         }
00209 
00210 
00211 void QVApplication::workerFinished()
00212 {
00213         workerCount--;
00214         if(workerCount == 0)
00215                 if(terminateOnLastWorker)
00216                         quit();
00217 }
00218 
00219 void QVApplication::initWorkers()
00220 {
00221         qDebug() << "QVApplication::initWorkers()";
00222         QSetIterator<QVPropertyContainer *> iq(qvps);
00223         while (iq.hasNext())
00224                 {
00225                 QVPropertyContainer* qvp = iq.next();
00226                 QVWorker* worker;
00227                 if((worker = dynamic_cast<QVWorker*>(qvp)) != NULL)
00228                         {
00229                                 workerCount++;
00230                                 worker->moveToThread(worker);
00231                                 connect(worker,SIGNAL(finished()),this,SLOT(workerFinished()));
00232                                 worker->start();
00233                         }
00234                 }
00235         qDebug() << "QVApplication::initWorkers() <~ return";
00236 }

Generated on Fri Feb 22 18:26:55 2008 for QVision by  doxygen 1.5.3