1
0
Fork 0
mirror of https://github.com/EdgeTX/edgetx.git synced 2025-07-25 17:25:10 +03:00

{Companion] Unload simulator libraries after each use -- reset all statically initialized firmware variables. (#4655)

* [simulatormainwindow] Move sub-window destructors to main destructor.

* [simulation] Move SimulatorInterface creation/ownership to SimulatorMainWindow.

* [simulation] Add option to unload simulator libraries after each use (eg. from Companion) so as to properly reset all statically initialized firmware variables; Introduce new SimulatorLoader class.
This commit is contained in:
Max Paperno 2017-03-21 14:48:25 -04:00 committed by Bertrand Songis
parent dc89d2d630
commit e48b1fd07d
13 changed files with 268 additions and 167 deletions

View file

@ -105,7 +105,7 @@ int main(int argc, char *argv[])
registerStorageFactories();
registerOpenTxFirmwares();
registerSimulators();
SimulatorLoader::registerSimulators();
if (g.profile[g.id()].fwType().isEmpty()){
g.profile[g.id()].fwType(default_firmware_variant->getId());
@ -135,7 +135,7 @@ int main(int argc, char *argv[])
delete splash;
delete mainWin;
unregisterSimulators();
SimulatorLoader::unregisterSimulators();
unregisterOpenTxFirmwares();
unregisterStorageFactories();

View file

@ -22,15 +22,19 @@
Q_LOGGING_CATEGORY(eepromImport, "eeprom.import")
Q_LOGGING_CATEGORY(simulatorInterfaceLoader, "simulator.interface.loader")
void CustomDebug::setFilterRules()
{
QString rules;
rules.append("eeprom.import=");
#if defined(DEBUG_STORAGE_IMPORT)
rules.append("true");
rules.append("true\n");
#else
rules.append("false");
rules.append("false\n");
#endif
rules.append("simulator.interface.*=true\n");
QLoggingCategory::setFilterRules(rules);
}

View file

@ -24,7 +24,10 @@
#include <QLoggingCategory>
// Controls the generation of debug output for EEPROM import
Q_DECLARE_LOGGING_CATEGORY(eepromImport)
Q_DECLARE_LOGGING_CATEGORY(eepromImport) // "eeprom.import"
// Controls the generation of debug output of SimulatorLoader class
Q_DECLARE_LOGGING_CATEGORY(simulatorInterfaceLoader) // "simulator.interface.loader"
class CustomDebug
{

View file

@ -1837,16 +1837,6 @@ void Firmware::addOptions(Option options[])
this->opts.push_back(opts);
}
SimulatorInterface * getCurrentSimulator()
{
QString firmwareId = getCurrentFirmware()->getId();
SimulatorFactory * factory = getSimulatorFactory(firmwareId);
if (factory)
return factory->create();
else
return NULL;
}
void FlightModeData::clear(const int phase)
{
memset(this, 0, sizeof(FlightModeData));

View file

@ -21,6 +21,7 @@
#ifndef _EEPROMINTERFACE_H_
#define _EEPROMINTERFACE_H_
#include "macros.h"
#include "radiodata.h"
#include "../../radio/src/definitions.h"
#include "simulatorinterface.h"
@ -195,14 +196,8 @@ inline int applyStickMode(int stick, unsigned int mode)
return stick;
}
const unsigned int stickModes[]= {
1, 2, 3, 4,
1, 3, 2, 4,
4, 2, 3, 1,
4, 3, 2, 1 };
if (stick >= 1 && stick <= 4)
return stickModes[(mode-1)*4 + stick - 1];
return modn12x3[mode-1][stick-1];
else
return stick;
}
@ -358,8 +353,6 @@ inline Firmware * getCurrentFirmware()
return current_firmware_variant;
}
SimulatorInterface * getCurrentSimulator();
inline EEPROMInterface * getCurrentEEpromInterface()
{
return getCurrentFirmware()->getEEpromInterface();
@ -375,7 +368,7 @@ inline int divRoundClosest(const int n, const int d)
return ((n < 0) ^ (d < 0)) ? ((n - d/2)/d) : ((n + d/2)/d);
}
#define CHECK_IN_ARRAY(T, index) ((unsigned int)index < (unsigned int)(sizeof(T)/sizeof(T[0])) ? T[(unsigned int)index] : "???")
#define CHECK_IN_ARRAY(T, index) ((unsigned int)index < DIM(T) ? T[(unsigned int)index] : "???")
extern QList<EEPROMInterface *> eepromInterfaces;

