From c7d501e24853106dcdba99c17eead2200f74bd74 Mon Sep 17 00:00:00 2001 From: Feeeeddmmmeee Date: Sat, 21 May 2022 14:45:04 +0200 Subject: [PATCH] async velocity updates + fixed dangling references in the vector class --- GravitySim/src/Game.cpp | 20 ++++++++++----- GravitySim/src/Planet.cpp | 25 +++++++++++++----- GravitySim/src/Planet.h | 9 ++++--- GravitySim/src/Universe.cpp | 51 ++++++++++++++++++++++++++++++++++--- GravitySim/src/Universe.h | 9 ++++++- GravitySim/src/Vector.cpp | 8 +++--- GravitySim/src/Vector.h | 8 +++--- GravitySim/src/main.cpp | 5 ++++ 8 files changed, 107 insertions(+), 28 deletions(-) diff --git a/GravitySim/src/Game.cpp b/GravitySim/src/Game.cpp index 53b1c99..eaa00ce 100644 --- a/GravitySim/src/Game.cpp +++ b/GravitySim/src/Game.cpp @@ -60,9 +60,9 @@ Game::Game(const char* title, int xpos, int ypos, int width, int height, bool fu }//*/ // Orbiting planets - /*this->universe.addPlanet(new Planet(100000, Vector(width/2, height/2), Vector(0 + 2, -0.3), this->renderer, this->planet)); - this->universe.addPlanet(new Planet(1000, Vector(width/2, height/2 - height/4), Vector(7 + 2, -0.3), this->renderer, this->planet)); - this->universe.addPlanet(new Planet(1000, Vector(width/2, height/2 + height/4), Vector(-7 + 2, -0.3), this->renderer, this->planet));//*/ + /*this->universe.addPlanet(new Planet(100000, Vector(width/2, height/2), Vector(0 , 0), this->renderer, this->planet)); + this->universe.addPlanet(new Planet(1000, Vector(width/2, height/2 - height/4), Vector(7 , 0), this->renderer, this->planet)); + this->universe.addPlanet(new Planet(1000, Vector(width/2, height/2 + height/4), Vector(-7 , 0), this->renderer, this->planet));//*/ this->ui = new UIManager(); this->ui->buttons.push_back(new UIElement(Vector(width - 34 - 5, 10), this->renderer, "res/gfx/gui_exit.png", ID::EXIT)); @@ -87,7 +87,7 @@ void Game::update() SDL_GetMouseState(&x, &y); Vector mouseVec = Vector(x, y); - this->universe.move(mouseVec - this->previousMousePos); + this->universe.move(mouseVec - this->previousMousePos, this->universe.getMutexPtr()); this->previousMousePos = mouseVec; } @@ -178,13 +178,21 @@ void Game::handleEvents() break; case SDLK_RIGHT: - this->universe.move(this->universe.getPlanetPosition(this->index) * -1 + Vector(400, 400)); + if (index >= this->universe.size()) index = 0; + else if (index < 0) index = this->universe.size() - 1; + + this->universe.move(this->universe.getPlanetPosition(this->index) * -1, this->universe.getMutexPtr()); + this->universe.move(Vector(400, 400), this->universe.getMutexPtr()); this->index++; break; case SDLK_LEFT: - this->universe.move(this->universe.getPlanetPosition(this->index) * -1 + Vector(400, 400)); + if (index < 0) index = this->universe.size() - 1; + else if (index >= this->universe.size()) index = 0; + + this->universe.move(this->universe.getPlanetPosition(this->index) * -1, this->universe.getMutexPtr()); + this->universe.move(Vector(400, 400), this->universe.getMutexPtr()); this->index--; break; diff --git a/GravitySim/src/Planet.cpp b/GravitySim/src/Planet.cpp index c1b3bfc..70423ea 100644 --- a/GravitySim/src/Planet.cpp +++ b/GravitySim/src/Planet.cpp @@ -3,7 +3,6 @@ Planet::Planet(double mass, Vector position, Vector velocity, SDL_Renderer* renderer, SDL_Texture* texture) { this->radius = std::cbrt(4 * mass / DENSITY / PI / 3); - this->acceleration = Vector(); this->mass = mass; this->position = position; this->velocity = velocity; @@ -16,9 +15,10 @@ void Planet::destroyTexture() SDL_DestroyTexture(this->texture); } -void Planet::updateVelocity(std::vector& others) +void Planet::updateVelocity(std::vector* vec, std::mutex* m) { - this->acceleration = Vector(); + auto& others = *vec; + Vector acceleration; for (auto& other : others) { @@ -26,6 +26,8 @@ void Planet::updateVelocity(std::vector& others) if (sqrt(pow((this->position.x + this->radius - other->position.x - other->radius), 2) + pow((this->position.y + this->radius - other->position.y - other->radius), 2)) < this->radius + other->radius) { + + std::lock_guard lock(*m); if (this->mass > other->mass) { this->mass += other->mass; @@ -33,7 +35,10 @@ void Planet::updateVelocity(std::vector& others) Planet* p = other; delete p; + others.erase(std::remove(others.begin(), others.end(), other), others.end()); + this->radius = std::cbrt(4 * this->mass / DENSITY / PI / 3); + return; } else @@ -43,25 +48,31 @@ void Planet::updateVelocity(std::vector& others) Planet* p = this; delete p; + others.erase(std::remove(others.begin(), others.end(), this), others.end()); + other->radius = std::cbrt(4 * other->mass / DENSITY / PI / 3); + return; } } Vector posV = other->position - this->position; double distance = posV.Lenght(); + if (!distance) return; Vector mag = posV / distance; double force = this->mass * other->mass * G / pow(distance, 2); - this->acceleration += mag * force / this->mass; - this->radius = std::cbrt(4 * this->mass / DENSITY / PI / 3); + + acceleration += mag * force / this->mass; } - this->velocity += this->acceleration; + std::lock_guard lock(*m); + this->velocity += acceleration; } -void Planet::updatePosition() +void Planet::updatePosition(std::mutex* m) { + std::lock_guard lock(*m); this->position += this->velocity; } diff --git a/GravitySim/src/Planet.h b/GravitySim/src/Planet.h index 30a7250..50a9f07 100644 --- a/GravitySim/src/Planet.h +++ b/GravitySim/src/Planet.h @@ -1,7 +1,10 @@ #ifndef PLANET_H #define PLANET_H +#define ASYNC 1 + #include +#include #include "SDL_image.h" @@ -14,7 +17,7 @@ constexpr auto G = 0.1; struct Planet { double radius, mass; - Vector position, velocity, acceleration; + Vector position, velocity; SDL_Rect destRect; SDL_Texture* texture; @@ -23,8 +26,8 @@ struct Planet void destroyTexture(); - void updateVelocity(std::vector& others); - void updatePosition(); + void updateVelocity(std::vector* others, std::mutex* m); + void updatePosition(std::mutex* m); void render(SDL_Renderer* renderer, float zoom); }; diff --git a/GravitySim/src/Universe.cpp b/GravitySim/src/Universe.cpp index 81bdc7b..ac8380a 100644 --- a/GravitySim/src/Universe.cpp +++ b/GravitySim/src/Universe.cpp @@ -9,13 +9,42 @@ void Universe::update() { for (auto& planet : this->planets) { - planet->updateVelocity(this->planets); + #if ASYNC + this->futures.push_back(std::async(std::launch::async, [planet, this]() -> void + { + planet->updateVelocity(&this->planets, &this->mutex); + } + )); + + #else + planet->updateVelocity(&this->planets, &this->mutex); + + #endif } + #if ASYNC + this->futures.clear(); + + #endif for (auto& planet : this->planets) { - planet->updatePosition(); + #if ASYNC + this->futures.push_back(std::async(std::launch::async, [planet, this]() -> void + { + planet->updatePosition(&this->mutex); + } + )); + + #else + planet->updatePosition(&this->mutex); + + #endif } + + #if ASYNC + this->futures.clear(); + + #endif } void Universe::render(SDL_Renderer* renderer, float zoom) @@ -36,12 +65,28 @@ void Universe::restart() this->planets.clear(); } -void Universe::move(Vector deltaPos) +void Universe::move(Vector deltaPos, std::mutex* m) { for (auto& planet : planets) { + #if ASYNC + this->futures.push_back(std::async(std::launch::async, [planet, deltaPos, m]() -> void + { + std::lock_guard lock(*m); + planet->position += deltaPos; + } + )); + + #else planet->position += deltaPos; + + #endif } + + #if ASYNC + this->futures.clear(); + + #endif } Vector Universe::getPlanetPosition(int& index) diff --git a/GravitySim/src/Universe.h b/GravitySim/src/Universe.h index eee5fa9..790d50a 100644 --- a/GravitySim/src/Universe.h +++ b/GravitySim/src/Universe.h @@ -1,6 +1,8 @@ #ifndef UNIVERSE_H #define UNIVERSE_H +#include + #include "Planet.h" class Universe @@ -10,14 +12,19 @@ class Universe void update(); void render(SDL_Renderer* renderer, float zoom); void restart(); - void move(Vector deltaPos); + void move(Vector deltaPos, std::mutex* m); size_t size() { return this->planets.size(); } Vector getPlanetPosition(int& index); + std::mutex* getMutexPtr() { return &this->mutex; } private: std::vector planets = {}; + + std::vector> futures; + std::mutex mutex; + }; #endif \ No newline at end of file diff --git a/GravitySim/src/Vector.cpp b/GravitySim/src/Vector.cpp index 2726b67..619e388 100644 --- a/GravitySim/src/Vector.cpp +++ b/GravitySim/src/Vector.cpp @@ -44,22 +44,22 @@ Vector& Vector::Divide(const Vector& vec) return *this; } -Vector& operator+(Vector vec1, const Vector vec2) +Vector operator+(Vector vec1, const Vector vec2) { return vec1.Add(vec2); } -Vector& operator-(Vector vec1, const Vector vec2) +Vector operator-(Vector vec1, const Vector vec2) { return vec1.Substract(vec2); } -Vector& operator*(Vector vec1, const Vector vec2) +Vector operator*(Vector vec1, const Vector vec2) { return vec1.Multiply(vec2); } -Vector& operator/(Vector vec1, const Vector vec2) +Vector operator/(Vector vec1, const Vector vec2) { return vec1.Divide(vec2); } diff --git a/GravitySim/src/Vector.h b/GravitySim/src/Vector.h index b6de1e3..b86c353 100644 --- a/GravitySim/src/Vector.h +++ b/GravitySim/src/Vector.h @@ -16,10 +16,10 @@ struct Vector Vector& Multiply(const Vector& vec); Vector& Divide(const Vector& vec); - friend Vector& operator+(Vector vec1, const Vector vec2); - friend Vector& operator-(Vector vec1, const Vector vec2); - friend Vector& operator*(Vector vec1, const Vector vec2); - friend Vector& operator/(Vector vec1, const Vector vec2); + friend Vector operator+(Vector vec1, const Vector vec2); + friend Vector operator-(Vector vec1, const Vector vec2); + friend Vector operator*(Vector vec1, const Vector vec2); + friend Vector operator/(Vector vec1, const Vector vec2); Vector& operator+=(const Vector vec); Vector& operator-=(const Vector vec); diff --git a/GravitySim/src/main.cpp b/GravitySim/src/main.cpp index 101b5c8..d8f8414 100644 --- a/GravitySim/src/main.cpp +++ b/GravitySim/src/main.cpp @@ -14,6 +14,11 @@ int main(int argc, char* argv[]) //ShowWindow(GetConsoleWindow(), SW_HIDE); + #if ASYNC + std::cout << "Async updates enabled!" << std::endl; + + #endif + while (game->running()) {