{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:
committed by
Bertrand Songis
parent
dc89d2d630
commit
e48b1fd07d
+32
-44
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user