View file

@ -25,9 +25,6 @@
#elif defined __GNUC__
#include <unistd.h>
#endif
#if defined(WIN32) && defined(WIN_USE_CONSOLE_STDIO)
#include "windows.h"
#endif
#include "appdata.h"
#include "helpers.h"
@ -811,39 +808,45 @@ CompanionIcon::CompanionIcon(const QString &baseimage)
void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx)
{
SimulatorInterface * simulator = getCurrentSimulator();
if (simulator) {
RadioData * simuData = new RadioData(radioData);
unsigned int flags = 0;
QString fwId = SimulatorLoader::findSimulatorByFirmwareName(getCurrentFirmware()->getId());
if (fwId.isEmpty()) {
QMessageBox::warning(NULL,
QObject::tr("Warning"),
QObject::tr("Simulator for this firmware is not yet available"));
return;
}
if (modelIdx >= 0) {
flags |= SIMULATOR_FLAGS_NOTX;
simuData->setCurrentModel(modelIdx);
}
RadioData * simuData = new RadioData(radioData);
unsigned int flags = 0;
SimulatorMainWindow * dialog = new SimulatorMainWindow(parent, simulator, flags);
if (!dialog->setRadioData(simuData)) {
QMessageBox::critical(NULL, QObject::tr("Data Load Error"), QObject::tr("Error occurred while starting simulator."));
delete dialog;
delete simuData;
return;
}
if (modelIdx >= 0) {
flags |= SIMULATOR_FLAGS_NOTX;
simuData->setCurrentModel(modelIdx);
}
dialog->setWindowModality(Qt::ApplicationModal);
dialog->setAttribute(Qt::WA_DeleteOnClose);
SimulatorMainWindow * dialog = new SimulatorMainWindow(parent, fwId, flags);
dialog->setWindowModality(Qt::ApplicationModal);
dialog->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(dialog, &SimulatorMainWindow::destroyed, [simuData] (void) {
// TODO simuData and Horus tmp directory is deleted on simulator close OR we could use it to get back data from the simulation
delete simuData;
});
QString resultMsg;
if (dialog->getExitStatus(&resultMsg)) {
if (resultMsg.isEmpty())
resultMsg = QObject::tr("Uknown error during Simulator startup.");
QMessageBox::critical(NULL, QObject::tr("Simulator Error"), resultMsg);
dialog->deleteLater();
}
else if (dialog->setRadioData(simuData)) {
dialog->start();
QObject::connect(dialog, &SimulatorMainWindow::destroyed, [simuData] (void) {
// TODO simuData and Horus tmp directory is deleted on simulator close OR we could use it to get back data from the simulation
delete simuData;
});
dialog->show();
}
else {
QMessageBox::warning(NULL,
QObject::tr("Warning"),
QObject::tr("Simulator for this firmware is not yet available"));
QMessageBox::critical(NULL, QObject::tr("Data Load Error"), QObject::tr("Error occurred while starting simulator."));
dialog->deleteLater();
}
}

View file

@ -19,38 +19,29 @@
*/
#include "simulatorinterface.h"
#include <QDebug>
#include <QDir>
#include <QLibrary>
#include <QLibraryInfo>
#include <QMap>
#include <QMessageBox>
#include "customdebug.h"
#include "version.h"
#include <QDebug>
#include <QLibraryInfo>
#if defined _MSC_VER || !defined __GNUC__
#include <windows.h>
#endif
QMap<QString, SimulatorFactory *> registered_simulators;
#ifndef SIMULATOR_INTERFACE_LOADER_METHOD
#define SIMULATOR_INTERFACE_LOADER_DYNAMIC 1 // How to load simulator libraries: 1=dynamic load and unload; 0=load once (old way)
#endif
void registerSimulator(const QString & filename)
QMap<QString, QLibrary *> SimulatorLoader::registeredSimulators;
QStringList SimulatorLoader::getAvailableSimulators()
{
QLibrary lib(filename);
typedef SimulatorFactory * (*RegisterSimulator)();
qDebug() << "trying to register simulator in " << filename;
RegisterSimulator registerFunc = (RegisterSimulator)lib.resolve("registerSimu");
if (registerFunc) {
SimulatorFactory * factory = registerFunc();
registered_simulators[factory->name()] = factory;
qDebug() << "Registered" << factory->name() << "simulator";
}
else {
qWarning() << "Library error" << filename << lib.errorString();
}
return registeredSimulators.keys();
}
int registerSimulators(const QDir & dir)
int SimulatorLoader::registerSimulators(const QDir & dir)
{
int noSimulatorsFound = 0;
QStringList filters;
#if defined(__APPLE__)
filters << "*-simulator.dylib";
@ -59,17 +50,41 @@ int registerSimulators(const QDir & dir)
#else
filters << "*-simulator.so";
#endif
registeredSimulators.clear();
qCDebug(simulatorInterfaceLoader) << "Searching for simulators in" << dir.path() << "matching pattern" << filters;
qDebug() << "Searching for simulators in" << dir.path();
foreach(QString filename, dir.entryList(filters, QDir::Files)) {
QString libraryFilename = dir.path() + "/" + filename;
registerSimulator(libraryFilename);
noSimulatorsFound++;
QLibrary * lib = new QLibrary( dir.path() + "/" + filename);
qCDebug(simulatorInterfaceLoader) << "Trying to register simulator in " << filename;
SimulatorFactory * factory;
RegisterSimulator registerFunc = (RegisterSimulator)lib->resolve("registerSimu");
if (registerFunc && (factory = registerFunc())) {
if (getAvailableSimulators().contains(factory->name()))
continue;
lib->setProperty("instances_used", 0);
registeredSimulators.insert(factory->name(), lib);
delete factory;
#if SIMULATOR_INTERFACE_LOADER_DYNAMIC
lib->unload();
#endif
qCDebug(simulatorInterfaceLoader) << "Registered" << registeredSimulators.lastKey() << "simulator in " << lib->fileName() << "and unloaded:" << !lib->isLoaded();
}
else {
qWarning() << "Library error" << lib->fileName() << lib->errorString();
delete lib;
}
}
return noSimulatorsFound;
qCDebug(simulatorInterfaceLoader) << "Found libraries:" << (registeredSimulators.size() ? registeredSimulators.keys() : QStringList() << "none");
return registeredSimulators.size();
}
void registerSimulators()
void SimulatorLoader::registerSimulators()
{
QDir dir(".");
if (registerSimulators(dir)) {
@ -90,31 +105,93 @@ void registerSimulators()
registerSimulators(dir);
}
SimulatorFactory * getSimulatorFactory(const QString & name)
void SimulatorLoader::unregisterSimulators()
{
foreach(QLibrary * lib, registeredSimulators)
delete lib;
}
QString SimulatorLoader::findSimulatorByFirmwareName(const QString & name)
{
int pos;
QString ret;
QString simuName = name;
while(1) {
qDebug() << "searching" << simuName << "simulator";
foreach (QString name, registered_simulators.keys()) {
if (name.contains(simuName)) {
simuName = name;
qDebug() << "found" << simuName;
return registered_simulators[simuName];
}
qCDebug(simulatorInterfaceLoader) << "searching" << simuName << "simulator";
if (registeredSimulators.contains(simuName)) {
ret = simuName;
break;
}
int pos = simuName.lastIndexOf('-');
if (pos <= 0)
if ((pos = simuName.lastIndexOf('-')) <= 0)
break;
simuName = simuName.mid(0, pos);
if (simuName.count('-') == 0)
break;
}
return NULL;
return ret;
}
void unregisterSimulators()
SimulatorInterface * SimulatorLoader::loadSimulator(const QString & name)
{
foreach(SimulatorFactory *factory, registered_simulators) {
SimulatorInterface * si = NULL;
QString libname = findSimulatorByFirmwareName(name);
if (libname.isEmpty()) {
qWarning() << "Simulator" << name << "not found.";
return si;
}
QLibrary * lib = registeredSimulators.value(libname, NULL);
if (!lib) {
qWarning() << "Simulator library is NULL";
return si;
}
qCDebug(simulatorInterfaceLoader) << "Trying to load simulator in " << lib->fileName();
SimulatorFactory * factory;
RegisterSimulator registerFunc = (RegisterSimulator)lib->resolve("registerSimu");
if (registerFunc && (factory = registerFunc()) && (si = factory->create())) {
quint8 instance = lib->property("instances_used").toUInt();
lib->setProperty("instances_used", ++instance);
qCDebug(simulatorInterfaceLoader) << "Loaded" << factory->name() << "simulator instance" << instance;
delete factory;
}
else {
qWarning() << "Library error" << lib->fileName() << lib->errorString();
}
return si;
}
bool SimulatorLoader::unloadSimulator(const QString & name)
{
bool ret = false;
#if SIMULATOR_INTERFACE_LOADER_DYNAMIC
QString simuName = findSimulatorByFirmwareName(name);
if (simuName.isEmpty())
return ret;
QLibrary * lib = registeredSimulators.value(simuName, NULL);
if (lib && lib->isLoaded()) {
quint8 instance = lib->property("instances_used").toUInt();
lib->setProperty("instances_used", --instance);
if (!instance) {
ret = lib->unload();
qCDebug(simulatorInterfaceLoader) << "Unloading" << simuName << "(" << lib->fileName() << ")" << "result:" << ret;
}
else {
ret = true;
qCDebug(simulatorInterfaceLoader) << "Simulator" << simuName << "instances remaining:" << instance;
}
}
else {
qCDebug(simulatorInterfaceLoader) << "Simulator library for " << simuName << "already unloaded.";
}
#else
qCDebug(simulatorInterfaceLoader) << "Keeping simulator library" << simuName << "loaded.";
#endif
return ret;
}

View file

@ -23,11 +23,16 @@
#include "boards.h"
#include "constants.h"
#include <algorithm>
#include <inttypes.h>
#include <QObject>
#include <QString>
#include <QByteArray>
#include <QDir>
#include <QLibrary>
#include <QMap>
#include <algorithm>
struct TxInputs
{
@ -122,9 +127,21 @@ class SimulatorFactory {
virtual SimulatorInterface *create() = 0;
};
void registerSimulators();
void unregisterSimulators();
SimulatorFactory *getSimulatorFactory(const QString &name);
extern QMap<QString, SimulatorFactory *> registered_simulators;
class SimulatorLoader
{
public:
static void registerSimulators();
static void unregisterSimulators();
static QStringList getAvailableSimulators();
static QString findSimulatorByFirmwareName(const QString & name);
static SimulatorInterface * loadSimulator(const QString & name);
static bool unloadSimulator(const QString & name);
protected:
typedef SimulatorFactory * (*RegisterSimulator)();
static int registerSimulators(const QDir & dir);
static QMap<QString, QLibrary *> registeredSimulators;
};
#endif // _SIMULATORINTERFACE_H_

View file

@ -40,9 +40,8 @@ extern AppData g; // ensure what "g" means
const quint16 SimulatorMainWindow::m_savedUiStateVersion = 2;
SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, SimulatorInterface * simulator, quint8 flags, Qt::WindowFlags wflags) :
SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, const QString & firmwareId, quint8 flags, Qt::WindowFlags wflags) :
QMainWindow(parent, wflags),
m_simulator(simulator),
ui(new Ui::SimulatorMainWindow),
m_simulatorWidget(NULL),
m_consoleWidget(NULL),
@ -52,12 +51,24 @@ SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, SimulatorInterface * s
m_telemetryDockWidget(NULL),
m_trainerDockWidget(NULL),
m_outputsDockWidget(NULL),
m_simulatorId(firmwareId),
m_exitStatusCode(0),
m_radioProfileId(g.sessionId()),
m_radioSizeConstraint(Qt::Horizontal | Qt::Vertical),
m_firstShow(true),
m_showRadioDocked(true),
m_showMenubar(true)
{
if (m_simulatorId.isEmpty()) {
m_simulatorId = SimulatorLoader::findSimulatorByFirmwareName(getCurrentFirmware()->getId());
}
m_simulator = SimulatorLoader::loadSimulator(m_simulatorId);
if (!m_simulator) {
m_exitStatusMsg = tr("ERROR: Failed to create simulator interface, possibly missing or bad library.");
m_exitStatusCode = -1;
return;
}
ui->setupUi(this);
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
@ -128,25 +139,30 @@ SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, SimulatorInterface * s
SimulatorMainWindow::~SimulatorMainWindow()
{
delete ui;
}
void SimulatorMainWindow::closeEvent(QCloseEvent *)
{
saveUiState();
if (m_telemetryDockWidget)
delete m_telemetryDockWidget;
if (m_trainerDockWidget)
delete m_trainerDockWidget;
if (m_outputsDockWidget)
delete m_outputsDockWidget;
if (m_consoleDockWidget)
delete m_consoleDockWidget;
if (m_simulatorDockWidget)
delete m_simulatorDockWidget;
else if (m_simulatorWidget)
delete m_simulatorWidget;
if (m_consoleDockWidget)
delete m_consoleDockWidget;
delete ui;
if (m_simulator)
delete m_simulator;
SimulatorLoader::unloadSimulator(m_simulatorId);
}
void SimulatorMainWindow::closeEvent(QCloseEvent *)
{
saveUiState();
}
void SimulatorMainWindow::show()
@ -173,7 +189,8 @@ void SimulatorMainWindow::changeEvent(QEvent *e)
}
}
QMenu * SimulatorMainWindow::createPopupMenu(){
QMenu * SimulatorMainWindow::createPopupMenu()
{
QMenu * menu = QMainWindow::createPopupMenu();
menu->clear();
menu->addActions(ui->menuView->actions());
@ -214,6 +231,13 @@ void SimulatorMainWindow::restoreUiState()
restoreState(windowState, m_savedUiStateVersion);
}
int SimulatorMainWindow::getExitStatus(QString * msg)
{
if (msg)
*msg = m_exitStatusMsg;
return m_exitStatusCode;
}
bool SimulatorMainWindow::setRadioData(RadioData * radioData)
{
return m_simulatorWidget->setRadioData(radioData);

View file

@ -25,7 +25,6 @@
#include <QDockWidget>
#include <QMainWindow>
#include <QPointer>
class DebugOutput;
class RadioData;
@ -48,13 +47,14 @@ class SimulatorMainWindow : public QMainWindow
Q_OBJECT
public:
explicit SimulatorMainWindow(QWidget * parent, SimulatorInterface * simulator, quint8 flags=0, Qt::WindowFlags wflags = Qt::WindowFlags());
explicit SimulatorMainWindow(QWidget * parent, const QString & firmwareId = "", quint8 flags=0, Qt::WindowFlags wflags = Qt::WindowFlags());
~SimulatorMainWindow();
int getExitStatus(QString * msg = Q_NULLPTR);
bool setRadioData(RadioData * radioData);
bool useTempDataPath(bool deleteOnClose = true);
bool setOptions(SimulatorOptions & options, bool withSave = true);
QMenu * createPopupMenu();
virtual QMenu * createPopupMenu();
public slots:
virtual void show();
@ -95,6 +95,9 @@ class SimulatorMainWindow : public QMainWindow
QDockWidget * m_outputsDockWidget;
QVector<keymapHelp_t> m_keymapHelp;
QString m_simulatorId;
QString m_exitStatusMsg;
int m_exitStatusCode;
int m_radioProfileId;
int m_radioSizeConstraint;
bool m_firstShow;

View file

@ -23,13 +23,14 @@
#include "appdata.h"
#include "constants.h"
#include "eeprominterface.h"
#include "simulatorinterface.h"
#include "helpers.h"
#include <QFileDialog>
using namespace Simulator;
extern AppData g;
extern QMap<QString, SimulatorFactory *> registered_simulators;
SimulatorStartupDialog::SimulatorStartupDialog(SimulatorOptions * options, int * profId, QWidget *parent) :
QDialog(parent),
@ -45,7 +46,7 @@ SimulatorStartupDialog::SimulatorStartupDialog(SimulatorOptions * options, int *
ui->radioProfile->addItem(pi.value(), pi.key());
}
ui->radioType->addItems(registered_simulators.keys());
ui->radioType->addItems(SimulatorLoader::getAvailableSimulators());
ui->optGrp_dataSource->setId(ui->optFile, SimulatorOptions::START_WITH_FILE);
ui->optGrp_dataSource->setId(ui->optFolder, SimulatorOptions::START_WITH_FOLDER);
@ -151,7 +152,7 @@ void SimulatorStartupDialog::updateContainerTypes(void)
void SimulatorStartupDialog::loadRadioProfile(int id)
{
QString tmpstr;
QString tmpstr, tmpstr2;
int i;
if (id < 0 || !g.getActiveProfiles().contains(id))
@ -166,8 +167,8 @@ void SimulatorStartupDialog::loadRadioProfile(int id)
tmpstr = m_options->firmwareId;
if (tmpstr.isEmpty() && !g.profile[id].fwType().isEmpty())
tmpstr = g.profile[id].fwType();
else if (getSimulatorFactory(tmpstr))
tmpstr = getSimulatorFactory(tmpstr)->name();
else if (!(tmpstr2 = SimulatorLoader::findSimulatorByFirmwareName(m_options->firmwareId)).isEmpty())
tmpstr = tmpstr2;
i = ui->radioType->findText(findRadioId(tmpstr), Qt::MatchContains);
if (i > -1)
ui->radioType->setCurrentIndex(i);

View file

@ -28,8 +28,6 @@ namespace Ui {
class SimulatorStartupDialog;
}
using namespace Simulator;
class SimulatorStartupDialog : public QDialog
{
Q_OBJECT

View file

@ -19,13 +19,13 @@
*/
#include <QApplication>
#include <QTranslator>
#include <QDir>
#include <QLibraryInfo>
#include <QLocale>
#include <QString>
#include <QDir>
#include <QTextStream>
#include <QMessageBox>
#include <QString>
#include <QTextStream>
#include <QTranslator>
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
#include <SDL.h>
#undef main
@ -66,20 +66,11 @@ void sharedHelpText(QTextStream &stream)
}
// list all available radios
stream << endl << QObject::tr("Available radios:") << endl;
foreach(QString name, registered_simulators.keys()) {
foreach(QString name, SimulatorLoader::getAvailableSimulators()) {
stream << "\t" << name << endl;
}
}
QString findFirmwareId(int profileId)
{
SimulatorFactory * sf = getSimulatorFactory(g.profile[profileId].fwType());
if (sf)
return sf->name();
else
return QString();
}
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(companion);
@ -100,6 +91,8 @@ int main(int argc, char *argv[])
g.init();
QString resultMsg;
QTranslator companionTranslator;
companionTranslator.load(":/companion_" + g.locale());
QTranslator qtTranslator;
@ -127,9 +120,9 @@ int main(int argc, char *argv[])
registerStorageFactories();
registerOpenTxFirmwares();
registerSimulators();
SimulatorLoader::registerSimulators();
if (!registered_simulators.size()) {
if (!SimulatorLoader::getAvailableSimulators().size()) {
showMessage(QObject::tr("ERROR: No simulator libraries available."), QMessageBox::Critical);
return finish(3);
}
@ -142,20 +135,19 @@ int main(int argc, char *argv[])
cliOptions.alias("help", "h");
cliOptions.parse(QCoreApplication::arguments());
if (cliOptions.count("help") || cliOptions.showUnrecognizedWarning()) {
QString msg;
QTextStream stream(&msg);
QTextStream stream(&resultMsg);
stream << QObject::tr("Usage: simulator [OPTION]... [EEPROM.BIN FILE OR DATA FOLDER] ") << endl << endl;
stream << QObject::tr("Options:") << endl;
cliOptions.showUsage(false, stream);
sharedHelpText(stream);
// display
showMessage(msg, QMessageBox::Information);
showMessage(resultMsg, QMessageBox::Information);
return finish(1);
}
// TODO : defaults should be set in Profile::init()
if (simOptions.firmwareId.isEmpty())
simOptions.firmwareId = findFirmwareId(profileId);
simOptions.firmwareId = SimulatorLoader::findSimulatorByFirmwareName(g.profile[profileId].fwType());
if (simOptions.dataFolder.isEmpty())
simOptions.dataFolder = g.eepromDir();
if (simOptions.sdPath.isEmpty())
@ -209,28 +201,16 @@ int main(int argc, char *argv[])
qDebug() << "profileId=" << profileId << simOptions;
if (profileId < 0 || simOptions.firmwareId.isEmpty() || (simOptions.dataFile.isEmpty() && simOptions.dataFolder.isEmpty())) {
showMessage(QObject::tr("ERROR: Couldn't start simulator, missing radio/profile/data file/folder.\n Profile ID: [%1]; Radio ID: [%2];\nData File: [%3]")
.arg(profileId).arg(simOptions.firmwareId, simOptions.dataFile), QMessageBox::Critical);
resultMsg = QObject::tr("ERROR: Couldn't start simulator, missing radio/profile/data file/folder.\n Profile ID: [%1]; Radio ID: [%2];\nData File: [%3]");
showMessage(resultMsg.arg(profileId).arg(simOptions.firmwareId, simOptions.dataFile), QMessageBox::Critical);
return finish(1);
}
if (!g.getActiveProfiles().contains(profileId) || !registered_simulators.keys().contains(simOptions.firmwareId)) {
QString msg;
QTextStream stream(&msg);
if (!g.getActiveProfiles().contains(profileId) || !SimulatorLoader::getAvailableSimulators().contains(simOptions.firmwareId)) {
QTextStream stream(&resultMsg);
stream << QObject::tr("ERROR: Radio profile or simulator firmware not found.\nProfile ID: [%1]; Radio ID: [%2]")
.arg(profileId).arg(simOptions.firmwareId);
sharedHelpText(stream);
showMessage(msg, QMessageBox::Critical);
return finish(2);
}
SimulatorFactory * factory = getSimulatorFactory(simOptions.firmwareId);
if (!factory) {
showMessage(QObject::tr("ERROR: Simulator %1 not found").arg(simOptions.firmwareId), QMessageBox::Critical);
return finish(2);
}
SimulatorInterface * simulator = factory->create();
if (!simulator) {
showMessage(QObject::tr("ERROR: Failed to create simulator interface, possibly missing or bad library."), QMessageBox::Critical);
showMessage(resultMsg, QMessageBox::Critical);
return finish(2);
}
@ -239,26 +219,33 @@ int main(int argc, char *argv[])
g.sessionId(profileId);
g.simuLastProfId(profileId);
int result = 1;
SimulatorMainWindow * mainWindow = new SimulatorMainWindow(NULL, simulator, SIMULATOR_FLAGS_STANDALONE);
if (mainWindow->setOptions(simOptions, true)) {
int result = 0;
SimulatorMainWindow * mainWindow = new SimulatorMainWindow(NULL, simOptions.firmwareId, SIMULATOR_FLAGS_STANDALONE);
if ((result = mainWindow->getExitStatus(&resultMsg))) {
if (resultMsg.isEmpty())
resultMsg = QObject::tr("Uknown error during Simulator startup.");
showMessage(resultMsg, QMessageBox::Critical);
}
else if (mainWindow->setOptions(simOptions, true)) {
mainWindow->start();
mainWindow->show();
result = app.exec();
if (!result) {
if ((result = mainWindow->getExitStatus(&resultMsg)) && !resultMsg.isEmpty())
qWarning() << "Exit message from SimulatorMainWindow:" << resultMsg;
}
}
else {
result = 3;
}
delete mainWindow;
delete simulator;
delete mainWindow;
return finish(result);
}
int finish(int exitCode)
{
qDebug() << "SIMULATOR EXIT" << exitCode;
unregisterSimulators();
SimulatorLoader::unregisterSimulators();
unregisterOpenTxFirmwares();
unregisterStorageFactories();
@ -266,5 +253,6 @@ int finish(int exitCode)
SDL_Quit();
#endif
qDebug() << "SIMULATOR EXIT" << exitCode;
return exitCode;
}