add and delete on simulation thread

main
Benjamin Kraft 1 year ago
parent 719c710618
commit d1ec81eb09
  1. 9
      src/MainWindow.cpp
  2. 5
      src/MainWindow.h
  3. 18
      src/Simulation.cpp
  4. 12
      src/Simulation.h

@ -12,7 +12,6 @@
#include <QDial> #include <QDial>
#include <QColorDialog> #include <QColorDialog>
#include <QCoreApplication> #include <QCoreApplication>
#include "Pendulum.h"
#include "Button.h" #include "Button.h"
#include <QThread> #include <QThread>
#include <QCloseEvent> #include <QCloseEvent>
@ -297,6 +296,7 @@ QWidget * MainWindow::buildAddUI() {
removeBtn->setStyleSheet("background-color: #ffaaaa"); removeBtn->setStyleSheet("background-color: #ffaaaa");
connect(addBtn, &QPushButton::clicked, this, &MainWindow::add); connect(addBtn, &QPushButton::clicked, this, &MainWindow::add);
connect(this, &MainWindow::pendulaCreated, simulation, &Simulation::addPendula);
connect(removeBtn, &QPushButton::clicked, simulation, &Simulation::clearPendula); connect(removeBtn, &QPushButton::clicked, simulation, &Simulation::clearPendula);
btnLyt->addWidget(addBtn); btnLyt->addWidget(addBtn);
@ -393,8 +393,8 @@ void MainWindow::normalizeLengths() {
} }
void MainWindow::add() { void MainWindow::add() {
std::vector<Pendulum *> addPendula;
if (multiple){ if (multiple){
for (int i = 0; i < count; i++){ for (int i = 0; i < count; i++){
auto M = std::vector(masses.begin(), masses.begin() + segments); auto M = std::vector(masses.begin(), masses.begin() + segments);
auto L = std::vector(lengths.begin(), lengths.begin() + segments); auto L = std::vector(lengths.begin(), lengths.begin() + segments);
@ -417,13 +417,14 @@ void MainWindow::add() {
auto hue = float(progress + 0.5); auto hue = float(progress + 0.5);
c = QColor::fromHsvF(hue, 1, 1); c = QColor::fromHsvF(hue, 1, 1);
} }
simulation->pendula.push_back(new Pendulum(M, L, c, angle)); addPendula.push_back(new Pendulum(M, L, c, angle));
} }
} else { } else {
auto M = std::vector(masses.begin(), masses.begin() + segments); auto M = std::vector(masses.begin(), masses.begin() + segments);
auto L = std::vector(lengths.begin(), lengths.begin() + segments); auto L = std::vector(lengths.begin(), lengths.begin() + segments);
simulation->pendula.push_back(new Pendulum(M, L, color, startingAngle)); addPendula.push_back(new Pendulum(M, L, color, startingAngle));
} }
emit pendulaCreated(addPendula);
} }
void MainWindow::resetSimulationControl() { void MainWindow::resetSimulationControl() {

@ -1,6 +1,7 @@
#include <QWidget> #include <QWidget>
#include <vector> #include <vector>
#include "Slider.h" #include "Slider.h"
#include "Pendulum.h"
class Simulation; class Simulation;
class QGridLayout; class QGridLayout;
@ -9,6 +10,7 @@ class GLWidget;
enum Property {Angle, Mass, Length}; enum Property {Angle, Mass, Length};
class MainWindow : public QWidget { class MainWindow : public QWidget {
Q_OBJECT
public: public:
explicit MainWindow(); explicit MainWindow();
protected: protected:
@ -39,7 +41,8 @@ private:
Slider<double> * gravitySlider = nullptr, * timescaleSlider = nullptr; Slider<double> * gravitySlider = nullptr, * timescaleSlider = nullptr;
Slider<> * substepsSlider = nullptr; Slider<> * substepsSlider = nullptr;
signals:
void pendulaCreated(const std::vector<Pendulum*> &add);
public slots: public slots:
void resetMasses(); void resetMasses();
void resetLengths(); void resetLengths();

@ -14,7 +14,7 @@ Simulation::Simulation() {
lastUpdate = high_resolution_clock::now(); lastUpdate = high_resolution_clock::now();
}; };
void Simulation::draw(QPainter *p, int screenSize) const { void Simulation::draw(QPainter *p, int screenSize) {
double scale = screenSize * 0.95 / size; double scale = screenSize * 0.95 / size;
for (const auto pendulum : pendula) for (const auto pendulum : pendula)
@ -35,14 +35,22 @@ void Simulation::update() {
h /= substeps; h /= substeps;
#pragma omp parallel for #pragma omp parallel for
for (const auto pendulum : pendula) for (const auto & pendulum : pendula)
for (int i = 0; i < substeps; i++) for (int k = 0; k < substeps; k++)
pendulum->update(h, gravity); pendulum->update(h, gravity);
} }
void Simulation::clearPendula() { void Simulation::clearPendula() {
for (auto p : pendula) auto deleteLater = pendula;
delete p;
pendula.clear(); pendula.clear();
pendula.shrink_to_fit();
QThread::usleep(500000);
for (auto p : deleteLater)
delete p;
}
void Simulation::addPendula(const std::vector<Pendulum *> &add) {
for (auto p : add)
pendula.push_back(p);
} }

@ -19,19 +19,17 @@ public:
double timescale {}; double timescale {};
int substeps {}; int substeps {};
int updateInterval = 17;
bool isPlaying = false; bool isPlaying = false;
std::vector<Pendulum *> pendula; void draw(QPainter*, int);
QTimer * timer;
void draw(QPainter*, int) const;
public slots: public slots:
void clearPendula(); void clearPendula();
void addPendula(const std::vector<Pendulum *> &add);
private slots: private slots:
void update(); void update();
private: private:
QTimer * timer;
int updateInterval = 17;
std::vector<Pendulum *> pendula;
time_point<system_clock> lastUpdate; time_point<system_clock> lastUpdate;
}; };
Loading…
Cancel
Save