diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bbc8c2b..12fc683 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,9 +8,9 @@ cppcheck: stage: lint script: cppcheck --inline-suppr --error-exitcode=1 src -#cpplint: -# stage: lint -# script: cpplint $(find src -type f) +cpplint: + stage: lint + script: cpplint $(find src -type f) make: stage: build diff --git a/CPPLINT.cfg b/CPPLINT.cfg index e4c5dea..95c92e4 100644 --- a/CPPLINT.cfg +++ b/CPPLINT.cfg @@ -1 +1 @@ -filter=-legal/copyright,-whitespace/indent,-build/header_guard,-build/include_order,-whitespace/comments +filter=-legal/copyright,-build/header_guard,-whitespace/indent,-whitespace/comments,-build/include_order diff --git a/src/gameoflife/CellMap.cpp b/src/gameoflife/CellMap.cpp index a5869b8..d72c610 100644 --- a/src/gameoflife/CellMap.cpp +++ b/src/gameoflife/CellMap.cpp @@ -1,31 +1,27 @@ -#include "CellMap.h" -#include "Game.h" +#include +#include - -CellMap::CellMap(Game* g, size_t w, size_t h) - : game(g), width(w), height(h), length_in_bytes(w * h) { +CellMap::CellMap(Game *g, size_t w, size_t h) + : game(g), width(w), height(h), length_in_bytes(w * h) { // Adding () calls constructor for every Cell in the array cells = new Cell[length_in_bytes](); } - CellMap::CellMap(size_t w, size_t h) - :width(w), height(h), length_in_bytes(w * h) { + : width(w), height(h), length_in_bytes(w * h) { // Adding () calls constructor for every Cell in the array cells = new Cell[length_in_bytes](); } -CellMap::~CellMap() { - delete[] cells; -} +CellMap::~CellMap() { delete[] cells; } -void CellMap::clear(){ - for(size_t i = 0; i < length_in_bytes; ++i) +void CellMap::clear() { + for (size_t i = 0; i < length_in_bytes; ++i) cells[i] = 0; } void CellMap::changeCellState(size_t c, size_t l, int toAlive) { - Cell* cell_ptr = cells + (l * width) + c; + Cell *cell_ptr = cells + (l * width) + c; if (toAlive) *(cell_ptr) |= LIVING_BIT; @@ -41,31 +37,19 @@ void CellMap::nextGeneration() { updateNeighbourCount(); size_t w = width, h = height; - Cell* cell_ptr; + Cell *cell_ptr; cell_ptr = cells; - for (size_t l = 0; l < h; ++l) - { - for (size_t c = 0; c < w; ++c) - { - if (*cell_ptr != 0) - { + for (size_t l = 0; l < h; ++l) { + for (size_t c = 0; c < w; ++c) { + if (*cell_ptr != 0) { size_t neighbours = *cell_ptr >> 1; - if (*cell_ptr & LIVING_BIT) - { - // TODO: adapt the game's rules + if (*cell_ptr & LIVING_BIT) { if ((neighbours != 2) && (neighbours != 3)) - { changeCellState(c, l, 0); - } - } - else - { - // TODO: adapt the game's rules + } else { if (neighbours == 3) - { changeCellState(c, l, 1); - } } } ++cell_ptr; @@ -74,25 +58,21 @@ void CellMap::nextGeneration() { } void CellMap::updateNeighbourCount() { - Cell* cell_ptr; + Cell *cell_ptr; size_t w = width, h = height; // we clear previous neighbour calculations cell_ptr = cells; - for (size_t i = 0; i < length_in_bytes; ++i) - { + for (size_t i = 0; i < length_in_bytes; ++i) { *(cell_ptr) &= LIVING_BIT; ++cell_ptr; } // and we calculate the neighbour count cell_ptr = cells; - for (size_t l = 0; l < h; ++l) - { - for (size_t c = 0; c < w; ++c) - { - if (*cell_ptr & LIVING_BIT) - { + for (size_t l = 0; l < h; ++l) { + for (size_t c = 0; c < w; ++c) { + if (*cell_ptr & LIVING_BIT) { if (c > 0 && l > 0) *(cell_ptr - w - 1) += NEIGHBOR_COUNT_BITS; // top left if (l > 0) @@ -115,11 +95,6 @@ void CellMap::updateNeighbourCount() { } } +size_t CellMap::getWidth() { return width; } -size_t CellMap::getWidth() { - return width; -} - -size_t CellMap::getHeight() { - return height; -} +size_t CellMap::getHeight() { return height; } diff --git a/src/gameoflife/CellMap.h b/src/gameoflife/CellMap.h index 63bb086..36c9866 100644 --- a/src/gameoflife/CellMap.h +++ b/src/gameoflife/CellMap.h @@ -5,7 +5,7 @@ #include #include -#define LIVING_BIT 0b01 +#define LIVING_BIT 0b01 #define NEIGHBOR_COUNT_BITS 0b10 typedef uint8_t Cell; @@ -23,10 +23,9 @@ class Game; * This allows us to not use the temp_cells array. */ -class CellMap -{ +class CellMap { public: - CellMap(Game* g, size_t w, size_t h); + CellMap(Game *g, size_t w, size_t h); CellMap(size_t w, size_t h); ~CellMap(); void changeCellState(size_t c, size_t l, int toAlive); @@ -37,8 +36,8 @@ class CellMap void clear(); private: - Game* game; - Cell* cells; + Game *game; + Cell *cells; size_t width; size_t height; size_t length_in_bytes; diff --git a/src/gameoflife/Game.cpp b/src/gameoflife/Game.cpp index db91d41..ef7d541 100644 --- a/src/gameoflife/Game.cpp +++ b/src/gameoflife/Game.cpp @@ -1,86 +1,76 @@ -#include "Game.h" -#include "CellMap.h" +#include +#include #include -Game::Game(std:: size_t width, std::size_t height) : generation(0) { +Game::Game(std::size_t width, std::size_t height) : generation(0) { map = new CellMap(this, width, height); } -Game::~Game() { } +Game::~Game() {} -std::size_t Game::getGeneration() { - return generation; -} +std::size_t Game::getGeneration() { return generation; } -CellMap* Game::getMap() { - return map; -} +CellMap *Game::getMap() { return map; } void Game::nextGeneration() { ++generation; map->nextGeneration(); } -//TODO: Expand world size if necessary -void Game::loadRLE(QString filename){ - +void Game::loadRLE(QString filename) { map->clear(); generation = 0; QFile file(filename); - if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) - return; - int width = 0; - int height = 0; - QByteArray data(""); - while(!file.atEnd()) - { - QByteArray line = file.readLine(); - if(line[0] == '#'){ - continue; - } - if(line[0] == 'x'){ - QList list = line.split(','); - width = ((list[0].split('='))[1].simplified()).toInt(); - height = ((list[1].split('='))[1].simplified()).toInt(); - continue; - } - data.append(line); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return; + int width = 0; + int height = 0; + QByteArray data(""); + while (!file.atEnd()) { + QByteArray line = file.readLine(); + if (line[0] == '#') { + continue; + } + if (line[0] == 'x') { + QList list = line.split(','); + width = ((list[0].split('='))[1].simplified()).toInt(); + height = ((list[1].split('='))[1].simplified()).toInt(); + continue; } - data = data.simplified(); - int init_x = map->getWidth()/2 - (int) (width/2); - int init_y = map->getHeight()/2 - (int) (height/2); + data.append(line); + } + data = data.simplified(); + int init_x = map->getWidth() / 2 - static_cast(width / 2); + int init_y = map->getHeight() / 2 - static_cast(height / 2); - int curr_x = init_x; - int curr_y = init_y; + int curr_x = init_x; + int curr_y = init_y; - QByteArray qs(""); - for(int i = 0; i < data.length(); ++i) - { - if(data[i] == '\0') - continue; - int q; - if(data[i] == '$'){ - q = qs.isEmpty() ? 1 : qs.toInt(); - curr_y += q; - curr_x = init_x; - qs.clear(); - } - if(data[i] >= '0' && data[i] <= '9'){ - qs.append(data[i]); - } - if(data[i] == 'o' || data[i] == 'b'){ - q = qs.isEmpty() ? 1 : qs.toInt(); - for (int n = 0; n < q; n++) { - map->changeCellState(curr_x,curr_y,(data[i] == 'o')); - curr_x++; - } - qs.clear(); + QByteArray qs(""); + for (int i = 0; i < data.length(); ++i) { + if (data[i] == '\0') + continue; + int q; + if (data[i] == '$') { + q = qs.isEmpty() ? 1 : qs.toInt(); + curr_y += q; + curr_x = init_x; + qs.clear(); + } + if (data[i] >= '0' && data[i] <= '9') { + qs.append(data[i]); + } + if (data[i] == 'o' || data[i] == 'b') { + q = qs.isEmpty() ? 1 : qs.toInt(); + for (int n = 0; n < q; n++) { + map->changeCellState(curr_x, curr_y, (data[i] == 'o')); + curr_x++; } - if(data[i] == '!') - break; + qs.clear(); } - + if (data[i] == '!') + break; + } } - diff --git a/src/gameoflife/Game.h b/src/gameoflife/Game.h index e75d630..a1859dc 100644 --- a/src/gameoflife/Game.h +++ b/src/gameoflife/Game.h @@ -3,21 +3,20 @@ #include "CellMap.h" -#include #include +#include -class Game -{ +class Game { public: - Game(std:: size_t width, std::size_t height); + Game(std::size_t width, std::size_t height); ~Game(); void nextGeneration(); - CellMap* getMap(); - std::size_t getGeneration() ; + CellMap *getMap(); + std::size_t getGeneration(); void loadRLE(QString filename); private: - CellMap* map; + CellMap *map; std::size_t generation; }; diff --git a/src/logic/BigInt.h b/src/logic/BigInt.h new file mode 100644 index 0000000..aa1750e --- /dev/null +++ b/src/logic/BigInt.h @@ -0,0 +1,25 @@ +#ifndef BIG_INT_HPP +#define BIG_INT_HPP + +#include +#include + +typedef mpz_class BigInt; + +static std::string bigint_to_str(BigInt i) { + std::string str_i = i.get_str(); + std::string result; + if (str_i.size() <= 20) { + return str_i; + } else { + result += str_i[0]; + result += '.'; + result += str_i[1]; + result += str_i[2]; + result += 'e'; + result += std::to_string(str_i.size() - 1); + } + return result; +} + +#endif // BIG_INT_HPP diff --git a/src/logic/BigInt.hpp b/src/logic/BigInt.hpp deleted file mode 100644 index 43ed60d..0000000 --- a/src/logic/BigInt.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef BIG_INT_HPP -#define BIG_INT_HPP - -#include -#include - -typedef mpz_class BigInt; - -static std::string bigint_to_str(BigInt i) -{ - std::string str_i = i.get_str(); - std::string result; - if(str_i.size() <= 20){ - return str_i; - } else { - result += str_i[0]; - result += '.'; - result += str_i[1]; - result += str_i[2]; - result += 'e'; - result += std::to_string(str_i.size() - 1); - } - return result; -} - -#endif // BIG_INT_HPP diff --git a/src/logic/CellState.hpp b/src/logic/CellState.h similarity index 100% rename from src/logic/CellState.hpp rename to src/logic/CellState.h diff --git a/src/logic/Coord.cpp b/src/logic/Coord.cpp index bdbaeb4..7f18fce 100644 --- a/src/logic/Coord.cpp +++ b/src/logic/Coord.cpp @@ -1,17 +1,16 @@ -#include "Coord.hpp" +#include Coord::Coord(size_t level) - : x(BigInt(1) << mp_size_t(level)), y(BigInt(1) << mp_size_t(level)) {} + : x(BigInt(1) << mp_size_t(level)), y(BigInt(1) << mp_size_t(level)) {} -Coord::Coord(BigInt x, BigInt y) - : x(x), y(y) {} +Coord::Coord(BigInt x, BigInt y) : x(x), y(y) {} bool Coord::operator==(const Coord &coord) { return x == coord.x && y == coord.y; } Coord Coord::operator+(const Coord &coord) { - return Coord(x + coord.x,y + coord .y); + return Coord(x + coord.x, y + coord.y); } void Coord::operator+=(const Coord &coord) { diff --git a/src/logic/Coord.hpp b/src/logic/Coord.h similarity index 89% rename from src/logic/Coord.hpp rename to src/logic/Coord.h index 4c70af9..4f0a4cf 100644 --- a/src/logic/Coord.hpp +++ b/src/logic/Coord.h @@ -2,14 +2,14 @@ #define COORD_HPP #include -#include "BigInt.hpp" +#include class Coord { public: BigInt x, y; Coord() = default; - Coord(size_t level); + explicit Coord(size_t level); Coord(BigInt x, BigInt y); bool operator==(const Coord &coord); @@ -17,7 +17,7 @@ class Coord { void operator+=(const Coord &coord); Coord operator-(const Coord &coord); void operator-=(const Coord &coord); - + Coord operator<<(size_t shift); void operator>>=(size_t shift); Coord operator>>(size_t shift); diff --git a/src/logic/HashlifeUniverse/HashlifeUniverse.cpp b/src/logic/HashlifeUniverse/HashlifeUniverse.cpp index 9a71fdc..8697216 100644 --- a/src/logic/HashlifeUniverse/HashlifeUniverse.cpp +++ b/src/logic/HashlifeUniverse/HashlifeUniverse.cpp @@ -1,58 +1,51 @@ -#include "HashlifeUniverse.hpp" +#include // #include #include -#include HashlifeUniverse::HashlifeUniverse(size_t top_level, Coord top_left) - : Universe(top_level, top_left), top_left(top_left), top_level(top_level) -{ + : Universe(top_level, top_left), top_left(top_left), top_level(top_level) { macrocell_sets.resize(top_level + 1); zeros.push_back(nullptr); - zeros.push_back((Quadrant *)minicell()); - for (size_t i = 2; i <= top_level; ++i) - { - zeros.push_back((Quadrant *)macrocell(i)); + zeros.push_back(reinterpret_cast(minicell())); + for (size_t i = 2; i <= top_level; ++i) { + zeros.push_back(reinterpret_cast(macrocell(i))); } - root = (MacroCell *)zeros.back(); + root = reinterpret_cast(zeros.back()); } HashlifeUniverse::HashlifeUniverse(QString filename, Coord top_left) - : Universe(filename, top_left), top_left(top_left) -{ + : Universe(filename, top_left), top_left(top_left) { QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return; - Coord boundingbox = read_rle_size(file); + Coord boundingbox = read_rle_size(&file); // Starting with one extra level macrocell_sets.resize(top_level + 1); zeros.push_back(nullptr); - zeros.push_back((Quadrant *)minicell()); - for (size_t i = 2; i <= top_level; ++i) - { - zeros.push_back((Quadrant *)macrocell(i)); + zeros.push_back(reinterpret_cast(minicell())); + for (size_t i = 2; i <= top_level; ++i) { + zeros.push_back(reinterpret_cast(macrocell(i))); } - root = (MacroCell *)zeros.back(); + root = reinterpret_cast(zeros.back()); - read_rle_data(file, boundingbox); + read_rle_data(&file, boundingbox); file.close(); } -void HashlifeUniverse::debug() { ((Quadrant *)root)->debug(top_level); } +void HashlifeUniverse::debug() { + (reinterpret_cast(root))->debug(top_level); +} -Coord HashlifeUniverse::read_rle_size(QFile &file) -{ - while (!file.atEnd()) - { - QByteArray line = file.readLine(); - if (line[0] == '#') - { +Coord HashlifeUniverse::read_rle_size(QFile *file) { + while (!file->atEnd()) { + QByteArray line = file->readLine(); + if (line[0] == '#') { continue; } - if (line[0] == 'x') - { + if (line[0] == 'x') { QList list = line.split(','); int width = ((list[0].split('='))[1].simplified()).toInt(); int height = ((list[1].split('='))[1].simplified()).toInt(); @@ -61,16 +54,13 @@ Coord HashlifeUniverse::read_rle_size(QFile &file) return Coord(width, height); } } - return 6; + return Coord(6); } -void HashlifeUniverse::read_rle_data(QFile &file, Coord boundingbox) -{ - +void HashlifeUniverse::read_rle_data(QFile *file, Coord boundingbox) { QByteArray data(""); - while (!file.atEnd()) - { - QByteArray line = file.readLine(); + while (!file->atEnd()) { + QByteArray line = file->readLine(); data.append(line); } @@ -84,27 +74,22 @@ void HashlifeUniverse::read_rle_data(QFile &file, Coord boundingbox) int curr_y = init_y; QByteArray qs(""); - for (int i = 0; i < data.length(); ++i) - { + for (int i = 0; i < data.length(); ++i) { if (data[i] == '\0') continue; int q; - if (data[i] == '$') - { + if (data[i] == '$') { q = qs.isEmpty() ? 1 : qs.toInt(); curr_y += q; curr_x = init_x; qs.clear(); } - if (data[i] >= '0' && data[i] <= '9') - { + if (data[i] >= '0' && data[i] <= '9') { qs.append(data[i]); } - if (data[i] == 'o' || data[i] == 'b') - { + if (data[i] == 'o' || data[i] == 'b') { q = qs.isEmpty() ? 1 : qs.toInt(); - for (int n = 0; n < q; n++) - { + for (int n = 0; n < q; n++) { set(Coord(curr_x, curr_y), data[i] == 'o'); curr_x++; } @@ -115,169 +100,134 @@ void HashlifeUniverse::read_rle_data(QFile &file, Coord boundingbox) } } -void HashlifeUniverse::assert_handles(size_t asserted_level) -{ - - if (asserted_level >= macrocell_sets.size()) - { - cout << "Asserted level greater\n"; +void HashlifeUniverse::assert_handles(size_t asserted_level) { + if (asserted_level >= macrocell_sets.size()) { + std::cout << "Asserted level greater\n"; size_t previous_asserted_level = macrocell_sets.size() - 1; macrocell_sets.resize(asserted_level + 1); - for (size_t level = previous_asserted_level + 1; - level <= asserted_level; ++level) - zeros.push_back((Quadrant *)macrocell(level)); + for (size_t level = previous_asserted_level + 1; level <= asserted_level; + ++level) + zeros.push_back(reinterpret_cast(macrocell(level))); } } -void HashlifeUniverse::step() -{ +void HashlifeUniverse::step() { // Assert that the creation of higher level is possible assert_handles(top_level + 2); // Add of crown of empty cell crown(); crown(); // Calculate result of universe - root = (MacroCell *) result(top_level--, root); + root = reinterpret_cast(result(top_level--, root)); generation_count += BigInt(1) << mp_size_t(top_level - 2); Quadrant *z = zeros[top_level - 2]; // Checking for crown - if (root->nw->macrocell.se == z && - root->nw->macrocell.nw == z && - root->nw->macrocell.ne == z && - root->ne->macrocell.nw == z && - root->ne->macrocell.ne == z && - root->ne->macrocell.se == z && - root->se->macrocell.ne == z && - root->se->macrocell.se == z && - root->se->macrocell.sw == z && - root->sw->macrocell.se == z && - root->sw->macrocell.sw == z && - root->sw->macrocell.nw == z) - { - cout << "Allo ?" << '\n'; + if (root->nw->macrocell.se == z && root->nw->macrocell.nw == z && + root->nw->macrocell.ne == z && root->ne->macrocell.nw == z && + root->ne->macrocell.ne == z && root->ne->macrocell.se == z && + root->se->macrocell.ne == z && root->se->macrocell.se == z && + root->se->macrocell.sw == z && root->sw->macrocell.se == z && + root->sw->macrocell.sw == z && root->sw->macrocell.nw == z) { + std::cout << "Allo ?" << '\n'; top_level--; root = macrocell(top_level, root->nw->macrocell.se, root->ne->macrocell.sw, root->sw->macrocell.ne, root->se->macrocell.nw); - } - else - { + } else { top_left -= Coord(top_level - 2); } - cout << "Universe size : " << top_level << '\n'; + std::cout << "Universe size : " << top_level << '\n'; } -const CellState HashlifeUniverse::get(Coord target) const -{ - if (target.y >= top_left.y && target.y < top_left.y + (BigInt(1) << mp_size_t(top_level)) && target.x >= top_left.x && target.x < top_left.x + (BigInt(1) << mp_size_t(top_level))) +const CellState HashlifeUniverse::get(Coord target) const { + if (target.y >= top_left.y && + target.y < top_left.y + (BigInt(1) << mp_size_t(top_level)) && + target.x >= top_left.x && + target.x < top_left.x + (BigInt(1) << mp_size_t(top_level))) return *find(target); else return 0; } -void HashlifeUniverse::set(Coord target, CellState state) -{ - root = (MacroCell *)set_rec(top_left, top_level, (Quadrant *)root, target, - state); +void HashlifeUniverse::set(Coord target, CellState state) { + root = reinterpret_cast(set_rec( + top_left, top_level, reinterpret_cast(root), target, state)); } Quadrant *HashlifeUniverse::set_rec(Coord current, size_t level, Quadrant *cell, - Coord target, CellState state) -{ + Coord target, CellState state) { Coord size(level - 1); Coord center = current + size; - if (level == 1) - { - if (target.y < center.y) - { + if (level == 1) { + if (target.y < center.y) { if (target.x < center.x) - return (Quadrant *)minicell(state, cell->minicell.ne, cell->minicell.sw, - cell->minicell.se); + return reinterpret_cast(minicell( + state, cell->minicell.ne, cell->minicell.sw, cell->minicell.se)); else - return (Quadrant *)minicell(cell->minicell.nw, state, cell->minicell.sw, - cell->minicell.se); - } - else - { + return reinterpret_cast(minicell( + cell->minicell.nw, state, cell->minicell.sw, cell->minicell.se)); + } else { if (target.x < center.x) - return (Quadrant *)minicell(cell->minicell.nw, cell->minicell.ne, state, - cell->minicell.se); + return reinterpret_cast(minicell( + cell->minicell.nw, cell->minicell.ne, state, cell->minicell.se)); else - return (Quadrant *)minicell(cell->minicell.nw, cell->minicell.ne, - cell->minicell.sw, state); + return reinterpret_cast(minicell( + cell->minicell.nw, cell->minicell.ne, cell->minicell.sw, state)); } - } - else - { + } else { level -= 1; - if (target.y < center.y) - { - if (target.x < center.x) - return (Quadrant *)macrocell( + if (target.y < center.y) { + if (target.x < center.x) { + return reinterpret_cast(macrocell( level, set_rec(current, level, cell->macrocell.nw, target, state), - cell->macrocell.ne, cell->macrocell.sw, cell->macrocell.se); - else - { + cell->macrocell.ne, cell->macrocell.sw, cell->macrocell.se)); + } else { current.x = center.x; - return (Quadrant *)macrocell( + return reinterpret_cast(macrocell( level, cell->macrocell.nw, set_rec(current, level, cell->macrocell.ne, target, state), - cell->macrocell.sw, cell->macrocell.se); + cell->macrocell.sw, cell->macrocell.se)); } - } - else - { + } else { current.y = center.y; - if (target.x < center.x) - return (Quadrant *)macrocell( + if (target.x < center.x) { + return reinterpret_cast(macrocell( level, cell->macrocell.nw, cell->macrocell.ne, set_rec(current, level, cell->macrocell.sw, target, state), - cell->macrocell.se); - else - { + cell->macrocell.se)); + } else { current.x = center.x; - return (Quadrant *)macrocell( + return reinterpret_cast(macrocell( level, cell->macrocell.nw, cell->macrocell.ne, cell->macrocell.sw, - set_rec(current, level, cell->macrocell.se, target, state)); + set_rec(current, level, cell->macrocell.se, target, state))); } } } } -CellState *HashlifeUniverse::find(Coord target) const -{ - Quadrant *cell = (Quadrant *)root; +CellState *HashlifeUniverse::find(Coord target) const { + Quadrant *cell = reinterpret_cast(root); Coord size(top_level - 1); Coord current(top_left); Coord center = current + size; - for (size_t level = top_level; level > 1; --level) - { - if (target.y < center.y) - { - if (target.x < center.x) - { + for (size_t level = top_level; level > 1; --level) { + if (target.y < center.y) { + if (target.x < center.x) { cell = cell->macrocell.nw; - } - else - { + } else { current.x = center.x; cell = cell->macrocell.ne; } - } - else - { + } else { current.y = center.y; - if (target.x < center.x) - { + if (target.x < center.x) { cell = cell->macrocell.sw; - } - else - { + } else { current.x = center.x; cell = cell->macrocell.se; } @@ -286,54 +236,39 @@ CellState *HashlifeUniverse::find(Coord target) const center = current + size; } - if (target.y < center.y) - { - if (target.x < center.x) - { + if (target.y < center.y) { + if (target.x < center.x) { return &cell->minicell.nw; } return &cell->minicell.ne; - } - else - { - if (target.x < center.x) - { + } else { + if (target.x < center.x) { return &cell->minicell.sw; } return &cell->minicell.se; } } -CellState *HashlifeUniverse::find_path(Coord coord, vector &path) const -{ - Quadrant *cell = (Quadrant *)root; +CellState *HashlifeUniverse::find_path(Coord coord, + std::vector *path) const { + Quadrant *cell = reinterpret_cast(root); Coord size(top_level - 1); Coord current(top_left); Coord center = current + size; - for (size_t level = top_level; level > 1; --level) - { - path.push_back(cell); - if (coord.x < center.x) - { - if (coord.y < center.y) - { + for (size_t level = top_level; level > 1; --level) { + path->push_back(cell); + if (coord.x < center.x) { + if (coord.y < center.y) { cell = cell->macrocell.nw; - } - else - { + } else { current.y += size.y; cell = cell->macrocell.ne; } - } - else - { + } else { current.x += size.x; - if (coord.y < center.y) - { + if (coord.y < center.y) { cell = cell->macrocell.sw; - } - else - { + } else { current.y += size.y; cell = cell->macrocell.se; } @@ -342,60 +277,51 @@ CellState *HashlifeUniverse::find_path(Coord coord, vector &path) co center = current + size; } - if (coord.y < center.y) - { - if (coord.x < center.x) - { + if (coord.y < center.y) { + if (coord.x < center.x) { return &cell->minicell.nw; } return &cell->minicell.ne; - } - else - { - if (coord.x < center.x) - { + } else { + if (coord.x < center.x) { return &cell->minicell.sw; } return &cell->minicell.se; } } -MiniCell *HashlifeUniverse::minicell() -{ - return (MiniCell *)&*minicells.emplace().first; +MiniCell *HashlifeUniverse::minicell() { + return const_cast( + reinterpret_cast(&*minicells.emplace().first)); } MiniCell *HashlifeUniverse::minicell(CellState nw, CellState ne, CellState sw, - CellState se) -{ - return (MiniCell *)&*minicells.emplace(nw, ne, sw, se).first; + CellState se) { + return const_cast(reinterpret_cast( + &*minicells.emplace(nw, ne, sw, se).first)); } -MacroCell *HashlifeUniverse::macrocell(size_t level) -{ - return (MacroCell *)&*macrocell_sets[level] - .emplace(zeros[level - 1], zeros[level - 1], zeros[level - 1], - zeros[level - 1]) - .first; +MacroCell *HashlifeUniverse::macrocell(size_t level) { + return const_cast(reinterpret_cast( + &*macrocell_sets[level] + .emplace(zeros[level - 1], zeros[level - 1], zeros[level - 1], + zeros[level - 1]) + .first)); } MacroCell *HashlifeUniverse::macrocell(size_t level, Quadrant *nw, Quadrant *ne, - Quadrant *sw, Quadrant *se) -{ - return (MacroCell *)&*macrocell_sets[level].emplace(nw, ne, sw, se).first; + Quadrant *sw, Quadrant *se) { + return const_cast(reinterpret_cast( + &*macrocell_sets[level].emplace(nw, ne, sw, se).first)); } -Quadrant *HashlifeUniverse::quadrant(size_t level) -{ - if (level <= 1) - { - return (Quadrant *)minicell(); - } - else - { - return (Quadrant *)macrocell(level, quadrant(level - 1), - quadrant(level - 1), quadrant(level - 1), - quadrant(level - 1)); +Quadrant *HashlifeUniverse::quadrant(size_t level) { + if (level <= 1) { + return reinterpret_cast(minicell()); + } else { + return reinterpret_cast( + macrocell(level, quadrant(level - 1), quadrant(level - 1), + quadrant(level - 1), quadrant(level - 1))); } } @@ -403,9 +329,7 @@ size_t HashlifeUniverse::get_top_level() { return top_level; } Coord HashlifeUniverse::get_top_left() { return top_left; } -void HashlifeUniverse::crown() -{ - +void HashlifeUniverse::crown() { Quadrant *zero = zeros[top_level - 1]; MacroCell *nw = macrocell(top_level, zero, zero, zero, root->nw); @@ -414,154 +338,117 @@ void HashlifeUniverse::crown() MacroCell *se = macrocell(top_level, root->se, zero, zero, zero); top_level++; - root = macrocell(top_level, - (Quadrant *)nw, (Quadrant *)ne, - (Quadrant *)sw, (Quadrant *)se); + root = macrocell(top_level, reinterpret_cast(nw), + reinterpret_cast(ne), + reinterpret_cast(sw), + reinterpret_cast(se)); } -Quadrant *HashlifeUniverse::result(size_t level, MacroCell *macrocell_tmp) -{ - +Quadrant *HashlifeUniverse::result(size_t level, MacroCell *macrocell_tmp) { if (macrocell_tmp->result != nullptr) return macrocell_tmp->result; - if (level == 2) - { + if (level == 2) { int nb_nw = - macrocell_tmp->nw->minicell.nw + macrocell_tmp->nw->minicell.ne + macrocell_tmp->ne->minicell.nw + - macrocell_tmp->nw->minicell.sw + macrocell_tmp->ne->minicell.sw + - macrocell_tmp->sw->minicell.nw + macrocell_tmp->sw->minicell.ne + macrocell_tmp->se->minicell.nw; + macrocell_tmp->nw->minicell.nw + macrocell_tmp->nw->minicell.ne + + macrocell_tmp->ne->minicell.nw + macrocell_tmp->nw->minicell.sw + + macrocell_tmp->ne->minicell.sw + macrocell_tmp->sw->minicell.nw + + macrocell_tmp->sw->minicell.ne + macrocell_tmp->se->minicell.nw; int nb_ne = - macrocell_tmp->nw->minicell.ne + macrocell_tmp->ne->minicell.nw + macrocell_tmp->ne->minicell.ne + - macrocell_tmp->nw->minicell.se + macrocell_tmp->ne->minicell.se + - macrocell_tmp->sw->minicell.ne + macrocell_tmp->se->minicell.nw + macrocell_tmp->se->minicell.ne; + macrocell_tmp->nw->minicell.ne + macrocell_tmp->ne->minicell.nw + + macrocell_tmp->ne->minicell.ne + macrocell_tmp->nw->minicell.se + + macrocell_tmp->ne->minicell.se + macrocell_tmp->sw->minicell.ne + + macrocell_tmp->se->minicell.nw + macrocell_tmp->se->minicell.ne; int nb_sw = - macrocell_tmp->nw->minicell.sw + macrocell_tmp->nw->minicell.se + macrocell_tmp->ne->minicell.sw + - macrocell_tmp->sw->minicell.nw + macrocell_tmp->se->minicell.nw + - macrocell_tmp->sw->minicell.sw + macrocell_tmp->sw->minicell.se + macrocell_tmp->se->minicell.sw; + macrocell_tmp->nw->minicell.sw + macrocell_tmp->nw->minicell.se + + macrocell_tmp->ne->minicell.sw + macrocell_tmp->sw->minicell.nw + + macrocell_tmp->se->minicell.nw + macrocell_tmp->sw->minicell.sw + + macrocell_tmp->sw->minicell.se + macrocell_tmp->se->minicell.sw; int nb_se = - macrocell_tmp->nw->minicell.se + macrocell_tmp->ne->minicell.sw + macrocell_tmp->ne->minicell.se + - macrocell_tmp->sw->minicell.ne + macrocell_tmp->se->minicell.ne + - macrocell_tmp->sw->minicell.se + macrocell_tmp->se->minicell.sw + macrocell_tmp->se->minicell.se; + macrocell_tmp->nw->minicell.se + macrocell_tmp->ne->minicell.sw + + macrocell_tmp->ne->minicell.se + macrocell_tmp->sw->minicell.ne + + macrocell_tmp->se->minicell.ne + macrocell_tmp->sw->minicell.se + + macrocell_tmp->se->minicell.sw + macrocell_tmp->se->minicell.se; CellState new_nw; CellState new_ne; CellState new_sw; CellState new_se; // I check if the cell is alive - if (macrocell_tmp->nw->minicell.se) - { + if (macrocell_tmp->nw->minicell.se) { // If the cell is alive, i check if cell survive - if ((nb_nw == 2) || (nb_nw == 3)) - { + if ((nb_nw == 2) || (nb_nw == 3)) { new_nw = 1; - } - else - { + } else { new_nw = 0; } - } - else - { + } else { // if the cell is dead, i check if cell born - if (nb_nw == 3) - { + if (nb_nw == 3) { new_nw = 1; - } - else - { + } else { new_nw = 0; } } // I check if the cell is alive - if (macrocell_tmp->ne->minicell.sw) - { + if (macrocell_tmp->ne->minicell.sw) { // If the cell is alive, i check if cell survive - if ((nb_ne == 2) || (nb_ne == 3)) - { + if ((nb_ne == 2) || (nb_ne == 3)) { new_ne = 1; - } - else - { + } else { new_ne = 0; } - } - else - { + } else { // if the cell is dead, i check if cell born - if (nb_ne == 3) - { + if (nb_ne == 3) { new_ne = 1; - } - else - { + } else { new_ne = 0; } } // I check if the cell is alive - if (macrocell_tmp->sw->minicell.ne) - { + if (macrocell_tmp->sw->minicell.ne) { // If the cell is alive, i check if cell survive - if ((nb_sw == 2) || (nb_sw == 3)) - { + if ((nb_sw == 2) || (nb_sw == 3)) { new_sw = 1; - } - else - { + } else { new_sw = 0; } - } - else - { + } else { // if the cell is dead, i check if cell born - if (nb_sw == 3) - { + if (nb_sw == 3) { new_sw = 1; - } - else - { + } else { new_sw = 0; } } // I check if the cell is alive - if (macrocell_tmp->se->minicell.nw) - { + if (macrocell_tmp->se->minicell.nw) { // If the cell is alive, i check if cell survive - if ((nb_se == 2) || (nb_se == 3)) - { + if ((nb_se == 2) || (nb_se == 3)) { new_se = 1; - } - else - { + } else { new_se = 0; } - } - else - { + } else { // if the cell is dead, i check if cell born - if (nb_se == 3) - { + if (nb_se == 3) { new_se = 1; - } - else - { + } else { new_se = 0; } } macrocell_tmp->result = - (Quadrant *)minicell(new_nw, new_ne, new_sw, new_se); + reinterpret_cast(minicell(new_nw, new_ne, new_sw, new_se)); return macrocell_tmp->result; - } - else - { - + } else { // voir figure 4 de : // https://www.drdobbs.com/jvm/an-algorithm-for-compressing-space-and-t/184406478 @@ -569,7 +456,9 @@ Quadrant *HashlifeUniverse::result(size_t level, MacroCell *macrocell_tmp) // je vais faire 6 assemblages différents de macroCell de taille n-2 // afin de pouvoir avoir les 4 carrés centraux (de taille n-2), puis // reconstruire la cellules centrale (n-1). - Quadrant *temp_nw = result(level - 1, (MacroCell *)macrocell_tmp->nw); + + Quadrant *temp_nw = + result(level - 1, reinterpret_cast(macrocell_tmp->nw)); Quadrant *temp_n = result(level - 1, macrocell(level - 1, macrocell_tmp->nw->macrocell.ne, @@ -577,7 +466,8 @@ Quadrant *HashlifeUniverse::result(size_t level, MacroCell *macrocell_tmp) macrocell_tmp->nw->macrocell.se, macrocell_tmp->ne->macrocell.sw)); - Quadrant *temp_ne = result(level - 1, (MacroCell *)macrocell_tmp->ne); + Quadrant *temp_ne = + result(level - 1, reinterpret_cast(macrocell_tmp->ne)); Quadrant *temp_w = result(level - 1, macrocell(level - 1, macrocell_tmp->nw->macrocell.sw, @@ -597,7 +487,8 @@ Quadrant *HashlifeUniverse::result(size_t level, MacroCell *macrocell_tmp) macrocell_tmp->se->macrocell.nw, macrocell_tmp->se->macrocell.ne)); - Quadrant *temp_sw = result(level - 1, (MacroCell *)macrocell_tmp->sw); + Quadrant *temp_sw = + result(level - 1, reinterpret_cast(macrocell_tmp->sw)); Quadrant *temp_s = result(level - 1, macrocell(level - 1, macrocell_tmp->sw->macrocell.ne, @@ -605,7 +496,8 @@ Quadrant *HashlifeUniverse::result(size_t level, MacroCell *macrocell_tmp) macrocell_tmp->sw->macrocell.se, macrocell_tmp->se->macrocell.sw)); - Quadrant *temp_se = result(level - 1, (MacroCell *)macrocell_tmp->se); + Quadrant *temp_se = + result(level - 1, reinterpret_cast(macrocell_tmp->se)); Quadrant *res_nw = result( level - 1, macrocell(level - 1, temp_nw, temp_n, temp_w, temp_c)); @@ -616,23 +508,20 @@ Quadrant *HashlifeUniverse::result(size_t level, MacroCell *macrocell_tmp) Quadrant *res_se = result( level - 1, macrocell(level - 1, temp_c, temp_e, temp_s, temp_se)); - macrocell_tmp->result = - (Quadrant *)macrocell(level - 1, res_nw, res_ne, res_sw, res_se); + macrocell_tmp->result = reinterpret_cast( + macrocell(level - 1, res_nw, res_ne, res_sw, res_se)); return macrocell_tmp->result; } } -void HashlifeUniverse::grid(int *L, int width, Quadrant *r, int level, int x, int y) -{ - if (level == 1) - { +void HashlifeUniverse::grid(int *L, int width, Quadrant *r, int level, int x, + int y) { + if (level == 1) { L[(x) + (width) * (y)] = r->minicell.nw; L[(x + 1) + (width) * (y)] = r->minicell.ne; L[(x) + (width) * (y + 1)] = r->minicell.sw; L[(x + 1) + (width) * (y + 1)] = r->minicell.se; - } - else - { + } else { int dec = 1 << (level - 1); grid(L, width, r->macrocell.nw, level - 1, x, y); grid(L, width, r->macrocell.ne, level - 1, x + dec, y); @@ -641,36 +530,24 @@ void HashlifeUniverse::grid(int *L, int width, Quadrant *r, int level, int x, in } } -void HashlifeUniverse::print_grid(Quadrant *r, size_t level) -{ +void HashlifeUniverse::print_grid(Quadrant *r, size_t level) { int cote = 1 << level; int T[cote * cote]; - grid(T, cote, r, (int)level, 0, 0); + grid(T, cote, r, static_cast(level), 0, 0); - for (int i = 0; i < cote; ++i) - { - for (int j = 0; j < cote; ++j) - { - if (1) - { - if (T[i * cote + j]) - { + for (int i = 0; i < cote; ++i) { + for (int j = 0; j < cote; ++j) { + if (1) { + if (T[i * cote + j]) { printf("# "); - } - else - { + } else { printf(". "); } - } - else - { - if (T[i * cote + j]) - { + } else { + if (T[i * cote + j]) { printf("█▉"); - } - else - { + } else { printf("╶╴"); } } @@ -679,69 +556,65 @@ void HashlifeUniverse::print_grid(Quadrant *r, size_t level) } } -void HashlifeUniverse::get_cell_in_bounds_rec(Rect bounds, vector &coords, size_t current_level, Quadrant *current_cell, Coord current_coord) const -{ - +void HashlifeUniverse::get_cell_in_bounds_rec(Rect bounds, + std::vector *coords, + size_t current_level, + Quadrant *current_cell, + Coord current_coord) const { BigInt x = current_coord.x; BigInt y = current_coord.y; - if (current_level == 1) - { + if (current_level == 1) { MiniCell minicell = current_cell->minicell; - if (bounds.is_in({x, y})) - { + if (bounds.is_in({x, y})) { if (minicell.nw) - coords.push_back({x, y}); + coords->push_back({x, y}); } - if (bounds.is_in({x + 1, y})) - { + if (bounds.is_in({x + 1, y})) { if (minicell.ne) - coords.push_back({x + 1, y}); + coords->push_back({x + 1, y}); } - if (bounds.is_in({x, y + 1})) - { + if (bounds.is_in({x, y + 1})) { if (minicell.sw) - coords.push_back({x, y + 1}); + coords->push_back({x, y + 1}); } - if (bounds.is_in({x + 1, y + 1})) - { + if (bounds.is_in({x + 1, y + 1})) { if (minicell.se) - coords.push_back({x + 1, y + 1}); + coords->push_back({x + 1, y + 1}); } - } - else - { + } else { MacroCell macrocell = current_cell->macrocell; - if (!(macrocell == zeros[current_level]->macrocell)) - { + if (!(macrocell == zeros[current_level]->macrocell)) { BigInt size = BigInt(1) << mp_size_t(current_level - 1); - if (bounds.collides({{x, y}, {x + size, y + size}})) - { - get_cell_in_bounds_rec(bounds, coords, current_level - 1, macrocell.nw, {x, y}); + if (bounds.collides({{x, y}, {x + size, y + size}})) { + get_cell_in_bounds_rec(bounds, coords, current_level - 1, macrocell.nw, + {x, y}); } - if (bounds.collides({{x + size, y}, {x + BigInt(2) * size, y + size}})) - { - get_cell_in_bounds_rec(bounds, coords, current_level - 1, macrocell.ne, {x + size, y}); + if (bounds.collides({{x + size, y}, {x + BigInt(2) * size, y + size}})) { + get_cell_in_bounds_rec(bounds, coords, current_level - 1, macrocell.ne, + {x + size, y}); } - if (bounds.collides({{x, y + size}, {x + size, y + BigInt(2) * size}})) - { - get_cell_in_bounds_rec(bounds, coords, current_level - 1, macrocell.sw, {x, y + size}); + if (bounds.collides({{x, y + size}, {x + size, y + BigInt(2) * size}})) { + get_cell_in_bounds_rec(bounds, coords, current_level - 1, macrocell.sw, + {x, y + size}); } - if (bounds.collides({{x + size, y + size}, {x + BigInt(2) * size, y + BigInt(2) * size}})) - { - get_cell_in_bounds_rec(bounds, coords, current_level - 1, macrocell.se, {x + size, y + size}); + if (bounds.collides({{x + size, y + size}, + {x + BigInt(2) * size, y + BigInt(2) * size}})) { + get_cell_in_bounds_rec(bounds, coords, current_level - 1, macrocell.se, + {x + size, y + size}); } } } } -void HashlifeUniverse::get_cell_in_bounds(Rect bounds, vector &coords) const -{ - get_cell_in_bounds_rec(bounds, coords, top_level, (Quadrant *)root, top_left); +void HashlifeUniverse::get_cell_in_bounds(Rect bounds, + std::vector *coords) const { + get_cell_in_bounds_rec(bounds, coords, top_level, + reinterpret_cast(root), top_left); } diff --git a/src/logic/HashlifeUniverse/HashlifeUniverse.h b/src/logic/HashlifeUniverse/HashlifeUniverse.h new file mode 100644 index 0000000..2b65c45 --- /dev/null +++ b/src/logic/HashlifeUniverse/HashlifeUniverse.h @@ -0,0 +1,85 @@ +#ifndef HASHLIFE_UNIVERSE_HPP +#define HASHLIFE_UNIVERSE_HPP + +#include +#include +// #include +#include +#include + +#include + +#include +#include +#include +#include +#include + +class HashlifeUniverse : public Universe { +public: + explicit HashlifeUniverse(size_t top_level, Coord top_left = Coord()); + explicit HashlifeUniverse(QString filename, Coord top_left = Coord()); + + void step(); + const CellState get(Coord coord) const; + void set(Coord target, CellState state); + void debug(); + + void get_cell_in_bounds(Rect bounds, std::vector *coords) const; + /* + class Iterator; + Iterator iter(Rect bounds); + */ + + Coord get_top_left(); + size_t get_top_level(); + + void grid(int *L, int width, Quadrant *r, int level, int x, int y); + void print_grid(Quadrant *r, size_t level); + +private: + size_t top_level; + Coord top_left; + MacroCell *root; + + std::vector> macrocell_sets; + std::unordered_set minicells; + std::vector zeros; + + // File loading + Coord read_rle_size(QFile *file); + void read_rle_data(QFile *file, Coord boundingbox); + + // TODO(chancyleg): find good name + void assert_handles(size_t asserted_level); + + // Step helpers + void crown(); + Quadrant *result(size_t level, MacroCell *macrocell_tmp); + + // Recursive setter + Quadrant *set_rec(Coord current, size_t level, Quadrant *cell, Coord target, + CellState state); + + // Finding + CellState *find(Coord) const; + CellState *find_path(Coord coord, std::vector *path) const; + + // Minicells + MiniCell *minicell(); + MiniCell *minicell(CellState nw, CellState ne, CellState sw, CellState se); + + // Macrocells + MacroCell *macrocell(size_t level); + MacroCell *macrocell(size_t level, Quadrant *nw, Quadrant *ne, Quadrant *sw, + Quadrant *se); + + // Quadrant + Quadrant *quadrant(size_t level); + + void get_cell_in_bounds_rec(Rect bounds, std::vector *coords, + size_t current_level, Quadrant *current_cell, + Coord current_coord) const; +}; + +#endif // HASHLIFE_UNIVERSE_HPP diff --git a/src/logic/HashlifeUniverse/HashlifeUniverse.hpp b/src/logic/HashlifeUniverse/HashlifeUniverse.hpp deleted file mode 100644 index 0b2cf17..0000000 --- a/src/logic/HashlifeUniverse/HashlifeUniverse.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef HASHLIFE_UNIVERSE_HPP -#define HASHLIFE_UNIVERSE_HPP - -#include -#include -// #include -#include -#include - -#include - -#include -#include -#include -#include -#include - -using namespace std; - -class HashlifeUniverse: public Universe { -public: - HashlifeUniverse(size_t top_level, Coord top_left = Coord()); - HashlifeUniverse(QString filename, Coord top_left = Coord()); - - void step(); - const CellState get(Coord coord) const; - void set(Coord target, CellState state); - void debug(); - - - void get_cell_in_bounds(Rect bounds, vector &coords) const; -/* - class Iterator; - Iterator iter(Rect bounds); -*/ - - - Coord get_top_left(); - size_t get_top_level(); - - - void grid(int *L, int width, Quadrant* r, int level, int x, int y); - void print_grid(Quadrant* r, size_t level); -private: - size_t top_level; - Coord top_left; - MacroCell *root; - - vector> macrocell_sets; - unordered_set minicells; - vector zeros; - - - // File loading - Coord read_rle_size(QFile &file); - void read_rle_data(QFile &file, Coord boundingbox); - - // TODO find good name - void assert_handles(size_t asserted_level); - - // Step helpers - void crown(); - Quadrant* result(size_t level, MacroCell* macrocell_tmp); - - - // Recursive setter - Quadrant *set_rec(Coord current, size_t level, Quadrant *cell, Coord target, CellState state); - - // Finding - CellState *find(Coord) const; - CellState *find_path(Coord coord, vector &path) const; - - // Minicells - MiniCell *minicell(); - MiniCell *minicell(CellState nw, CellState ne, - CellState sw, CellState se); - - // Macrocells - MacroCell *macrocell(size_t level); - MacroCell *macrocell(size_t level, - Quadrant *nw, Quadrant *ne, - Quadrant *sw, Quadrant *se); - - // Quadrant - Quadrant *quadrant(size_t level); - - - void get_cell_in_bounds_rec(Rect bounds, vector &coords, size_t current_level, Quadrant* current_cell, Coord current_coord) const; -}; - -#endif // HASHLIFE_UNIVERSE_HPP diff --git a/src/logic/HashlifeUniverse/cell/MacroCell.cpp b/src/logic/HashlifeUniverse/cell/MacroCell.cpp index fd29968..2d53281 100644 --- a/src/logic/HashlifeUniverse/cell/MacroCell.cpp +++ b/src/logic/HashlifeUniverse/cell/MacroCell.cpp @@ -1,15 +1,13 @@ -#include "MacroCell.hpp" - -MacroCell::MacroCell(Quadrant *nw, Quadrant *ne, - Quadrant *sw, Quadrant *se) - : nw(nw), ne(ne), sw(sw), se(se), result(nullptr) {} +#include +MacroCell::MacroCell(Quadrant *nw, Quadrant *ne, Quadrant *sw, Quadrant *se) + : nw(nw), ne(ne), sw(sw), se(se), result(nullptr) {} bool MacroCell::operator==(const MacroCell other) const { return nw == other.nw && ne == other.ne && sw == other.sw && se == other.se; } -Quadrant* MacroCell::operator[](const size_t index) const { +Quadrant *MacroCell::operator[](const size_t index) const { switch (index) { case 0: return nw; @@ -19,5 +17,5 @@ Quadrant* MacroCell::operator[](const size_t index) const { return sw; default: return se; - }; + } } diff --git a/src/logic/HashlifeUniverse/cell/MacroCell.h b/src/logic/HashlifeUniverse/cell/MacroCell.h new file mode 100644 index 0000000..2e974c9 --- /dev/null +++ b/src/logic/HashlifeUniverse/cell/MacroCell.h @@ -0,0 +1,36 @@ +#ifndef MACROCELL_H +#define MACROCELL_H + +#include + +#include + +union Quadrant; + +class MacroCell { +public: + MacroCell(Quadrant *nw, Quadrant *ne, Quadrant *sw, Quadrant *se); + + bool operator==(const MacroCell other) const; + Quadrant *operator[](const size_t index) const; + + friend std::hash; + friend Quadrant; + + Quadrant *result; + Quadrant *nw, *ne; + Quadrant *sw, *se; +}; + +// Defining default hashers +namespace std { +template <> struct hash { + size_t operator()(const MacroCell ¯ocell) const { + return hasher(macrocell.nw) ^ hasher(macrocell.ne) ^ hasher(macrocell.sw) ^ + hasher(macrocell.se); + } + hash hasher; +}; +} // namespace std + +#endif // MACROCELL_H diff --git a/src/logic/HashlifeUniverse/cell/MacroCell.hpp b/src/logic/HashlifeUniverse/cell/MacroCell.hpp deleted file mode 100644 index 6887901..0000000 --- a/src/logic/HashlifeUniverse/cell/MacroCell.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef MACROCELL_H -#define MACROCELL_H - -#include - -#include - -union Quadrant; - -class MacroCell { -public: - MacroCell(Quadrant *nw, Quadrant *ne, - Quadrant *sw, Quadrant *se); - - bool operator==(const MacroCell other) const; - Quadrant* operator[](const size_t index) const; - - friend std::hash; - friend Quadrant; - - Quadrant *result; - Quadrant *nw, *ne; - Quadrant *sw, *se; -}; - - -// Defining default hashers -namespace std { - template <> - struct hash { - size_t operator()(const MacroCell ¯ocell) const { - return hasher(macrocell.nw) ^ hasher(macrocell.ne) ^ - hasher(macrocell.sw) ^ hasher(macrocell.se); - } - hash hasher; - }; -} - -#endif // MACROCELL_H diff --git a/src/logic/HashlifeUniverse/cell/MiniCell.cpp b/src/logic/HashlifeUniverse/cell/MiniCell.cpp index 5a5aa7d..4a4950b 100644 --- a/src/logic/HashlifeUniverse/cell/MiniCell.cpp +++ b/src/logic/HashlifeUniverse/cell/MiniCell.cpp @@ -1,7 +1,7 @@ -#include "MiniCell.hpp" +#include MiniCell::MiniCell(CellState nw, CellState ne, CellState sw, CellState se) - : nw(nw), ne(ne), se(se), sw(sw) {} + : nw(nw), ne(ne), se(se), sw(sw) {} bool MiniCell::operator==(const MiniCell other) const { return nw == other.nw && ne == other.ne && sw == other.sw && se == other.se; diff --git a/src/logic/HashlifeUniverse/cell/MiniCell.hpp b/src/logic/HashlifeUniverse/cell/MiniCell.h similarity index 60% rename from src/logic/HashlifeUniverse/cell/MiniCell.hpp rename to src/logic/HashlifeUniverse/cell/MiniCell.h index 5150097..f7f9c6a 100644 --- a/src/logic/HashlifeUniverse/cell/MiniCell.hpp +++ b/src/logic/HashlifeUniverse/cell/MiniCell.h @@ -3,7 +3,7 @@ #include -#include "../../CellState.hpp" +#include union Quadrant; @@ -23,17 +23,16 @@ class MiniCell { }; namespace std { - template <> - struct hash { - hash() = default; +template <> struct hash { + hash() = default; - size_t operator()(const MiniCell &minicell) const { - return hasher(minicell.nw) ^ hasher(minicell.ne) - ^ hasher(minicell.sw) ^ hasher(minicell.se); - } + size_t operator()(const MiniCell &minicell) const { + return hasher(minicell.nw) ^ hasher(minicell.ne) ^ hasher(minicell.sw) ^ + hasher(minicell.se); + } - hash hasher; - }; + hash hasher; +}; } // namespace std #endif // MINICELL_HPP diff --git a/src/logic/HashlifeUniverse/cell/Quadrant.cpp b/src/logic/HashlifeUniverse/cell/Quadrant.cpp index 3d96aa5..253a771 100644 --- a/src/logic/HashlifeUniverse/cell/Quadrant.cpp +++ b/src/logic/HashlifeUniverse/cell/Quadrant.cpp @@ -1,40 +1,45 @@ -#include "Quadrant.hpp" +#include Quadrant *Quadrant::generate(size_t level) { if (level <= 1) { - return (Quadrant*) new MiniCell; + return reinterpret_cast(new MiniCell); } else { - return (Quadrant*)new MacroCell(generate(level - 1), generate(level - 1), - generate(level - 1), generate(level - 1)); + return reinterpret_cast( + new MacroCell(generate(level - 1), generate(level - 1), + generate(level - 1), generate(level - 1))); } } Quadrant *Quadrant::generate_random(size_t level, CellState max_value) { std::random_device undeterministic_generator; - std::default_random_engine deterministic_generator(undeterministic_generator()); + std::default_random_engine deterministic_generator( + undeterministic_generator()); std::uniform_int_distribution range(0, max_value); return raw_generate_random(level, deterministic_generator, range); } -Quadrant *Quadrant::raw_generate_random(size_t level, - std::default_random_engine random_engine, - std::uniform_int_distribution range) { +Quadrant * +Quadrant::raw_generate_random(size_t level, + std::default_random_engine random_engine, + std::uniform_int_distribution range) { if (level <= 1) { - return (Quadrant *)new MiniCell(range(random_engine), range(random_engine), - range(random_engine), range(random_engine)); + return reinterpret_cast( + new MiniCell(range(random_engine), range(random_engine), + range(random_engine), range(random_engine))); } else { - return (Quadrant *)new MacroCell(raw_generate_random(level - 1, random_engine, range), - raw_generate_random(level - 1, random_engine, range), - raw_generate_random(level - 1, random_engine, range), - raw_generate_random(level - 1, random_engine, range)); + return reinterpret_cast( + new MacroCell(raw_generate_random(level - 1, random_engine, range), + raw_generate_random(level - 1, random_engine, range), + raw_generate_random(level - 1, random_engine, range), + raw_generate_random(level - 1, random_engine, range))); } } void Quadrant::debug_rec(size_t level, std::string indentation) { if (level <= 1) { - std::cout << indentation << "(Quadrant *) new MiniCell(" << minicell.nw << ", " - << minicell.ne << ", " << minicell.sw << ", " << minicell.se - << ")"; + std::cout << indentation << "(Quadrant *) new MiniCell(" << minicell.nw + << ", " << minicell.ne << ", " << minicell.sw << ", " + << minicell.se << ")"; } else { std::cout << indentation << "(Quadrant *) new MacroCell(\n"; macrocell.nw->debug_rec(level - 1, indentation + " "); @@ -50,7 +55,7 @@ void Quadrant::debug_rec(size_t level, std::string indentation) { void Quadrant::debug(size_t level) { Quadrant::debug_rec(level, ""); } -Quadrant* Quadrant::operator[](const size_t index) const { +Quadrant *Quadrant::operator[](const size_t index) const { switch (index) { case 0: return macrocell.nw; diff --git a/src/logic/HashlifeUniverse/cell/Quadrant.hpp b/src/logic/HashlifeUniverse/cell/Quadrant.h similarity index 79% rename from src/logic/HashlifeUniverse/cell/Quadrant.hpp rename to src/logic/HashlifeUniverse/cell/Quadrant.h index 2a47521..5044843 100644 --- a/src/logic/HashlifeUniverse/cell/Quadrant.hpp +++ b/src/logic/HashlifeUniverse/cell/Quadrant.h @@ -5,15 +5,15 @@ #include #include -#include "MiniCell.hpp" -#include "MacroCell.hpp" +#include +#include union Quadrant { public: MiniCell minicell; MacroCell macrocell; - Quadrant* operator[](const size_t index) const; + Quadrant *operator[](const size_t index) const; void debug(size_t level); diff --git a/src/logic/LifeFile.hpp b/src/logic/LifeFile.h similarity index 59% rename from src/logic/LifeFile.hpp rename to src/logic/LifeFile.h index fde57f9..e107251 100644 --- a/src/logic/LifeFile.hpp +++ b/src/logic/LifeFile.h @@ -4,20 +4,20 @@ #include #include -#include "CellState.hpp" -#include "Coord.hpp" -#include "Rect.hpp" -#include "Rule.hpp" +#include +#include +#include +#include class LifeFile { public: - LifeFile(QFile *file); + explicit LifeFile(QFile *file); class Iterator { public: - Iterator(QFile *file); + explicit Iterator(QFile *file); - bool next(CellState& state); + bool next(const CellState &state); }; Iterator iterate(QFile *file) const; diff --git a/src/logic/RLE/RLE.cpp b/src/logic/RLE/RLE.cpp index 8a0318c..0b77f92 100644 --- a/src/logic/RLE/RLE.cpp +++ b/src/logic/RLE/RLE.cpp @@ -1,7 +1,5 @@ - +#include /* -#include "RLE.hpp" - RLE::RLE(QFile *_file): file(_file) { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) throw "File could not be opened"; @@ -40,4 +38,4 @@ QFile RLE::get_file_at_data() { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) throw "File could not be opened"; } -*/ \ No newline at end of file +*/ diff --git a/src/logic/RLE/RLE.hpp b/src/logic/RLE/RLE.h similarity index 67% rename from src/logic/RLE/RLE.hpp rename to src/logic/RLE/RLE.h index 366b981..d8e1ac7 100644 --- a/src/logic/RLE/RLE.hpp +++ b/src/logic/RLE/RLE.h @@ -1,28 +1,26 @@ #ifndef RLE_HPP #define RLE_HPP -#include "../CellState.hpp" -#include "../Coord.hpp" -#include "../LifeFile.hpp" -#include "../Rect.hpp" -#include "../Rule.hpp" +#include +#include +#include +#include +#include -#include #include - -using namespace std; +#include class RLE { public: // Constructors - RLE(QFile *file); + explicit RLE(QFile *file); // Iterator class Iterator { public: - Iterator(QFile *file); + explicit Iterator(QFile *file); - bool next(CellState &state); + bool next(const CellState &state); private: QFile *file; diff --git a/src/logic/RLE/RLERule.cpp b/src/logic/RLE/RLERule.cpp index 94b6f71..61e5a56 100644 --- a/src/logic/RLE/RLERule.cpp +++ b/src/logic/RLE/RLERule.cpp @@ -1,6 +1,6 @@ -#include "RLERule.hpp" -#include "../CellState.hpp" #include +#include +#include enum ReadingState { B_SEARCH, B_VALUES, S_SEARCH, S_VALUES }; @@ -32,18 +32,19 @@ RLERule::RLERule(QString rule_string) { case B_SEARCH: if (c == 'B') state = B_VALUES; - else throw "RLERule strings should start with B"; + else + throw "RLERule strings should start with B"; break; case B_VALUES: if ('0' < c && c < '8') { - size_t index = c.toLatin1() - '0'; + size_t index = c.toLatin1() - '0'; transition[0][index] = 1; - } - else if (c == '/'){ + } else if (c == '/') { state = S_SEARCH; + } else { + throw "Birth values should be between 0 and 8"; } - else throw "Birth values should be between 0 and 8"; break; case S_SEARCH: @@ -57,8 +58,9 @@ RLERule::RLERule(QString rule_string) { if ('0' < c && c < '8') { size_t index = c.toLatin1() - '0'; transition[1][index] = 1; - } else + } else { throw "Survival values should be between 0 and 8"; + } break; } } @@ -66,7 +68,6 @@ RLERule::RLERule(QString rule_string) { throw "Incomplete rule string"; } - CellState RLERule::apply(CellState state, size_t neighbour_count) const { return transition[state][neighbour_count]; } diff --git a/src/logic/RLE/RLERule.hpp b/src/logic/RLE/RLERule.h similarity index 79% rename from src/logic/RLE/RLERule.hpp rename to src/logic/RLE/RLERule.h index 10045cc..ee7fc07 100644 --- a/src/logic/RLE/RLERule.hpp +++ b/src/logic/RLE/RLERule.h @@ -1,14 +1,14 @@ #ifndef RLE_RULE_HPP #define RLE_RULE_HPP -#include "../CellState.hpp" +#include #include class RLERule { public: RLERule() = default; - RLERule(QString rule_string); + explicit RLERule(QString rule_string); QString to_qstring() const; diff --git a/src/logic/Rect.cpp b/src/logic/Rect.cpp index 53424f6..6accf26 100644 --- a/src/logic/Rect.cpp +++ b/src/logic/Rect.cpp @@ -1,23 +1,21 @@ -#include "Rect.hpp" +#include Rect::Rect(Coord top_left, Coord bottom_right) - : top_left(top_left), bottom_right(bottom_right) {} + : top_left(top_left), bottom_right(bottom_right) {} bool Rect::is_in(Coord coord) const { - return (top_left.x <= coord.x && - top_left.y <= coord.y && - coord.x < bottom_right.x && - coord.y < bottom_right.y); + return (top_left.x <= coord.x && top_left.y <= coord.y && + coord.x < bottom_right.x && coord.y < bottom_right.y); } bool Rect::collides(Rect rect) const { - return (rect.top_left.x < bottom_right.x && - rect.bottom_right.x >= top_left.x && - rect.top_left.y < bottom_right.y && - rect.bottom_right.y >= top_left.y ); + return ( + rect.top_left.x < bottom_right.x && rect.bottom_right.x >= top_left.x && + rect.top_left.y < bottom_right.y && rect.bottom_right.y >= top_left.y); } bool Rect::does_not_collide(Rect rect) const { - return (rect.top_left.x >= bottom_right.x || rect.bottom_right.x < top_left.x || - rect.top_left.y >= bottom_right.y || rect.bottom_right.y < top_left.y); + return ( + rect.top_left.x >= bottom_right.x || rect.bottom_right.x < top_left.x || + rect.top_left.y >= bottom_right.y || rect.bottom_right.y < top_left.y); } diff --git a/src/logic/Rect.hpp b/src/logic/Rect.h similarity index 92% rename from src/logic/Rect.hpp rename to src/logic/Rect.h index e1a1543..47c4886 100644 --- a/src/logic/Rect.hpp +++ b/src/logic/Rect.h @@ -1,7 +1,7 @@ #ifndef RECT_HPP #define RECT_HPP -#include "Coord.hpp" +#include class Rect { public: diff --git a/src/logic/Rule.hpp b/src/logic/Rule.h similarity index 85% rename from src/logic/Rule.hpp rename to src/logic/Rule.h index 6efbb7e..223c4d8 100644 --- a/src/logic/Rule.hpp +++ b/src/logic/Rule.h @@ -1,8 +1,8 @@ #ifndef RULE_HPP #define RULE_HPP -#include "CellState.hpp" #include +#include class Rule { virtual CellState apply(CellState state, size_t neighbout_count) const; diff --git a/src/logic/Universe.cpp b/src/logic/Universe.cpp index ad09b8f..0d3ae31 100644 --- a/src/logic/Universe.cpp +++ b/src/logic/Universe.cpp @@ -1,19 +1,17 @@ -#include "Universe.hpp" -#include "LifeFile.hpp" +#include +#include Universe::Universe(Rect bounds) : bounds(bounds), generation_count(0) {} // This is just an alias of the above Universe::Universe(Coord size) : Universe({Coord(), size}) {} -Universe::Universe(QString filename, Coord top_left): generation_count(0) {} +Universe::Universe(QString filename, Coord top_left) : generation_count(0) {} -Universe::Universe(size_t top_level, Coord top_left):generation_count(0) {} +Universe::Universe(size_t top_level, Coord top_left) : generation_count(0) {} Universe::~Universe() {} Rect Universe::get_bounds() const { return bounds; } BigInt Universe::get_generation() const { return generation_count; } - - diff --git a/src/logic/Universe.h b/src/logic/Universe.h new file mode 100644 index 0000000..6062200 --- /dev/null +++ b/src/logic/Universe.h @@ -0,0 +1,46 @@ +#ifndef UNIVERSE_HPP +#define UNIVERSE_HPP + +#include +#include +#include +#include +#include +#include + +// Universal Universe interface +class Universe { +public: + explicit Universe(Rect bounds); + explicit Universe(QString filename, Coord top_left); + explicit Universe(Coord size = Coord(8, 8)); + Universe(size_t top_level, Coord top_left); + virtual ~Universe(); + + // Makes a step in the simulation + virtual void step() = 0; + + // Universe interaction + virtual void set(Coord, CellState) = 0; + virtual const CellState get(Coord coord) const = 0; + + // virtual void get_cell_in_bounds(Rect bounds, vector coords, + // vector cell_states) const = 0; + + /* + class Iterator { + virtual bool next(Coord &coord, CellState &state) = 0; + }; + + virtual Iterator iterate(Rect bounds) const = 0; + */ + + // Getters + Rect get_bounds() const; + BigInt get_generation() const; + + BigInt generation_count; + Rect bounds; +}; + +#endif // UNIVERSE_HPP diff --git a/src/logic/Universe.hpp b/src/logic/Universe.hpp deleted file mode 100644 index 9c3d24a..0000000 --- a/src/logic/Universe.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef UNIVERSE_HPP -#define UNIVERSE_HPP - -#include "CellState.hpp" -#include "Coord.hpp" -#include "LifeFile.hpp" -#include "Rect.hpp" -#include -#include "RLE/RLE.hpp" - -using namespace std; - -// Universal Universe interface -class Universe { -public: - Universe(Rect bounds); - Universe(QString filename, Coord top_left = 0); - Universe(Coord size = Coord(8, 8)); - Universe(size_t top_level, Coord top_left); - virtual ~Universe(); - - // Makes a step in the simulation - virtual void step() = 0; - - // Universe interaction - virtual void set(Coord, CellState) = 0; - virtual const CellState get(Coord coord) const = 0; - - //virtual void get_cell_in_bounds(Rect bounds, vector coords, vector cell_states) const = 0; - -/* - class Iterator { - virtual bool next(Coord &coord, CellState &state) = 0; - }; - - virtual Iterator iterate(Rect bounds) const = 0; -*/ - - // Getters - Rect get_bounds() const; - BigInt get_generation() const; - - BigInt generation_count; - Rect bounds; -}; - -#endif // UNIVERSE_HPP diff --git a/src/main.cpp b/src/main.cpp index 2539732..99c0dff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,15 +1,13 @@ -#include "ui/MainWindow.h" +#include #include int main(int argc, char **argv) { - QCoreApplication::setApplicationName("aging"); QCoreApplication::setOrganizationName("aging-team"); - QApplication app(argc,argv); + QApplication app(argc, argv); MainWindow window; window.show(); return app.exec(); - } diff --git a/src/ui/Camera2D.cpp b/src/ui/Camera2D.cpp index 9ec9f04..031d185 100644 --- a/src/ui/Camera2D.cpp +++ b/src/ui/Camera2D.cpp @@ -1,71 +1,76 @@ -#include "Camera2D.h" -#include #include +#include +#include -Camera2D::Camera2D(void) -:zoom(1), pos(0.0f,0.0f), origin(0.0f,0.0f) -{ - transform.update(pos,origin,zoom); +Camera2D::Camera2D(void) : zoom(1), pos(0.0f, 0.0f), origin(0.0f, 0.0f) { + transform.update(pos, origin, zoom); - generate_view_matrix(); + generate_view_matrix(); } void Camera2D::set_zoom(const int n_zoom) { - zoom = n_zoom; - zoom = zoom < 1.0f ? 1.0f : zoom; -} -int Camera2D::get_zoom() const { - return zoom; + zoom = n_zoom; + zoom = zoom < 1.0f ? 1.0f : zoom; } +int Camera2D::get_zoom() const { return zoom; } + QMatrix4x4 Camera2D::get_view() { + bool dirty = false; - bool dirty = false; + if (transform.last_pos != pos) { + dirty = true; + } else if (transform.last_origin != origin) { + dirty = true; + } else if (transform.last_zoom != zoom) { + dirty = true; + } - if (transform.last_pos != pos) { dirty = true; } - else if (transform.last_origin != origin) { dirty = true; } - else if (transform.last_zoom != zoom) { dirty = true; } - if (dirty) generate_view_matrix(); - return transform.matrix; + if (dirty) + generate_view_matrix(); + return transform.matrix; } -void Camera2D::Transformation::update(const QVector2D& p, const QVector2D& origin, const int zoom) { - last_pos = p; - last_zoom = zoom; - last_origin = origin; +void Camera2D::Transformation::update(const QVector2D &p, + const QVector2D &origin, const int zoom) { + last_pos = p; + last_zoom = zoom; + last_origin = origin; } void Camera2D::generate_view_matrix() { + transform.update(pos, origin, zoom); - transform.update(pos,origin,zoom); - - transform.matrix.setToIdentity(); - transform.matrix.translate(-pos.x(),-pos.y(),0); - transform.matrix.scale(1.0f/zoom, 1.0f/zoom, 1); - transform.matrix.translate(origin.x(),origin.y(),0); - + transform.matrix.setToIdentity(); + transform.matrix.translate(-pos.x(), -pos.y(), 0); + transform.matrix.scale(1.0f / zoom, 1.0f / zoom, 1); + transform.matrix.translate(origin.x(), origin.y(), 0); } Rect Camera2D::get_view_bounds(float aspect_ratio, Universe *universe) { + bool invertible; + QMatrix4x4 inv = get_view().inverted(&invertible); + if (!invertible) + std::cout << "Non-invertible view matrix" << '\n'; - bool invertible; - QMatrix4x4 inv = get_view().inverted(&invertible); - if(!invertible) - std::cout << "Non-invertible view matrix" << '\n'; - - QRectF rectf = inv.mapRect(QRectF(QPointF(0.0f,0.0f),QPointF(1.0f * aspect_ratio,1.0f))); + QRectF rectf = inv.mapRect( + QRectF(QPointF(0.0f, 0.0f), QPointF(1.0f * aspect_ratio, 1.0f))); - Coord top_left = Coord(BigInt((int) std::ceil(rectf.topLeft().x()) - 1), BigInt((int) std::ceil(rectf.bottomRight().y()))); - Coord bottom_right = Coord(BigInt((int) std::ceil(rectf.bottomRight().x())), BigInt((int) std::ceil(rectf.topLeft().y()))); + Coord top_left = + Coord(BigInt(static_cast(std::ceil(rectf.topLeft().x())) - 1), + BigInt(static_cast(std::ceil(rectf.bottomRight().y())))); + Coord bottom_right = + Coord(BigInt(static_cast(std::ceil(rectf.bottomRight().x()))), + BigInt(static_cast(std::ceil(rectf.topLeft().y())))); - //top_left.y = (1 << universe->get_top_level()) - top_left.y; - //bottom_right.y = (1 << universe->get_top_level()) - bottom_right.y; + // top_left.y = (1 << universe->get_top_level()) - top_left.y; + // bottom_right.y = (1 << universe->get_top_level()) - bottom_right.y; - BigInt diff_y = bottom_right.y - top_left.y; + BigInt diff_y = bottom_right.y - top_left.y; - top_left.y *= -1; - bottom_right.y = top_left.y - diff_y + 2; + top_left.y *= -1; + bottom_right.y = top_left.y - diff_y + 2; - Rect rect(top_left,bottom_right); - return rect; + Rect rect(top_left, bottom_right); + return rect; } diff --git a/src/ui/Camera2D.h b/src/ui/Camera2D.h index af132d3..d6715ab 100644 --- a/src/ui/Camera2D.h +++ b/src/ui/Camera2D.h @@ -1,39 +1,35 @@ #ifndef UI_CAMERA2D_H_ #define UI_CAMERA2D_H_ +#include +#include #include #include -#include "../logic/Rect.hpp" -#include "../logic/Universe.hpp" class Camera2D { - public: - Camera2D(void); - void set_zoom(const int n_zoom); - int get_zoom() const; - QMatrix4x4 get_view(); + Camera2D(void); + void set_zoom(const int n_zoom); + int get_zoom() const; + QMatrix4x4 get_view(); - Rect get_view_bounds(float aspect_ratio, Universe *universe); - QVector2D pos; - QVector2D origin; - + Rect get_view_bounds(float aspect_ratio, Universe *universe); + QVector2D pos; + QVector2D origin; protected: - void generate_view_matrix(); - - struct Transformation - { - QMatrix4x4 matrix; - QVector2D last_pos; - int last_zoom; - QVector2D last_origin; - void update(const QVector2D& p, const QVector2D& origin, const int zoom); - }; - - int zoom; - Transformation transform; + void generate_view_matrix(); + + struct Transformation { + QMatrix4x4 matrix; + QVector2D last_pos; + int last_zoom; + QVector2D last_origin; + void update(const QVector2D &p, const QVector2D &origin, const int zoom); + }; + + int zoom; + Transformation transform; }; - #endif /* UI_CAMERA2D_H_ */ diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp index 9b34848..c1f5219 100644 --- a/src/ui/MainWindow.cpp +++ b/src/ui/MainWindow.cpp @@ -1,200 +1,191 @@ -#include "MainWindow.h" -#include "../logic/Universe.hpp" -#include "../logic/HashlifeUniverse/HashlifeUniverse.hpp" +#include +#include +#include -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include MainWindow::MainWindow() { - - this->resize(720, 720); - this->setFocusPolicy(Qt::FocusPolicy::ClickFocus); - - simulationRunning = false; - /* - game = new Game(100,100); - - CellMap *map = game->getMap(); - for (size_t c = 0; c < map->getWidth(); ++c) - for (size_t l = 0; l < map->getHeight(); ++l) - map->changeCellState(c,l,c % 3); - */ - game = nullptr; - hashlife_universe = new HashlifeUniverse(3); - - hashlife_universe->set(Coord(0,0),1); - hashlife_universe->set(Coord(0,7),1); - hashlife_universe->set(Coord(7,0),1); - hashlife_universe->set(Coord(7,7),1); - - createUI(); - stepTimer = new QTimer(this); - connect(stepTimer, &QTimer::timeout, this, &MainWindow::stepSimulation); + this->resize(720, 720); + this->setFocusPolicy(Qt::FocusPolicy::ClickFocus); + + simulationRunning = false; + /* + game = new Game(100,100); + + CellMap *map = game->getMap(); + for (size_t c = 0; c < map->getWidth(); ++c) + for (size_t l = 0; l < map->getHeight(); ++l) + map->changeCellState(c,l,c % 3); + */ + game = nullptr; + hashlife_universe = new HashlifeUniverse(3); + + hashlife_universe->set(Coord(0, 0), 1); + hashlife_universe->set(Coord(0, 7), 1); + hashlife_universe->set(Coord(7, 0), 1); + hashlife_universe->set(Coord(7, 7), 1); + + createUI(); + stepTimer = new QTimer(this); + connect(stepTimer, &QTimer::timeout, this, &MainWindow::stepSimulation); } void MainWindow::createUI() { - - updateStatusBar(); - - //Render Area - r_area = new RenderArea(this,hashlife_universe); - setCentralWidget(r_area); - - r_area->setCursor(Qt::ArrowCursor); - - //Simulation control toolbar - QToolBar *controlToolbar = addToolBar("Simulation Controls"); - addToolBar(Qt::LeftToolBarArea, controlToolbar); - playIcon = new QIcon("../res/icons/play.svg"); - pauseIcon = new QIcon("../res/icons/pause.svg"); - playPauseAction = controlToolbar->addAction(*playIcon,"Play/Pause"); - QIcon *stepIcon = new QIcon("../res/icons/step.svg"); - QAction *stepAction = controlToolbar->addAction(*stepIcon,"Advance one step"); - - connect(playPauseAction, &QAction::triggered, this, &MainWindow::playPause); - connect(stepAction, &QAction::triggered, this, &MainWindow::stepSimulation); - - //Control toolbox - QToolBar *toolboxToolbar = addToolBar("Toolbox"); - QButtonGroup *toolboxGroup = new QButtonGroup(); - toolboxGroup->setExclusive(true); - addToolBar(Qt::LeftToolBarArea, toolboxToolbar); - - pencilButton = new QToolButton(toolboxToolbar); - pencilButton->setIcon(QIcon("../res/icons/pencil.svg")); - pencilButton->setCheckable(true); - toolboxGroup->addButton(pencilButton); - toolboxToolbar->addWidget(pencilButton); - - eraserButton = new QToolButton(toolboxToolbar); - eraserButton->setIcon(QIcon("../res/icons/eraser.svg")); - eraserButton->setCheckable(true); - toolboxGroup->addButton(eraserButton); - toolboxToolbar->addWidget(eraserButton); - - zoominButton = new QToolButton(toolboxToolbar); - zoominButton->setIcon(QIcon("../res/icons/zoom-in.svg")); - zoominButton->setCheckable(true); - toolboxGroup->addButton(zoominButton); - toolboxToolbar->addWidget(zoominButton); - - zoomoutButton = new QToolButton(toolboxToolbar); - zoomoutButton->setIcon(QIcon("../res/icons/zoom-out.svg")); - zoomoutButton->setCheckable(true); - toolboxGroup->addButton(zoomoutButton); - toolboxToolbar->addWidget(zoomoutButton); - - - //Menu Bar - QMenu *fileMenu = new QMenu("File"); - QMenu *prefMenu = new QMenu("Preferences"); - QAction *loadAction = fileMenu->addAction("Load pattern"); - QAction *changeColorsAction = prefMenu->addAction("Choose colors"); - - connect(loadAction, &QAction::triggered, this, &MainWindow::load); - connect(changeColorsAction, &QAction::triggered, this, &MainWindow::chooseColors); - loadAction->setShortcut(QKeySequence::Open); - - menuBar()->addMenu(fileMenu); - menuBar()->addMenu(prefMenu); + updateStatusBar(); + + // Render Area + r_area = new RenderArea(this, hashlife_universe); + setCentralWidget(r_area); + + r_area->setCursor(Qt::ArrowCursor); + + // Simulation control toolbar + QToolBar *controlToolbar = addToolBar("Simulation Controls"); + addToolBar(Qt::LeftToolBarArea, controlToolbar); + playIcon = new QIcon("../res/icons/play.svg"); + pauseIcon = new QIcon("../res/icons/pause.svg"); + playPauseAction = controlToolbar->addAction(*playIcon, "Play/Pause"); + QIcon *stepIcon = new QIcon("../res/icons/step.svg"); + QAction *stepAction = + controlToolbar->addAction(*stepIcon, "Advance one step"); + + connect(playPauseAction, &QAction::triggered, this, &MainWindow::playPause); + connect(stepAction, &QAction::triggered, this, &MainWindow::stepSimulation); + + // Control toolbox + QToolBar *toolboxToolbar = addToolBar("Toolbox"); + QButtonGroup *toolboxGroup = new QButtonGroup(); + toolboxGroup->setExclusive(true); + addToolBar(Qt::LeftToolBarArea, toolboxToolbar); + + pencilButton = new QToolButton(toolboxToolbar); + pencilButton->setIcon(QIcon("../res/icons/pencil.svg")); + pencilButton->setCheckable(true); + toolboxGroup->addButton(pencilButton); + toolboxToolbar->addWidget(pencilButton); + + eraserButton = new QToolButton(toolboxToolbar); + eraserButton->setIcon(QIcon("../res/icons/eraser.svg")); + eraserButton->setCheckable(true); + toolboxGroup->addButton(eraserButton); + toolboxToolbar->addWidget(eraserButton); + + zoominButton = new QToolButton(toolboxToolbar); + zoominButton->setIcon(QIcon("../res/icons/zoom-in.svg")); + zoominButton->setCheckable(true); + toolboxGroup->addButton(zoominButton); + toolboxToolbar->addWidget(zoominButton); + + zoomoutButton = new QToolButton(toolboxToolbar); + zoomoutButton->setIcon(QIcon("../res/icons/zoom-out.svg")); + zoomoutButton->setCheckable(true); + toolboxGroup->addButton(zoomoutButton); + toolboxToolbar->addWidget(zoomoutButton); + + // Menu Bar + QMenu *fileMenu = new QMenu("File"); + QMenu *prefMenu = new QMenu("Preferences"); + QAction *loadAction = fileMenu->addAction("Load pattern"); + QAction *changeColorsAction = prefMenu->addAction("Choose colors"); + + connect(loadAction, &QAction::triggered, this, &MainWindow::load); + connect(changeColorsAction, &QAction::triggered, this, + &MainWindow::chooseColors); + loadAction->setShortcut(QKeySequence::Open); + + menuBar()->addMenu(fileMenu); + menuBar()->addMenu(prefMenu); } void MainWindow::playPause() { - - simulationRunning = !simulationRunning; - if(simulationRunning) { - playPauseAction->setIcon(*pauseIcon); - stepTimer->start(50); - }else{ - playPauseAction->setIcon(*playIcon); - stepTimer->stop(); - } - + simulationRunning = !simulationRunning; + if (simulationRunning) { + playPauseAction->setIcon(*pauseIcon); + stepTimer->start(50); + } else { + playPauseAction->setIcon(*playIcon); + stepTimer->stop(); + } } void MainWindow::updateStatusBar() { - std::string s; - s += "Generation : "; - if(game != nullptr) - s += std::to_string(game->getGeneration()); - else if(hashlife_universe != nullptr) - s += bigint_to_str(hashlife_universe->get_generation()); - statusBar()->showMessage(QString(s.c_str())); + std::string s; + s += "Generation : "; + if (game != nullptr) + s += std::to_string(game->getGeneration()); + else if (hashlife_universe != nullptr) + s += bigint_to_str(hashlife_universe->get_generation()); + statusBar()->showMessage(QString(s.c_str())); } void MainWindow::stepSimulation() { - if(game != nullptr) - game->nextGeneration(); - else if(hashlife_universe != nullptr) { - hashlife_universe->step(); - } + if (game != nullptr) + game->nextGeneration(); + else if (hashlife_universe != nullptr) + hashlife_universe->step(); + r_area->update(); - updateStatusBar(); + updateStatusBar(); } void MainWindow::load() { - QString fileName = QFileDialog::getOpenFileName(this, "Open File","","Run Length Encoded (*.rle)"); - if(game != nullptr) { - game->loadRLE(fileName); - } else if(hashlife_universe != nullptr) { - delete hashlife_universe; - hashlife_universe = new HashlifeUniverse(fileName); - delete r_area; - r_area = new RenderArea(this,hashlife_universe); - setCentralWidget(r_area); - } - updateStatusBar(); - -} - -MainWindow::~MainWindow() { - delete r_area; + QString fileName = QFileDialog::getOpenFileName(this, "Open File", "", + "Run Length Encoded (*.rle)"); + if (game != nullptr) { + game->loadRLE(fileName); + } else if (hashlife_universe != nullptr) { + delete hashlife_universe; + hashlife_universe = new HashlifeUniverse(fileName); + delete r_area; + r_area = new RenderArea(this, hashlife_universe); + setCentralWidget(r_area); + } + updateStatusBar(); } +MainWindow::~MainWindow() { delete r_area; } -void MainWindow::keyPressEvent(QKeyEvent *event) { - r_area->handleInput(event); -} +void MainWindow::keyPressEvent(QKeyEvent *event) { r_area->handleInput(event); } void MainWindow::mousePressEvent(QMouseEvent *event) { - if(r_area->underMouse()){ - QPoint pos = event->pos(); - if(zoominButton->isChecked()){ - r_area->zoomin_event(r_area->mapFromParent(pos)); - } - else if(zoomoutButton->isChecked()){ - r_area->zoomout_event(r_area->mapFromParent(pos)); - } - else if(pencilButton->isChecked()){ - Coord c = r_area->map_coords_from_mouse(r_area->mapFromParent(pos)); - std::cout << "Coords : " << c.x << "," << c.y << "\n"; - hashlife_universe->set(c,1); - r_area->update(); - } - else if(eraserButton->isChecked()){ - Coord c = r_area->map_coords_from_mouse(r_area->mapFromParent(pos)); - std::cout << "Coords : " << c.x << "," << c.y << "\n"; - hashlife_universe->set(c,0); - r_area->update(); - } - } + if (r_area->underMouse()) { + QPoint pos = event->pos(); + if (zoominButton->isChecked()) { + r_area->zoomin_event(r_area->mapFromParent(pos)); + } else if (zoomoutButton->isChecked()) { + r_area->zoomout_event(r_area->mapFromParent(pos)); + } else if (pencilButton->isChecked()) { + Coord c = r_area->map_coords_from_mouse(r_area->mapFromParent(pos)); + std::cout << "Coords : " << c.x << "," << c.y << "\n"; + hashlife_universe->set(c, 1); + r_area->update(); + } else if (eraserButton->isChecked()) { + Coord c = r_area->map_coords_from_mouse(r_area->mapFromParent(pos)); + std::cout << "Coords : " << c.x << "," << c.y << "\n"; + hashlife_universe->set(c, 0); + r_area->update(); + } + } } -void MainWindow::chooseColors(){ - QColor cell_color = QColorDialog::getColor(Qt::white,this,"Choose cell color"); - QColor bg_color = QColorDialog::getColor(Qt::black,this,"Choose background color"); +void MainWindow::chooseColors() { + QColor cell_color = + QColorDialog::getColor(Qt::white, this, "Choose cell color"); + QColor bg_color = + QColorDialog::getColor(Qt::black, this, "Choose background color"); - QSettings settings("aging-team", "aging"); - settings.setValue("renderer/bg-color",bg_color); - settings.setValue("renderer/cell-color",cell_color); + QSettings settings("aging-team", "aging"); + settings.setValue("renderer/bg-color", bg_color); + settings.setValue("renderer/cell-color", cell_color); - r_area->set_colors(cell_color,bg_color); - r_area->update(); + r_area->set_colors(cell_color, bg_color); + r_area->update(); } - diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index fd73dfc..4361421 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -1,43 +1,42 @@ #ifndef UI_MAINWINDOW_H_ #define UI_MAINWINDOW_H_ +#include #include -#include -#include #include -#include "RenderArea.h" +#include +#include class MainWindow : public QMainWindow { - Q_OBJECT + Q_OBJECT public: - MainWindow(); - virtual ~MainWindow(); + MainWindow(); + virtual ~MainWindow(); public slots: - void stepSimulation(); - void load(); - void playPause(); - void chooseColors(); + void stepSimulation(); + void load(); + void playPause(); + void chooseColors(); protected: - void keyPressEvent(QKeyEvent *event); - void mousePressEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent *event); + void mousePressEvent(QMouseEvent *event); private: - RenderArea *r_area; - Game *game; - Universe *hashlife_universe; - void createUI(); - void updateStatusBar(); - - bool simulationRunning; - QAction *playPauseAction; - QIcon *playIcon, *pauseIcon; - QTimer *stepTimer; - - QToolButton *zoominButton, *zoomoutButton, *pencilButton, *eraserButton; - + RenderArea *r_area; + Game *game; + Universe *hashlife_universe; + void createUI(); + void updateStatusBar(); + + bool simulationRunning; + QAction *playPauseAction; + QIcon *playIcon, *pauseIcon; + QTimer *stepTimer; + + QToolButton *zoominButton, *zoomoutButton, *pencilButton, *eraserButton; }; #endif /* UI_MAINWINDOW_H_ */ diff --git a/src/ui/RenderArea.cpp b/src/ui/RenderArea.cpp index 8080d32..a2ab9a1 100644 --- a/src/ui/RenderArea.cpp +++ b/src/ui/RenderArea.cpp @@ -1,244 +1,236 @@ -#include "RenderArea.h" +#include +#include #include +#include +#include +#include #include -#include -#include -#include "../logic/Rect.hpp" -#include "../logic/HashlifeUniverse/HashlifeUniverse.hpp" RenderArea::RenderArea(QWidget *parent, CellMap *gol_map) - : QOpenGLWidget(parent), gol_map(gol_map), hashlife_universe(nullptr) -{ -} -RenderArea::RenderArea(QWidget *parent, Universe *hashlife_universe) - : QOpenGLWidget(parent), hashlife_universe(hashlife_universe), gol_map(nullptr) -{ -} + : QOpenGLWidget(parent), gol_map(gol_map), hashlife_universe(nullptr) {} -void RenderArea::initializeGL() -{ - - QSettings settings("aging-team", "aging"); - settings.sync(); - QColor bg_color = settings.value("renderer/bg-color").value(); - QColor c_color = settings.value("renderer/cell-color").value(); - - set_colors(c_color, bg_color); - - this->vertexShaderSource = - "attribute vec2 posAttr;\n" - "uniform mat4 model;\n" - "uniform mat4 view;\n" - "uniform mat4 projection;\n" - "void main() {\n" - " gl_Position = projection * view * model * vec4(posAttr,1,1);\n" - "}\n"; - - this->fragmentShaderSource = - "uniform vec3 color;" - "void main() {\n" - " gl_FragColor = vec4(color,1.0f);\n" - "}\n"; - - initializeOpenGLFunctions(); - glDepthMask(0); - - m_program = new QOpenGLShaderProgram(this); - m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource.c_str()); - m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource.c_str()); - m_program->link(); - m_posAttr = m_program->attributeLocation("posAttr"); - m_modelUniform = m_program->uniformLocation("model"); - m_viewUniform = m_program->uniformLocation("view"); - m_projectionUniform = m_program->uniformLocation("projection"); - m_colorUniform = m_program->uniformLocation("color"); - - glGenBuffers(1, &square_ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, square_ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(square_elements), square_elements, GL_STATIC_DRAW); - - float aspect_ratio = (float)width() / (float)height(); - - // We create the projection matrix - projectionMatrix.setToIdentity(); - projectionMatrix.ortho(QRectF(0.0f, 0.0f, 1.0f * aspect_ratio, 1.0f)); - - // The Camera holds the view matrix and handles zooming - camera = new Camera2D(); - camera->pos.setX(0.0f); - camera->pos.setY(0.0f); - - if (hashlife_universe != nullptr) - camera->set_zoom(1 << (((HashlifeUniverse *)hashlife_universe)->get_top_level() + 1)); +RenderArea::RenderArea(QWidget *parent, Universe *hashlife_universe) + : QOpenGLWidget(parent), hashlife_universe(hashlife_universe), + gol_map(nullptr) {} + +void RenderArea::initializeGL() { + QSettings settings("aging-team", "aging"); + settings.sync(); + QColor bg_color = settings.value("renderer/bg-color").value(); + QColor c_color = settings.value("renderer/cell-color").value(); + + set_colors(c_color, bg_color); + + this->vertexShaderSource = + "attribute vec2 posAttr;\n" + "uniform mat4 model;\n" + "uniform mat4 view;\n" + "uniform mat4 projection;\n" + "void main() {\n" + " gl_Position = projection * view * model * vec4(posAttr,1,1);\n" + "}\n"; + + this->fragmentShaderSource = "uniform vec3 color;" + "void main() {\n" + " gl_FragColor = vec4(color,1.0f);\n" + "}\n"; + + initializeOpenGLFunctions(); + glDepthMask(0); + + m_program = new QOpenGLShaderProgram(this); + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, + vertexShaderSource.c_str()); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, + fragmentShaderSource.c_str()); + m_program->link(); + m_posAttr = m_program->attributeLocation("posAttr"); + m_modelUniform = m_program->uniformLocation("model"); + m_viewUniform = m_program->uniformLocation("view"); + m_projectionUniform = m_program->uniformLocation("projection"); + m_colorUniform = m_program->uniformLocation("color"); + + glGenBuffers(1, &square_ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, square_ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(square_elements), + square_elements, GL_STATIC_DRAW); + + float aspect_ratio = + static_cast(width()) / static_cast(height()); + + // We create the projection matrix + projectionMatrix.setToIdentity(); + projectionMatrix.ortho(QRectF(0.0f, 0.0f, 1.0f * aspect_ratio, 1.0f)); + + // The Camera holds the view matrix and handles zooming + camera = new Camera2D(); + camera->pos.setX(0.0f); + camera->pos.setY(0.0f); + + if (hashlife_universe != nullptr) + camera->set_zoom(1 << ((static_cast(hashlife_universe)) + ->get_top_level() + + 1)); } -void RenderArea::resizeGL(int w, int h) -{ - - const qreal retinaScale = devicePixelRatio(); - glViewport(0, 0, width(), height() * retinaScale); +void RenderArea::resizeGL(int w, int h) { + const qreal retinaScale = devicePixelRatio(); + glViewport(0, 0, width(), height() * retinaScale); - float aspect_ratio = (float)width() / (float)height(); - projectionMatrix.setToIdentity(); - projectionMatrix.ortho(QRectF(0.0f, 0.0f, 1.0f * aspect_ratio, 1.0f)); + float aspect_ratio = + static_cast(width()) / static_cast(height()); + projectionMatrix.setToIdentity(); + projectionMatrix.ortho(QRectF(0.0f, 0.0f, 1.0f * aspect_ratio, 1.0f)); - update(); + update(); } -void RenderArea::paintGL() -{ - - const qreal retinaScale = devicePixelRatio(); - glViewport(0, 0, width() * retinaScale, height() * retinaScale); - - glClearColor(bg_r, bg_g, bg_b, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - m_program->bind(); - m_program->setUniformValue(m_colorUniform, cell_color); - glEnableVertexAttribArray(0); - glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, square_vertices); - - QMatrix4x4 viewMatrix = camera->get_view(); - - if (gol_map != nullptr) - { - render_gol(viewMatrix); - } - else if (hashlife_universe != nullptr) - { - render_hashlife(viewMatrix); - } - else - { - std::cout << "Error : No Universe detected" << std::endl; - } - - glDisableVertexAttribArray(0); - m_program->release(); -} +void RenderArea::paintGL() { + const qreal retinaScale = devicePixelRatio(); + glViewport(0, 0, width() * retinaScale, height() * retinaScale); + + glClearColor(bg_r, bg_g, bg_b, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); -void RenderArea::render_gol(QMatrix4x4 &matrix) -{ + m_program->bind(); + m_program->setUniformValue(m_colorUniform, cell_color); + glEnableVertexAttribArray(0); + glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, square_vertices); - /* - for(size_t c = 0; c< gol_map->getWidth();c++) { + QMatrix4x4 viewMatrix = camera->get_view(); - matrix.translate(1.0f,0.0f,0.0f); - for(size_t l = 0; l< gol_map->getHeight(); l++) { - matrix.translate(0.0f,-1.0f,0.0f); - if(gol_map->isAlive(c,l)){ - m_program->setUniformValue(m_matrixUniform, matrix); - glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0); - } - } - matrix.translate(0.0f,gol_map->getHeight(),0.0f); + if (gol_map != nullptr) { + render_gol(viewMatrix); + } else if (hashlife_universe != nullptr) { + render_hashlife(viewMatrix); + } else { + std::cout << "Error : No Universe detected" << std::endl; + } - } - */ + glDisableVertexAttribArray(0); + m_program->release(); } -void RenderArea::render_hashlife(QMatrix4x4 &viewMatrix) -{ +void RenderArea::render_gol(const QMatrix4x4 &matrix) { + /* + for(size_t c = 0; c< gol_map->getWidth();c++) { + + matrix.translate(1.0f,0.0f,0.0f); + for(size_t l = 0; l< gol_map->getHeight(); l++) { + matrix.translate(0.0f,-1.0f,0.0f); + if(gol_map->isAlive(c,l)){ + m_program->setUniformValue(m_matrixUniform, matrix); + glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, + 0); + } + } + matrix.translate(0.0f,gol_map->getHeight(),0.0f); + + } + */ +} - Coord top_left = ((HashlifeUniverse *)hashlife_universe)->get_top_left(); - size_t level = ((HashlifeUniverse *)hashlife_universe)->get_top_level(); +void RenderArea::render_hashlife(const QMatrix4x4 &viewMatrix) { + Coord top_left = + (static_cast(hashlife_universe))->get_top_left(); + size_t level = + (static_cast(hashlife_universe))->get_top_level(); - Rect bounds = camera->get_view_bounds((float)width() / (float)height(), hashlife_universe); + Rect bounds = camera->get_view_bounds(static_cast(width()) / + static_cast(height()), + hashlife_universe); - std::vector coords; + std::vector coords; - ((HashlifeUniverse *)hashlife_universe)->get_cell_in_bounds(bounds, coords); + static_cast(hashlife_universe) + ->get_cell_in_bounds(bounds, &coords); - QMatrix4x4 modelMatrix; - modelMatrix.setToIdentity(); + QMatrix4x4 modelMatrix; + modelMatrix.setToIdentity(); - m_program->setUniformValue(m_viewUniform, viewMatrix); - m_program->setUniformValue(m_projectionUniform, projectionMatrix); + m_program->setUniformValue(m_viewUniform, viewMatrix); + m_program->setUniformValue(m_projectionUniform, projectionMatrix); - std::cout << "Top left : " << bounds.top_left.x << ',' << bounds.top_left.y << '\n'; - std::cout << "Bottom right : " << bounds.bottom_right.x << ',' << bounds.bottom_right.y << '\n'; + std::cout << "Top left : " << bounds.top_left.x << ',' << bounds.top_left.y + << '\n'; + std::cout << "Bottom right : " << bounds.bottom_right.x << ',' + << bounds.bottom_right.y << '\n'; - for (size_t i = 0; i < coords.size(); ++i) - { - modelMatrix.setToIdentity(); - modelMatrix.translate(coords[i].x.get_si(), -coords[i].y.get_si(), 0); - m_program->setUniformValue(m_modelUniform, modelMatrix); - glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0); - } + for (size_t i = 0; i < coords.size(); ++i) { + modelMatrix.setToIdentity(); + modelMatrix.translate(coords[i].x.get_si(), -coords[i].y.get_si(), 0); + m_program->setUniformValue(m_modelUniform, modelMatrix); + glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0); + } } -void RenderArea::wheelEvent(QWheelEvent *event) -{ - //camera->set_zoom(camera->get_zoom() - event->delta() / 100.0f); - //update(); +void RenderArea::wheelEvent(QWheelEvent *event) { + // camera->set_zoom(camera->get_zoom() - event->delta() / 100.0f); + // update(); } -void RenderArea::zoomin_event(QPoint origin) -{ - camera->set_zoom(camera->get_zoom() / 2); - update(); +void RenderArea::zoomin_event(QPoint origin) { + camera->set_zoom(camera->get_zoom() / 2); + update(); } -void RenderArea::zoomout_event(QPoint origin) -{ - camera->set_zoom(camera->get_zoom() * 2); - update(); +void RenderArea::zoomout_event(QPoint origin) { + camera->set_zoom(camera->get_zoom() * 2); + update(); } -Coord RenderArea::map_coords_from_mouse(QPoint mouseCoords) -{ - float aspect_ratio = (float) width() / (float) height(); - float x_relative = (float)mouseCoords.x() / (float)width() * aspect_ratio; - float y_relative = (float)mouseCoords.y() / (float)height(); - - QMatrix4x4 viewinv = camera->get_view().inverted(); - Coord c; - QPointF p = viewinv.map(QPointF(x_relative,y_relative)); - c.x = BigInt(std::floor(p.x())); - c.y = BigInt(std::ceil(-p.y())); - - return c; +Coord RenderArea::map_coords_from_mouse(QPoint mouseCoords) { + float aspect_ratio = + static_cast(width()) / static_cast(height()); + float x_relative = static_cast(mouseCoords.x()) / + static_cast(width()) * aspect_ratio; + float y_relative = + static_cast(mouseCoords.y()) / static_cast(height()); + + QMatrix4x4 viewinv = camera->get_view().inverted(); + Coord c; + QPointF p = viewinv.map(QPointF(x_relative, y_relative)); + c.x = BigInt(std::floor(p.x())); + c.y = BigInt(std::ceil(-p.y())); + + return c; } -void RenderArea::handleInput(QKeyEvent *event) -{ - switch (event->key()) - { - case Qt::Key_Z: - case Qt::Key_Up: - camera->pos.setY(camera->pos.y() - 0.05f); - break; - case Qt::Key_S: - case Qt::Key_Down: - camera->pos.setY(camera->pos.y() + 0.05f); - break; - case Qt::Key_Q: - case Qt::Key_Left: - camera->pos.setX(camera->pos.x() - 0.05f); - break; - case Qt::Key_D: - case Qt::Key_Right: - camera->pos.setX(camera->pos.x() + 0.05f); - break; - case Qt::Key_Plus: - zoomin_event(QPoint(0, 0)); - break; - case Qt::Key_Minus: - zoomout_event(QPoint(0, 0)); - break; - - default: - break; - } - update(); +void RenderArea::handleInput(QKeyEvent *event) { + switch (event->key()) { + case Qt::Key_Z: + case Qt::Key_Up: + camera->pos.setY(camera->pos.y() - 0.05f); + break; + case Qt::Key_S: + case Qt::Key_Down: + camera->pos.setY(camera->pos.y() + 0.05f); + break; + case Qt::Key_Q: + case Qt::Key_Left: + camera->pos.setX(camera->pos.x() - 0.05f); + break; + case Qt::Key_D: + case Qt::Key_Right: + camera->pos.setX(camera->pos.x() + 0.05f); + break; + case Qt::Key_Plus: + zoomin_event(QPoint(0, 0)); + break; + case Qt::Key_Minus: + zoomout_event(QPoint(0, 0)); + break; + + default: + break; + } + update(); } -void RenderArea::set_colors(QColor c_color, QColor bg_color) -{ - bg_r = bg_color.redF(); - bg_g = bg_color.greenF(); - bg_b = bg_color.blueF(); +void RenderArea::set_colors(QColor c_color, QColor bg_color) { + bg_r = bg_color.redF(); + bg_g = bg_color.greenF(); + bg_b = bg_color.blueF(); - cell_color.setX(c_color.redF()); - cell_color.setY(c_color.greenF()); - cell_color.setZ(c_color.blueF()); + cell_color.setX(c_color.redF()); + cell_color.setY(c_color.greenF()); + cell_color.setZ(c_color.blueF()); } diff --git a/src/ui/RenderArea.h b/src/ui/RenderArea.h index 1f9ef47..9236cfa 100644 --- a/src/ui/RenderArea.h +++ b/src/ui/RenderArea.h @@ -1,66 +1,68 @@ #ifndef UI_RENDERAREA_H_ #define UI_RENDERAREA_H_ -#include "../logic/Universe.hpp" -#include "../gameoflife/Game.h" -#include "Camera2D.h" -#include #include #include +#include #include +#include +#include +#include +#include -class RenderArea : public QOpenGLWidget , protected QOpenGLFunctions { - +class RenderArea : public QOpenGLWidget, protected QOpenGLFunctions { public: - RenderArea(QWidget *parent = 0, CellMap *gol_map= 0); - RenderArea(QWidget *parent = 0, Universe *hashlife_universe = 0); - void handleInput(QKeyEvent *event); - void zoomin_event(QPoint origin); - void zoomout_event(QPoint origin); + explicit RenderArea(QWidget *parent = 0, CellMap *gol_map = 0); + explicit RenderArea(QWidget *parent = 0, Universe *hashlife_universe = 0); + void handleInput(QKeyEvent *event); + void zoomin_event(QPoint origin); + void zoomout_event(QPoint origin); - Coord map_coords_from_mouse(QPoint mouseCoords); - void set_colors(QColor cell_color, QColor bg_color); + Coord map_coords_from_mouse(QPoint mouseCoords); + void set_colors(QColor cell_color, QColor bg_color); protected: - void initializeGL() override; - void resizeGL(int w, int h) override; - void paintGL() override; - void wheelEvent(QWheelEvent *event) override; + void initializeGL() override; + void resizeGL(int w, int h) override; + void paintGL() override; + void wheelEvent(QWheelEvent *event) override; private: - CellMap *gol_map; - Universe *hashlife_universe; - std::string vertexShaderSource; - std::string fragmentShaderSource; - - GLuint m_posAttr; - GLuint m_modelUniform; - GLuint m_viewUniform; - GLuint m_projectionUniform; - GLuint m_colorUniform; + CellMap *gol_map; + Universe *hashlife_universe; + std::string vertexShaderSource; + std::string fragmentShaderSource; - GLclampf bg_r, bg_g, bg_b; - QVector3D cell_color; + GLuint m_posAttr; + GLuint m_modelUniform; + GLuint m_viewUniform; + GLuint m_projectionUniform; + GLuint m_colorUniform; - QMatrix4x4 projectionMatrix; + GLclampf bg_r, bg_g, bg_b; + QVector3D cell_color; - float square_vertices[8] = { - 0.05f, 0.05f, // Top-left - 0.95f, 0.05f, // Top-right - 0.95f, 0.95f, // Bottom-right - 0.05f, 0.95f, // Bottom-left - }; - GLuint square_elements[4] = { - 0,1,3,2, - }; - GLuint square_ebo; + QMatrix4x4 projectionMatrix; - QOpenGLShaderProgram *m_program; - Camera2D *camera; + float square_vertices[8] = { + 0.05f, 0.05f, // Top-left + 0.95f, 0.05f, // Top-right + 0.95f, 0.95f, // Bottom-right + 0.05f, 0.95f, // Bottom-left + }; + GLuint square_elements[4] = { + 0, + 1, + 3, + 2, + }; + GLuint square_ebo; - void render_gol(QMatrix4x4 &matrix); - void render_hashlife(QMatrix4x4 &matrix); + QOpenGLShaderProgram *m_program; + Camera2D *camera; + void render_gol(const QMatrix4x4 &matrix); + void render_hashlife(const QMatrix4x4 &matrix); }; #endif /* UI_RENDERAREA_H_ */