main.cpp 6.39 KB
Newer Older
1 2 3 4
#include <iostream>
#include <fstream>
#include <string>

Thiago C. Santini's avatar
Thiago C. Santini committed
5 6 7 8 9 10 11 12 13
#include <QtWidgets>
#include <QTime>
#include <QDir>
#include <QThread>
#include <QSplashScreen>

#include "ImageAcquisition.h"
#include "ImageProcessing.h"
#include "NetworkStream.h"
Thiago C. Santini's avatar
Thiago C. Santini committed
14
#include "ThreadManager.h"
15
#include "Trigger.h"
Thiago C. Santini's avatar
Thiago C. Santini committed
16 17 18 19

#include "Journal.h"
#include "Gui.h"
#include "settings.h"
20
#include "utils.h"
Thiago C. Santini's avatar
Thiago C. Santini committed
21

Thiago C. Santini's avatar
Thiago C. Santini committed
22
#define VERSION "2.1.0"
Thiago C. Santini's avatar
Thiago C. Santini committed
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QPixmap center(":icons/splash.png");
    QSplashScreen splash(center);
    splash.show();
    splash.showMessage("Checking settings...", Qt::AlignAbsolute, Qt::white);
    app.processEvents();

    // Verify if settings exists and update missing values
    QFile settingsFile(settingsFileName);
    if (! settingsFile.exists()) {
        QString tmp;
        tmp.append(QString("Could not find %1.\n\n").arg(settingsFileName));
        tmp.append("Creating file with default settings.\n\n");
        tmp.append("I will not make assumptions regarding your master/slave camera configuration.\n");
        int x = splash.geometry().x() + splash.geometry().width() + 10;
        int y = splash.geometry().y();
        QMessageBox msg(QMessageBox::Icon::Warning, "No settings file found.", tmp, QMessageBox::Ok);
        msg.move(x,y);
        msg.show();
        QThread::msleep(500);
        splash.setPixmap(QPixmap(":icons/splash-right.png"));
        app.processEvents();
        msg.exec();
        splash.setPixmap(center);
        app.processEvents();
    }
    updateSettings();

    // Allow copy pasting
    app.setStyleSheet("QMessageBox { messagebox-text-interaction-flags: 5; }");

    // Create the output directory if needed and make it the current directory
58
    gBinaryPath = QDir::currentPath();
Thiago C. Santini's avatar
Thiago C. Santini committed
59 60 61 62 63 64 65
    QDir outputDir(settings.value("general/outputDirectory").toString());
    if (!outputDir.exists())
        outputDir.mkpath(".");
    QDir::setCurrent(outputDir.path());

    qRegisterMetaType<JournalEntry>();

66 67 68 69 70 71 72
    qInstallMessageHandler(logMessages);
    initBanner();

    /*********************************************************************
     * Instantiate the stages
     ********************************************************************/

Thiago C. Santini's avatar
Thiago C. Santini committed
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
    // Image acquisition stage
    splash.showMessage("Starting image acquisition stage...", Qt::AlignAbsolute, Qt::white);
    app.processEvents();
    ImageAcquisition imageAcquisition;
    if (!imageAcquisition.ready)
        return -1;

    // Image processing stage
    splash.showMessage("Starting image processing stage...", Qt::AlignAbsolute, Qt::white);
    app.processEvents();
    ImageProcessing imageProcessing;

    // Data journaling stage
    splash.showMessage("Starting data journaling stage...", Qt::AlignAbsolute, Qt::white);
    app.processEvents();
    Journal journal("journal");
    journal.masterFps = imageAcquisition.master->format.fps;

    // Data streaming stage
    splash.showMessage("Starting data streaming stage...", Qt::AlignAbsolute, Qt::white);
    app.processEvents();
    NetworkStream networkStream;

96
    // Gui update stage (and keyboard triggers)
Thiago C. Santini's avatar
Thiago C. Santini committed
97 98 99 100
    splash.showMessage("Starting GUI...", Qt::AlignAbsolute, Qt::white);
    app.processEvents();
    Gui gui;

