diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..26b7b90f290470d564eeb8526ec60b76723feaf1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libs/googletest"] + path = libs/googletest + url = https://github.com/google/googletest.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 737b51021b3ccb1b6de8cd7e90a6179e11974922..8f3c5d712819558d928d08fd544e633461414d64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,18 +1,38 @@ -## CMake file for the Q-Pong game. -## -project(QuantumPong) - +# CMake file for the QPong project. +project(QPong) cmake_minimum_required(VERSION 3.2) -## Use modern C++! + +# Options +option(create_test "Build all tests." OFF) +option(release_type "Set the type of the releas (Debug/Release)." Release) + + +# Use modern C++! set(CMAKE_CXX_STANDARD 17) -set(CMAKE_BUILD_TYPE Release) + +## PkgConfig find_package(PkgConfig REQUIRED) -message(" - Build type is set to ${CMAKE_BUILD_TYPE}") -add_subdirectory( - src -) +# @todo Check versions of glib etc. librarys. +# On Ubuntu 19.10 there are warnings which are not present in Ubuntu 18.04 +# set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations") + + +# Add qpong lib for core qpong functionality +add_subdirectory(qpong_core) +include_directories(qpong_core) + + +# Add dir with gtk qpong app +add_subdirectory(gtk_qpong_app) + +# Add some unit tests +# not many yet ^^ +if (create_test) + add_subdirectory(libs/googletest) + add_subdirectory(tests) +endif() diff --git a/README.md b/README.md index 109ab413322fe1d94adcb5c423a8d47dd850aabb..44b8087c6c5e910c074e8287dea7cb8a002208aa 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,12 @@ make ```` +## TODOS + - ImageBuffer in die Klasse Particle ziehen, + - Methoden bereitstellen zum Abrufen der ImageBuffer + - ParticleImage muss das Particle Objekt kennen, um die ImageBuffer abrufen zu können. + - Umbauen der Klasse Particle zu einer Klasse Simulation Environemnt + ## Erweiterungsideen - Konfiguration über die GUI, evt. mit speichern - Spalt & Interferenz diff --git a/src/CMakeLists.txt b/gtk_qpong_app/CMakeLists.txt similarity index 51% rename from src/CMakeLists.txt rename to gtk_qpong_app/CMakeLists.txt index ea953791c8b9bd20f89a9f56260d76941af167a6..bafe30a2e44db8c7e4e56c7e308eeef8513ea929 100644 --- a/src/CMakeLists.txt +++ b/gtk_qpong_app/CMakeLists.txt @@ -1,18 +1,26 @@ -# library for the app should be GTK independent -add_library(qpong - Particle.cpp - ImageBuffer.cpp - QPlayer.cpp - Profiler.cpp - Config.cpp -) +# Specific settings for macOS +if(APPLE) + link_directories("/usr/local/lib") + message("ATTENTION: You probably have to export the PKG_CONFIG_PATH.") + message("For example: export PKG_CONFIG_PATH=\"/usr/local/lib:/usr/local/opt/zlib/lib/pkgconfig\"") +endif() + + +# Setup GTK configuration +pkg_check_modules(GTKMM gtkmm-3.0) +link_directories(${GTKMM_LIBRARY_DIRS}) + + +# get all GTKMM dependencies and configuration +include_directories(${GTKMM_INCLUDE_DIRS}) + +if(APPLE) + include_directories(/usr/local/include) +endif() -# @todo Check versions of glib etc. librarys. -# On Ubuntu 19.10 there are warnings which are not present in Ubuntu 18.04 -set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations") # create the application -add_executable(qpong.app +add_executable( qpong.app main.cpp QWindow.cpp QDrawingArea.cpp @@ -23,15 +31,10 @@ add_executable(qpong.app # we do need some threads find_package(Threads) -# get all GTKMM dependencies and configuration -pkg_check_modules(GTKMM gtkmm-3.0) - -link_directories(${GTKMM_LIBRARY_DIRS}) -include_directories(${GTKMM_INCLUDE_DIRS}) # link all necessary libs to the target -target_link_libraries(qpong.app - qpong +target_link_libraries( qpong.app + qpong_core ${CMAKE_THREAD_LIBS_INIT} ${GTKMM_LIBRARIES} fftw3 diff --git a/src/Common.cpp b/gtk_qpong_app/Common.cpp similarity index 95% rename from src/Common.cpp rename to gtk_qpong_app/Common.cpp index 06339680a6e5c4509e008ae462c8f0da71a23f58..cb507ffdfe84fbf62dcea030f605936074a71c97 100644 --- a/src/Common.cpp +++ b/gtk_qpong_app/Common.cpp @@ -1,4 +1,3 @@ -/// /// @brief /// diff --git a/src/Config.cpp b/gtk_qpong_app/Config.cpp similarity index 100% rename from src/Config.cpp rename to gtk_qpong_app/Config.cpp diff --git a/src/Config.hpp b/gtk_qpong_app/Config.hpp similarity index 100% rename from src/Config.hpp rename to gtk_qpong_app/Config.hpp diff --git a/src/ParticleImage.cpp b/gtk_qpong_app/ParticleImage.cpp similarity index 97% rename from src/ParticleImage.cpp rename to gtk_qpong_app/ParticleImage.cpp index fc6adaac0414bafc8b8e8789057db895ec2e32b6..e51aa727fca45ce3daf0f084f7981d0b0b976f23 100644 --- a/src/ParticleImage.cpp +++ b/gtk_qpong_app/ParticleImage.cpp @@ -4,9 +4,10 @@ /// #include "ParticleImage.hpp" -#include "Profiler.hpp" #include "Common.hpp" +using namespace QPong; + constexpr int bytesPerPixel = 3; constexpr int bitsPerSample = 8; diff --git a/src/ParticleImage.hpp b/gtk_qpong_app/ParticleImage.hpp similarity index 90% rename from src/ParticleImage.hpp rename to gtk_qpong_app/ParticleImage.hpp index 5e481856b7e4cee40e14f603cba07da3c7fe8f51..8d8ab97f11f891d77fe12bb83db31beafae7aed8 100644 --- a/src/ParticleImage.hpp +++ b/gtk_qpong_app/ParticleImage.hpp @@ -13,10 +13,11 @@ #include "ImageBuffer.hpp" + /// @brief Wraps an one dimensional array. /// Values can be accessed as in 2D. /// -class ParticleImage : public ImageBuffer +class ParticleImage : public QPong::ImageBuffer { public: ParticleImage(); diff --git a/src/QDrawingArea.cpp b/gtk_qpong_app/QDrawingArea.cpp similarity index 99% rename from src/QDrawingArea.cpp rename to gtk_qpong_app/QDrawingArea.cpp index 80f230391ed22412619b9af1170e38be4ab9fd8e..674092c4d316a1ddd81be3c4b28c1963e3ba7699 100644 --- a/src/QDrawingArea.cpp +++ b/gtk_qpong_app/QDrawingArea.cpp @@ -5,21 +5,25 @@ #include "QDrawingArea.hpp" + QDrawingArea::QDrawingArea() { m_dispatcher.connect(sigc::mem_fun(*this, &QDrawingArea::queue_draw)); } + void QDrawingArea::redraw() { m_dispatcher.emit(); } + void QDrawingArea::setPixbuf(Glib::RefPtr<Gdk::Pixbuf> pixbuf) { m_image = pixbuf; } + bool QDrawingArea::on_draw(const Cairo::RefPtr<Cairo::Context> &cr) { cr->save(); diff --git a/src/QDrawingArea.hpp b/gtk_qpong_app/QDrawingArea.hpp similarity index 100% rename from src/QDrawingArea.hpp rename to gtk_qpong_app/QDrawingArea.hpp diff --git a/src/QWindow.cpp b/gtk_qpong_app/QWindow.cpp similarity index 89% rename from src/QWindow.cpp rename to gtk_qpong_app/QWindow.cpp index 861565904b64820ed45268b47f672703061bb318..ff42b83469a80e96a6b27a39d1f4084d3ba24bf0 100644 --- a/src/QWindow.cpp +++ b/gtk_qpong_app/QWindow.cpp @@ -4,8 +4,8 @@ #include "QWindow.hpp" -#include "Profiler.hpp" #include "Config.hpp" +using namespace QPong; bool propagating = true; int propRate = 0; @@ -28,16 +28,16 @@ void QWindow::simulation() propRate = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count(); if (qPressed) - m_players[Player::One]->move(Direction::Up); + m_players[Player::Id::One]->move(Player::Direction::Up); if (aPressed) - m_players[Player::One]->move(Direction::Down); + m_players[Player::Id::One]->move(Player::Direction::Down); if (upPressed) - m_players[Player::Two]->move(Direction::Up); + m_players[Player::Id::Two]->move(Player::Direction::Up); if (downPressed) - m_players[Player::Two]->move(Direction::Down); + m_players[Player::Id::Two]->move(Player::Direction::Down); // Limit the speed of the simulation. auto dt = std::chrono::system_clock::now() - start; @@ -59,7 +59,7 @@ void render(QWindow *w) { using namespace std::chrono_literals; auto start = std::chrono::system_clock::now(); - std::this_thread::sleep_for(20ms); + std::this_thread::sleep_for(15ms); w->updateView(); renderRate = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count(); } while (true); @@ -75,8 +75,8 @@ QWindow::QWindow() constexpr double playerOneStartX = -0.7; constexpr double playerTwoStartX = 0.7; - m_players.insert(std::make_pair<Player, std::shared_ptr<QPlayer>>(Player::One, std::make_shared<QPlayer>(Player::One, Position{-0.7, 0}))); - m_players.insert(std::make_pair<Player, std::shared_ptr<QPlayer>>(Player::Two, std::make_shared<QPlayer>(Player::Two, Position{ 0.7, 0.4}))); + m_players.insert(std::make_pair<Player::Id, std::shared_ptr<Player>>(Player::Id::One, std::make_shared<Player>(Player::Id::One, Player::Position{-0.7, 0}))); + m_players.insert(std::make_pair<Player::Id, std::shared_ptr<Player>>(Player::Id::Two, std::make_shared<Player>(Player::Id::Two, Player::Position{ 0.7, 0.4}))); m_momentum = new ParticleImage; m_position = new ParticleImage; @@ -147,7 +147,7 @@ void QWindow::updateGui() ss = std::stringstream(); ss << "Score Player 1: "; - auto score = m_players[Player::One]->getScore(); + auto score = m_players[Player::Id::One]->getScore(); ss << std::setprecision(2) << std::setw(7) << score << "%"; if (score > 50.0) { @@ -158,7 +158,7 @@ void QWindow::updateGui() ss = std::stringstream(); ss << "Score Player 2: "; - score = m_players[Player::Two]->getScore(); + score = m_players[Player::Id::Two]->getScore(); ss << std::setprecision(2) << std::setw(7) << score << "%"; if (score > 50.0) { diff --git a/src/QWindow.hpp b/gtk_qpong_app/QWindow.hpp similarity index 93% rename from src/QWindow.hpp rename to gtk_qpong_app/QWindow.hpp index d2f17b1765476df2a632cae59007cad0c6fcd3b4..b9a610d287b61eba61a38857d57448593b629257 100644 --- a/src/QWindow.hpp +++ b/gtk_qpong_app/QWindow.hpp @@ -72,13 +72,13 @@ private: QDrawingArea m_positionArea; QDrawingArea m_momentumArea; - Particle *m_particle; + QPong::Particle *m_particle; std::thread m_propagatingThread; ParticleImage *m_momentum; ParticleImage *m_position; ParticleImage *m_obstacle; - std::map<Player, std::shared_ptr<QPlayer>> m_players; + std::map<QPong::Player::Id, std::shared_ptr<QPong::Player>> m_players; }; #endif \ No newline at end of file diff --git a/src/main.cpp b/gtk_qpong_app/main.cpp similarity index 100% rename from src/main.cpp rename to gtk_qpong_app/main.cpp diff --git a/src/qpong.config b/gtk_qpong_app/qpong.config similarity index 100% rename from src/qpong.config rename to gtk_qpong_app/qpong.config diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/libs/googletest b/libs/googletest index 8b4817e3df3746a20502a84580f661ac448821be..dcc92d0ab6c4ce022162a23566d44f673251eee4 160000 --- a/libs/googletest +++ b/libs/googletest @@ -1 +1 @@ -Subproject commit 8b4817e3df3746a20502a84580f661ac448821be +Subproject commit dcc92d0ab6c4ce022162a23566d44f673251eee4 diff --git a/qpong_core/CMakeLists.txt b/qpong_core/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b6f2974fbc7fd21e6f24281e53c9e9b92c555f67 --- /dev/null +++ b/qpong_core/CMakeLists.txt @@ -0,0 +1,7 @@ +# Add macOS specific include path. +if(APPLE) + include_directories(/usr/local/include) +endif() + +# Core QPong library +add_library(qpong_core Particle.cpp ImageBuffer.cpp Player.cpp) \ No newline at end of file diff --git a/src/Common.hpp b/qpong_core/Common.hpp similarity index 100% rename from src/Common.hpp rename to qpong_core/Common.hpp diff --git a/src/ImageBuffer.cpp b/qpong_core/ImageBuffer.cpp similarity index 88% rename from src/ImageBuffer.cpp rename to qpong_core/ImageBuffer.cpp index 7ad83ea1537646fc5abcf05bc7826ea0d0ea3ef6..b4a524b9b65cb2edcd870e0871c34c8e87511aed 100644 --- a/src/ImageBuffer.cpp +++ b/qpong_core/ImageBuffer.cpp @@ -5,6 +5,8 @@ #include "Common.hpp" #include "ImageBuffer.hpp" +using namespace QPong; + ImageBuffer::ImageBuffer() { m_potbuf = new double[QPong::arraySize]; @@ -28,11 +30,11 @@ const QColor ImageBuffer::getValue(unsigned index) QColor c { static_cast<float>(obs + r*r), //< red - static_cast<float>(r*r + i*i + obs/2), //< green + static_cast<float>(r*r + i*i + obs/1.5), //< green static_cast<float>(i*i) //< blue }; - constexpr double max = 0.83; + constexpr double max = 0.81; if (c.r > max) { c.r = max; diff --git a/src/ImageBuffer.hpp b/qpong_core/ImageBuffer.hpp similarity index 90% rename from src/ImageBuffer.hpp rename to qpong_core/ImageBuffer.hpp index fcbb81ee504f60bedc83fed3a09b6fe20e5be845..d7b58e93e5c507e4a7a10e75731165230bf2894c 100644 --- a/src/ImageBuffer.hpp +++ b/qpong_core/ImageBuffer.hpp @@ -9,16 +9,18 @@ #include <complex> +namespace QPong +{ + /// @brief Convinient conatiner to store a RGB value. /// {r, g, b} struct QColor { - float r = 0; - float g = 0; - float b = 0; + float r = 0.0f; + float g = 0.0f; + float b = 0.0f; }; - /// @brief Class ImageBuffer /// class ImageBuffer @@ -28,23 +30,22 @@ public: /// ImageBuffer(); - /// @brief Update the buffer at the given position. /// @param index Index of the value that should be changed. /// @param v The value as a complex number which will be interpreted as a color. /// @param pot Potential at position. - /// + /// void updateAt(unsigned index, std::complex<double> v, double pot); - /// @return Get color value from particle at array index. /// const QColor getValue(unsigned index); - private: double *m_potbuf; std::complex<double> *m_complexBuffer; }; +} // namespace QPong + #endif diff --git a/src/Particle.cpp b/qpong_core/Particle.cpp similarity index 83% rename from src/Particle.cpp rename to qpong_core/Particle.cpp index eae2dfa90defd07c72e3ca5a298da6b9e2358c51..c639bfe2f0baab602cb00bd81ef011215a044854 100644 --- a/src/Particle.cpp +++ b/qpong_core/Particle.cpp @@ -11,9 +11,10 @@ #include "Common.hpp" #include "Particle.hpp" -#include "Profiler.hpp" #include "Config.hpp" +using namespace QPong; + const std::complex<double> Ci(0.0, 1.0); @@ -69,7 +70,7 @@ void Particle::initMomentum() } -Particle::Particle(ImageBuffer *momentum, ImageBuffer *position, std::map<Player, std::shared_ptr<QPlayer>> players) +Particle::Particle(ImageBuffer *momentum, ImageBuffer *position, std::map<Player::Id, std::shared_ptr<Player>> players) : m_bufMomentumRepresentation{momentum} , m_bufPositionRepresentation{position} , m_ready{false} @@ -101,31 +102,15 @@ bool Particle::notReady() double Particle::removeParticle(int index, double cx) { - double e = cos(cx) * cos(cx); - double normPre = sqr(std::real(m_psi[index])) + sqr(std::real(m_psi[index])); + double normPre = sqr(std::real(m_psi[index])) + sqr(std::imag(m_psi[index])); + double e = sqr(cos(cx)); m_psi[index] *= e; - double dif = normPre - (sqr(std::real(m_psi[index])) + sqr(std::real(m_psi[index]))); + double dif = normPre - (sqr(std::real(m_psi[index])) + sqr(std::imag(m_psi[index]))); return dif; } -const double pxAt(int ix) -{ - if (ix > Config::getArrayWidth() / 2) - ix -= Config::getArrayWidth(); - return ix * M_PI * Config::getHbar(); -} - - -const double pyAt(int iy) -{ - if (iy > Config::getArrayHeight() / 2) - iy -= Config::getArrayHeight(); - return iy * M_PI * Config::getHbar(); -} - - -const double batPotential(double x, double y, Position pos) +const double batPotential(double x, double y, Player::Position pos) { y -= pos.y; double E = 0.0; @@ -154,8 +139,8 @@ const double batPotential(double x, double y, Position pos) constexpr double dt = 0.15; void Particle::manipulateParticleInPosition(int indexFrom, int indexTo) { - auto pOneX = m_players[Player::One]->getPosition().x; - auto pTwoX = m_players[Player::Two]->getPosition().x; + auto pOneX = m_players[Player::Id::One]->getPosition().x; + auto pTwoX = m_players[Player::Id::Two]->getPosition().x; float sumScorePlayerOne = 0.0; float sumScorePlayerTwo = 0.0; @@ -166,41 +151,62 @@ void Particle::manipulateParticleInPosition(int indexFrom, int indexTo) if (x < pOneX) //< expects p1.x < 0 { double cx = -pOneX + x; - cx = cx * (M_PI / 2) / (1.0 + pOneX); + cx = cx * (M_PI / 2.0) / (1.0 + pOneX); double dif = removeParticle(index, cx); sumScorePlayerTwo += dif; } if (x > pTwoX) //< expects p2.x > 0 { double cx = x - pTwoX; - cx = cx * (M_PI / 2) / (1.0 - pTwoX); + cx = cx * (M_PI / 2.0) / (1.0 - pTwoX); double dif = removeParticle(index, cx); sumScorePlayerOne += dif; } - double playerOneBat = batPotential(x, y, m_players[Player::One]->getPosition()); - double playerTwoBat = batPotential(x, y, m_players[Player::Two]->getPosition()); + double playerOneBat = batPotential(x, y, m_players[Player::Id::One]->getPosition()); + double playerTwoBat = batPotential(x, y, m_players[Player::Id::Two]->getPosition()); double horizontalBorders = sqr(y) * sqr(y) * sqr(y) * sqr(y) * 0.01; - std::complex<double> tmp = m_psi[index] * exp(-Ci * dt / Config::getHbar() * (playerOneBat + playerTwoBat + horizontalBorders)); - m_psi[index] = tmp; - m_bufPositionRepresentation->updateAt(index, tmp * 125.0, (playerOneBat + playerTwoBat + horizontalBorders) * 150); + auto potentialSum = playerOneBat + playerTwoBat + horizontalBorders; + auto tmpPsi = m_psi[index] * exp(-Ci * dt / hbar * potentialSum); + m_psi[index] = tmpPsi; + m_bufPositionRepresentation->updateAt(index, tmpPsi * 125.0, potentialSum * 150); } - m_players[Player::One]->addScore(sumScorePlayerOne); - m_players[Player::Two]->addScore(sumScorePlayerTwo); + m_players[Player::Id::One]->addScore(sumScorePlayerOne); + m_players[Player::Id::Two]->addScore(sumScorePlayerTwo); } double flattenMomentum(double x, double y) { double distanceToCenter = sqr(x) + sqr(y); - double offset = Config::getFlattenMomentumCutOff(); - if (distanceToCenter < offset) + constexpr double offset = 0.012; + if (distanceToCenter > offset) { - return 1.0; + return 1.0 / (1.0 + (distanceToCenter * 2.5)); } else { - return 1.0 / (1.0 + (distanceToCenter * Config::getFlattenMomentumFallOff())); + return 1.0; + } +} + + +const double pxAt(int ix) +{ + if (ix > QPong::arrayWidth / 2) + { + ix -= QPong::arrayWidth; + } + return ix * M_PI * hbar; +} + + +const double pyAt(int iy) +{ + if (iy > QPong::arrayHeight / 2) + { + iy -= QPong::arrayHeight; } + return iy * M_PI * hbar; } @@ -213,7 +219,9 @@ void Particle::moveStep(int indexFrom, int indexTo) constexpr double m = 1.0; double N = 1.0 / Config::getArraySize(); double E = (sqr(px) + sqr(py)) / (2.0 * m); - m_psi[i] *= exp(-Ci * dt / Config::getHbar() * E) * N * flattenMomentum(px, py); + auto f = flattenMomentum(px, py); + m_psi[i] *= exp(-Ci * dt / hbar * E) * N * f; + // m_psi[i] = flattenMomentum(px, py) * 0.00001; } } diff --git a/src/Particle.hpp b/qpong_core/Particle.hpp similarity index 90% rename from src/Particle.hpp rename to qpong_core/Particle.hpp index 4f67371c919d0f6a5a71686b22d636a6b4ee292e..0477612d625d4c2a94cd8a10cc3ba44943efb554 100644 --- a/src/Particle.hpp +++ b/qpong_core/Particle.hpp @@ -1,7 +1,6 @@ /// /// @file Particle.hpp /// @author Armin Co -/// /// @brief Particle class header. /// @@ -16,8 +15,9 @@ #include <fftw3.h> #include "ImageBuffer.hpp" -#include "QPlayer.hpp" +#include "Player.hpp" +namespace QPong { class Particle { @@ -25,7 +25,7 @@ public: /// @brief Contructor /// - Particle(ImageBuffer *momentum, ImageBuffer *position, std::map<Player, std::shared_ptr<QPlayer>> players); + Particle(ImageBuffer *momentum, ImageBuffer *position, std::map<Player::Id, std::shared_ptr<Player>> players); /// @brief Destructor @@ -50,17 +50,6 @@ public: private: - std::complex<double> *m_psi; - fftw_plan m_planForward; - fftw_plan m_planBackward; - bool m_ready; - - std::map<Player, std::shared_ptr<QPlayer>> m_players; - - ImageBuffer *m_bufPositionRepresentation; - ImageBuffer *m_bufMomentumRepresentation; - - /// @brief Update the array at the ArrayCanvas /// void updateMomentumImage(); @@ -83,7 +72,22 @@ private: double removeParticle(int index, double cx); + std::complex<double> *m_psi; + fftw_plan m_planForward; + fftw_plan m_planBackward; + bool m_ready; + + std::map<Player::Id, std::shared_ptr<Player>> m_players; + + ImageBuffer *m_bufPositionRepresentation; + ImageBuffer *m_bufMomentumRepresentation; + + + + Particle() = delete; }; +} // namespace QPong + #endif \ No newline at end of file diff --git a/src/QPlayer.cpp b/qpong_core/Player.cpp similarity index 78% rename from src/QPlayer.cpp rename to qpong_core/Player.cpp index 925be69d952a127d3fdd030e3d8edb7290db31e9..31db21340b65b86981484c1555e600563c7b524e 100644 --- a/src/QPlayer.cpp +++ b/qpong_core/Player.cpp @@ -3,23 +3,24 @@ /// @author Armin Co /// -#include "QPlayer.hpp" #include <mutex> +#include "Player.hpp" + +using namespace QPong; constexpr double speedStepSize = 0.0005; -QPlayer::QPlayer(Player pl, Position pos) +Player::Player(Player::Id pl, Player::Position pos) : m_id {pl} , m_x {pos.x} , m_y {pos.y} { - } -void QPlayer::update(double dt) +void Player::update(double dt) { constexpr double negativeAccelScale = 1.5; m_y += (m_vy * dt * 4); @@ -49,7 +50,7 @@ void QPlayer::update(double dt) } -void QPlayer::move(Direction direction) +void Player::move(Direction direction) { constexpr double addSpped = 3; switch (direction) @@ -74,28 +75,27 @@ void QPlayer::move(Direction direction) } -float QPlayer::getScore() +float Player::getScore() { return m_score * 100; } -std::mutex mtx; - -void QPlayer::addScore(float score) +std::mutex scoreMtx; +void Player::addScore(float score) { - std::lock_guard<std::mutex> lockScore(mtx); + std::lock_guard<std::mutex> lockScore(scoreMtx); m_score += score; } -Position QPlayer::getPosition() +Player::Position Player::getPosition() { return {m_x, m_y}; } -void QPlayer::reset() +void Player::reset() { m_score = 0; } \ No newline at end of file diff --git a/src/QPlayer.hpp b/qpong_core/Player.hpp similarity index 55% rename from src/QPlayer.hpp rename to qpong_core/Player.hpp index 22f42ea3ee1d04c4a63cc1540f28b3d25f5b4957..7154bc9ae2705929b17696a2638a33f2cd264ad0 100644 --- a/src/QPlayer.hpp +++ b/qpong_core/Player.hpp @@ -8,42 +8,44 @@ #ifndef QPONG_QPLAYER_HPP #define QPONG_QPLAYER_HPP -/// @brief Available players -/// -enum class Player -{ - One, - Two -}; +namespace QPong { -/// @brief The bat can be moved up and down. -/// -enum class Direction +/// @brief Class wraps all values of one Player. +/// +class Player { - Up, - Down -}; +public: + enum class Id + { + One, + Two + }; -struct Position -{ - double x; - double y; -}; -class QPlayer -{ -public: - QPlayer(Player pl, Position pos); + struct Position + { + double x; + double y; + }; + + + enum class Direction + { + Up, + Down + }; + + + Player(Id pl, Position pos); void update(double dt); void move(Direction d); - float getScore(); void addScore(float score); void reset(); - + float getScore(); Position getPosition(); private: - Player m_id; + Id m_id; double m_x; double m_y; double m_vx = 0; @@ -51,4 +53,6 @@ private: double m_score = 0; }; +} // namespace QPong + #endif \ No newline at end of file diff --git a/src/Profiler.cpp b/src/Profiler.cpp deleted file mode 100644 index e3346012892de08bee0593dc5397ebdac6162e52..0000000000000000000000000000000000000000 --- a/src/Profiler.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/// -/// @file Profiler.cpp -/// @author Armin Co -/// -/// @brief - -#include "Profiler.hpp" - -Profiler::Profiler(const char* name) - : m_name {name} - , m_stopped {false} - , m_verbose {Verbose::False} -{ - m_startTimepoint = std::chrono::high_resolution_clock::now(); -} - -Profiler::~Profiler() -{ - if (!m_stopped) - { - stop(); - } -} - -long Profiler::stop() -{ - auto endTimepoint = std::chrono::high_resolution_clock::now(); - m_stopped = true; - long mus = std::chrono::duration_cast<std::chrono::nanoseconds>(endTimepoint - m_startTimepoint).count(); - - if (m_verbose == Verbose::True) - { - std::cout << m_name << ": " << mus / 1000.0 / 1000.0<< "ms" << std::endl; - } - - return mus; -} \ No newline at end of file diff --git a/src/Profiler.hpp b/src/Profiler.hpp deleted file mode 100644 index 24a39ee26deb9b2e2756b87b6c5b9d79fb21eb69..0000000000000000000000000000000000000000 --- a/src/Profiler.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/// -/// @file Profiler.hpp -/// @author Armin Co -/// -/// @brief Class to do some basic timing and profiling. -/// - -#ifndef QPONG_PROFILER_HPP -#define QPONG_PROFILER_HPP - -#include <chrono> -#include <iostream> - -enum class Verbose -{ - True, - False -}; - -class Profiler -{ - -public: - Profiler(const char* name); - ~Profiler(); - - long stop(); - -private: - const char* m_name; - Verbose m_verbose; - std::chrono::time_point<std::chrono::system_clock> m_startTimepoint; - bool m_stopped; - -}; - -#endif \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..0f98b3350c88a659ba0c241e28dc1b5d184275bd --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,23 @@ + +enable_testing() + +include_directories( + ${gtest_SOURCE_DIR}/include + ${gtest_SOURCE_DIR} +) + +add_executable( + runUnitTests + test_qpong.cpp +) + +target_link_libraries( + runUnitTests + gtest + gtest_main +) + +target_link_libraries( + runUnitTests + qpong_core +) diff --git a/tests/test_qpong.cpp b/tests/test_qpong.cpp new file mode 100644 index 0000000000000000000000000000000000000000..203e84f6c4600c2f707e4ae16ec91816512cccc8 --- /dev/null +++ b/tests/test_qpong.cpp @@ -0,0 +1,65 @@ +#include <iostream> +#include "gtest/gtest.h" + +#include "ImageBuffer.hpp" + + +/// @brief Creating a test fixture frequently used objects for tests +/// +class QPongLib : public testing::Test +{ + protected: + ImageBuffer *momentumImage; + ImageBuffer *positionImage; + // members + + // called before any test + void SetUp() override + { + + } + + virtual void TearDown() + { + + } + +}; + +/// @brief A simple function to test +/// +int addInts(int a, int b) +{ + return a + b; +} + + +TEST(ImageBuffer, getValue) +{ + const ImageBuffer imbf; + const ImageBuffer imbff; + const ImageBuffer imbfff; + +} + + +TEST(addInts, positiveValues) +{ + int a {1}; + int b {3}; + + ASSERT_EQ(addInts(a, b), 4); +} + +TEST(addInts, shouldBreak) +{ + EXPECT_NE(3+1, 0) << "Yes yes, because it is just a test!"; +} + +TEST(addInts, negativeValues) +{ + ASSERT_EQ(-3 + -5, -8); +} + +/// @todo Example for mocks and an explanation what they are. +/// \ No newline at end of file