diff --git a/fmusim-gui/MainWindow.cpp b/fmusim-gui/MainWindow.cpp index 9686b730..76590340 100644 --- a/fmusim-gui/MainWindow.cpp +++ b/fmusim-gui/MainWindow.cpp @@ -39,29 +39,19 @@ MainWindow::MainWindow(QWidget *parent) simulationThread = new SimulationThread(this); - progressDialog = new QProgressDialog(this); - - progressDialog->setWindowTitle("FMUSim"); - progressDialog->setLabelText("Simulating..."); - progressDialog->setRange(0, 100); - progressDialog->setMinimumDuration(1000); - progressDialog->setWindowModality(Qt::WindowModal); - - Qt::WindowFlags flags = progressDialog->windowFlags(); - Qt::WindowFlags closeFlag = Qt::WindowCloseButtonHint; - flags = flags & (~closeFlag); - progressDialog->setWindowFlags(flags); - progressDialog->reset(); - - connect(simulationThread, &SimulationThread::progressChanged, progressDialog, &QProgressDialog::setValue); - connect(simulationThread, &SimulationThread::finished, progressDialog, &QProgressDialog::reset); + connect(simulationThread, &SimulationThread::plotChanged, this, &MainWindow::runPlotScript); connect(simulationThread, &SimulationThread::finished, this, &MainWindow::simulationFinished); - connect(progressDialog, &QProgressDialog::canceled, simulationThread, &SimulationThread::stop); + connect(this, &MainWindow::stopSimulationRequested, simulationThread, &SimulationThread::stop); + connect(this, &MainWindow::plotVariablesChanged, simulationThread, &SimulationThread::setPlotVariables); buildPlatformBinaryThread = new BuildPlatformBinaryThread(this); buildPlatformBinaryProgressDialog = new QProgressDialog(this); + Qt::WindowFlags flags = buildPlatformBinaryProgressDialog->windowFlags(); + Qt::WindowFlags closeFlag = Qt::WindowCloseButtonHint; + flags = flags & (~closeFlag); + buildPlatformBinaryProgressDialog->setWindowTitle("FMUSim"); buildPlatformBinaryProgressDialog->setLabelText("Building Platform Binary..."); buildPlatformBinaryProgressDialog->setRange(0, 0); @@ -536,6 +526,11 @@ void MainWindow::setColorScheme(Qt::ColorScheme colorScheme) { void MainWindow::simulate() { + if (simulationThread->isRunning()) { + emit stopSimulationRequested(); + return; + } + ui->logPlainTextEdit->clear(); double stopTime = stopTimeLineEdit->text().toDouble(); @@ -547,6 +542,7 @@ void MainWindow::simulate() { outputInterval = stopTime / ui->maxSamplesLineEdit->text().toDouble(); } + simulationThread->setPlotVariables(plotVariables); simulationThread->logFMICalls = ui->logFMICallsCheckBox->isChecked(); const QString logLevel = ui->logLevelComboBox->currentText(); @@ -624,6 +620,10 @@ void MainWindow::simulate() { simulationThread->inputFilename = ""; } + ui->simulateAction->setIcon(QIcon(":/buttons/dark/stop.svg")); + + setCurrentPage(ui->plotPage); + simulationThread->start(); } @@ -744,16 +744,34 @@ void MainWindow::unloadFMU() { interfaceTypeComboBox->setEnabled(false); } +void MainWindow::runPlotScript(QString javaScript) { + ui->plotWebEngineView->page()->runJavaScript(javaScript); +} + void MainWindow::addPlotVariable(const FMIModelVariable* variable) { + plotVariables.append(variable); + variablesListModel->setPlotVariables(&plotVariables); - updatePlot(); + + emit plotVariablesChanged(plotVariables); + + if (!simulationThread->isRunning()) { + updatePlot(); + } } void MainWindow::removePlotVariable(const FMIModelVariable* variable) { + plotVariables.removeAll(variable); + variablesListModel->setPlotVariables(&plotVariables); - updatePlot(); + + emit plotVariablesChanged(plotVariables); + + if (!simulationThread->isRunning()) { + updatePlot(); + } } void MainWindow::setOptionalColumnsVisible(bool visible) { @@ -776,6 +794,8 @@ void MainWindow::setOptionalColumnsVisible(bool visible) { void MainWindow::simulationFinished() { + ui->simulateAction->setIcon(QIcon(":/buttons/dark/play.svg")); + ui->logPlainTextEdit->setPlainText(simulationThread->messages.join('\n')); updatePlot(); diff --git a/fmusim-gui/MainWindow.h b/fmusim-gui/MainWindow.h index 0323aafe..3ec2742f 100644 --- a/fmusim-gui/MainWindow.h +++ b/fmusim-gui/MainWindow.h @@ -60,7 +60,6 @@ class MainWindow : public QMainWindow ModelVariablesTreeModel* modelVariablesTreeModel = nullptr; SimulationThread* simulationThread = nullptr; BuildPlatformBinaryThread* buildPlatformBinaryThread = nullptr; - QProgressDialog* progressDialog; QProgressDialog* buildPlatformBinaryProgressDialog; static MainWindow* currentMainWindow; @@ -70,6 +69,9 @@ class MainWindow : public QMainWindow void updatePlot(); void unloadFMU(); +public slots: + void runPlotScript(QString javaScript); + private slots: void openFile(); void selectInputFile(); @@ -83,5 +85,9 @@ private slots: void buildPlatformBinary(); void showModelVariablesListView(bool show); +signals: + void stopSimulationRequested(); + void plotVariablesChanged(QList plotVariables); + }; #endif // MAINWINDOW_H diff --git a/fmusim-gui/SimulationThread.cpp b/fmusim-gui/SimulationThread.cpp index b1aa1869..0442f76f 100644 --- a/fmusim-gui/SimulationThread.cpp +++ b/fmusim-gui/SimulationThread.cpp @@ -1,5 +1,6 @@ #include #include "SimulationThread.h" +#include "PlotUtil.h" SimulationThread* SimulationThread::currentSimulationThread = nullptr; @@ -60,7 +61,8 @@ void SimulationThread::run() { emit progressChanged(0); - const qint64 startTime = QDateTime::currentMSecsSinceEpoch(); + startTime = QDateTime::currentMSecsSinceEpoch(); + nextPlotTime = startTime; char platformBinaryPath[2048] = ""; @@ -106,14 +108,12 @@ void SimulationThread::run() { } } - FMIRecorder* initialRecorder = FMICreateRecorder(S, modelDescription->nModelVariables, (const FMIModelVariable**)modelDescription->modelVariables); + settings->initialRecorder = FMICreateRecorder(S, modelDescription->nModelVariables, (const FMIModelVariable**)modelDescription->modelVariables); - FMIRecorder* recorder = FMICreateRecorder(S, recordedVariables.size(), (const FMIModelVariable**)recordedVariables.data()); + settings->recorder = FMICreateRecorder(S, recordedVariables.size(), (const FMIModelVariable**)recordedVariables.data()); settings->S = S; settings->modelDescription = modelDescription; - settings->initialRecorder = initialRecorder; - settings->recorder = recorder; settings->input = input; status = FMISimulate(settings); @@ -127,6 +127,10 @@ void SimulationThread::stop() { continueSimulation = false; } +void SimulationThread::setPlotVariables(QList plotVariables) { + this->plotVariables = plotVariables; +} + bool SimulationThread::stepFinished(const FMISimulationSettings* settings, double time) { SimulationThread* simulationThread = static_cast(settings->userData); @@ -135,6 +139,14 @@ bool SimulationThread::stepFinished(const FMISimulationSettings* settings, doubl emit simulationThread->progressChanged(progress); + const qint64 currentTime = QDateTime::currentMSecsSinceEpoch(); + + if (currentTime >= simulationThread->nextPlotTime) { + const QString plot = PlotUtil::createPlot(settings->initialRecorder, settings->recorder, simulationThread->plotVariables, Qt::ColorScheme::Dark); + emit simulationThread->plotChanged(plot); + simulationThread->nextPlotTime = currentTime + simulationThread->plotInterval; + } + return simulationThread->continueSimulation; } diff --git a/fmusim-gui/SimulationThread.h b/fmusim-gui/SimulationThread.h index d704e5b2..07d95bdf 100644 --- a/fmusim-gui/SimulationThread.h +++ b/fmusim-gui/SimulationThread.h @@ -13,6 +13,7 @@ class SimulationThread : public QThread Q_OBJECT public: + qint64 plotInterval = 1000; FMIStatus logLevel = FMIOK; bool logFMICalls = false; FMIInterfaceType interfaceType; @@ -30,8 +31,12 @@ class SimulationThread : public QThread public slots: void stop(); + void setPlotVariables(QList plotVariables); private: + qint64 startTime; + qint64 nextPlotTime; + QList plotVariables; static SimulationThread* currentSimulationThread; static void appendMessage(const char* message, va_list args); static bool stepFinished(const FMISimulationSettings* settings, double time); @@ -39,6 +44,7 @@ public slots: signals: void progressChanged(int progress); + void plotChanged(QString); }; diff --git a/fmusim-gui/resources/buttons/buttons.afdesign b/fmusim-gui/resources/buttons/buttons.afdesign index 40c7c744..39c979fc 100644 Binary files a/fmusim-gui/resources/buttons/buttons.afdesign and b/fmusim-gui/resources/buttons/buttons.afdesign differ diff --git a/fmusim-gui/resources/buttons/dark/stop.svg b/fmusim-gui/resources/buttons/dark/stop.svg index c4b42cdc..31e5e971 100644 --- a/fmusim-gui/resources/buttons/dark/stop.svg +++ b/fmusim-gui/resources/buttons/dark/stop.svg @@ -1,10 +1,10 @@ - + - + diff --git a/fmusim-gui/resources/buttons/light/stop.svg b/fmusim-gui/resources/buttons/light/stop.svg index eacd0985..31e5e971 100644 --- a/fmusim-gui/resources/buttons/light/stop.svg +++ b/fmusim-gui/resources/buttons/light/stop.svg @@ -1,10 +1,10 @@ - + - +