101 102 103
    // User triggers that are not handled by other objects/threads
    splash.showMessage("Starting triggers...", Qt::AlignAbsolute, Qt::white);
    Trigger trigger;
Thiago C. Santini's avatar
Thiago C. Santini committed
104 105 106

    imageProcessing.calibration = &gui.calibration;

107 108 109 110
    /*********************************************************************
     * Connect signals & slots
     ********************************************************************/

Thiago C. Santini's avatar
Thiago C. Santini committed
111 112 113 114 115 116
    QObject::connect(&imageAcquisition, SIGNAL(imageAcquisitionDone(JournalEntry)), &imageProcessing, SLOT(processImage(JournalEntry)));

    QObject::connect(&imageProcessing, SIGNAL(imageProcessingDone(JournalEntry)), &networkStream, SLOT(push(JournalEntry)));
    QObject::connect(&imageProcessing, SIGNAL(imageProcessingDone(JournalEntry)), &journal, SLOT(store(JournalEntry)));
    QObject::connect(&imageProcessing, SIGNAL(imageProcessingDone(JournalEntry)), &gui, SLOT(update(JournalEntry)));

117 118 119 120
    // This is a little bit chaotic and will probably be redone in the future
    // The GUI is responsible for part of the recording setup (e.g., subject name), but indexes are handled by the journal
    // Logically, the setup is ready when recordingStarted is emmited (by the journal); at this point we can assume everything
    // has been setup properly
Thiago C. Santini's avatar
Thiago C. Santini committed
121
    QObject::connect(&gui, SIGNAL(setRecording(bool)), &journal, SLOT(setRecording(bool)));
122 123 124 125
    QObject::connect(&journal, SIGNAL(recordingStarted()), &gui, SLOT(recordingStarted()));
    QObject::connect(&journal, SIGNAL(recordingStopped()), &gui, SLOT(recordingStopped()));
    QObject::connect(&journal, SIGNAL(recordingStarted()), &trigger, SLOT(recordingStarted()));
    QObject::connect(&journal, SIGNAL(recordingStopped()), &trigger, SLOT(recordingStopped()));
Thiago C. Santini's avatar
Thiago C. Santini committed
126 127


128 129 130 131 132
    /*********************************************************************
     * Thread Management
     ********************************************************************/

    QThread::currentThread()->setObjectName("Gui");
Thiago C. Santini's avatar
Thiago C. Santini committed
133
    ThreadManager threadManager;
Thiago C. Santini's avatar
Thiago C. Santini committed
134
    QThread::currentThread()->setPriority(QThread::NormalPriority);
Thiago C. Santini's avatar
Thiago C. Santini committed
135 136 137 138
    threadManager.newThread(imageAcquisition, "ImageAcquisitionThread", QThread::TimeCriticalPriority);
    threadManager.newThread(imageProcessing, "ImageProcessingThread", QThread::TimeCriticalPriority);
    threadManager.newThread(networkStream, "NetworkStreamThread", QThread::TimeCriticalPriority);
    threadManager.newThread(journal, "JournalThread", QThread::NormalPriority);
139 140 141 142 143
    threadManager.newThread(trigger, "TriggerThread", QThread::TimeCriticalPriority);

    /*********************************************************************
     * GUI placement and start the main event loop
     ********************************************************************/
Thiago C. Santini's avatar
Thiago C. Santini committed
144 145 146 147 148 149 150 151 152 153 154

    QRect screenGeometry = QApplication::desktop()->screenGeometry();
    int x = (screenGeometry.width() - gui.width()) / 2;
    int y = (screenGeometry.height() - gui.height()) / 2;
    gui.move(x,y);
    gui.setWindowTitle(QString("EyeRec ").append(VERSION));
    gui.show();
    splash.finish(&gui);

    int ret = app.exec();

155 156 157 158
    /*********************************************************************
     * Exiting
     ********************************************************************/

Thiago C. Santini's avatar
Thiago C. Santini committed
159
    threadManager.finishThreads();
Thiago C. Santini's avatar
Thiago C. Santini committed
160

161 162
    exitBanner();

Thiago C. Santini's avatar
Thiago C. Santini committed
163 164
    return ret;
}