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

Generated on Thu Jul 17 17:23:27 2008 for QVision by  doxygen 1.5.3