From fe79577396231f2edb7927f1f61ce814f03851a7 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 27 Feb 2022 17:12:49 +0100 Subject: add basic engine graphics --- src/CMakeLists.txt | 3 ++ src/DI/object_wrapper.hpp | 2 +- src/bootstrap.cpp | 21 +++++++++++ src/engine/graphics/bounds.cpp | 65 +++++++++++++++++++++++++++++++++++ src/engine/graphics/bounds.hpp | 28 +++++++++++++++ src/engine/graphics/scene.cpp | 57 ++++++++++++++++++++++++++++++ src/engine/graphics/scene.hpp | 31 +++++++++++++++++ src/engine/graphics/string_matrix.cpp | 41 ++++++++++++++++++++++ src/engine/graphics/string_matrix.hpp | 60 ++++++++++++++++++++++++++++++++ src/game/game.cpp | 14 +++++--- src/game/game.hpp | 10 +++--- src/interfaces/bounds.hpp | 41 ++++++++++++++++++++++ src/interfaces/matrix.hpp | 48 ++++++++++++++++++++++++++ src/interfaces/scene.hpp | 15 ++++++++ 14 files changed, 427 insertions(+), 9 deletions(-) create mode 100644 src/engine/graphics/bounds.cpp create mode 100644 src/engine/graphics/bounds.hpp create mode 100644 src/engine/graphics/scene.cpp create mode 100644 src/engine/graphics/scene.hpp create mode 100644 src/engine/graphics/string_matrix.cpp create mode 100644 src/engine/graphics/string_matrix.hpp create mode 100644 src/interfaces/bounds.hpp create mode 100644 src/interfaces/matrix.hpp create mode 100644 src/interfaces/scene.hpp (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a32942b..385283d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,6 +15,9 @@ file(GLOB SOURCES argument_parser.cpp game/game.cpp engine/graphics/vector2.cpp + engine/graphics/bounds.cpp + engine/graphics/scene.cpp + engine/graphics/string_matrix.cpp randomization/generator.cpp randomization/seed_generator.cpp DI/object_type.cpp) diff --git a/src/DI/object_wrapper.hpp b/src/DI/object_wrapper.hpp index 0ae66df..19d8cdd 100644 --- a/src/DI/object_wrapper.hpp +++ b/src/DI/object_wrapper.hpp @@ -9,7 +9,7 @@ template class ObjectWrapper : public IWrapper> { public: - explicit ObjectWrapper(const Container &container) : _container(container) {} + explicit ObjectWrapper(const Container &container) noexcept : _container(container) {} [[nodiscard]] std::shared_ptr get() const; diff --git a/src/bootstrap.cpp b/src/bootstrap.cpp index ce07621..8a8aa25 100644 --- a/src/bootstrap.cpp +++ b/src/bootstrap.cpp @@ -2,12 +2,18 @@ // Interfaces #include "interfaces/argument_parser.hpp" +#include "interfaces/bounds.hpp" #include "interfaces/game.hpp" +#include "interfaces/matrix.hpp" #include "interfaces/randomization.hpp" +#include "interfaces/scene.hpp" #include "interfaces/vector2.hpp" // Implementations #include "argument_parser.hpp" +#include "engine/graphics/bounds.hpp" +#include "engine/graphics/scene.hpp" +#include "engine/graphics/string_matrix.hpp" #include "engine/graphics/vector2.hpp" #include "game/game.hpp" #include "randomization/generator.hpp" @@ -15,6 +21,7 @@ #include #include +#include Container bootstrap() { @@ -22,6 +29,7 @@ Container bootstrap() container.bind().to(); container.bind().to(); + container.bind().to(); container.bind().to_factory( [](const unsigned int &seed) @@ -44,5 +52,18 @@ Container bootstrap() std::make_shared(options)); }); + container.bind>().to_factory( + [](const IBounds &bounds) + { + return std::dynamic_pointer_cast>( + std::make_shared(bounds)); + }); + + container.bind().to_factory( + [](const IBoundsOptions &options) + { + return std::dynamic_pointer_cast(std::make_shared(options)); + }); + return container; } diff --git a/src/engine/graphics/bounds.cpp b/src/engine/graphics/bounds.cpp new file mode 100644 index 0000000..8cb83eb --- /dev/null +++ b/src/engine/graphics/bounds.cpp @@ -0,0 +1,65 @@ +#include "bounds.hpp" + +Bounds::Bounds(const IBoundsOptions &options) + : _width(options.width), _height(options.height) +{ +} + +unsigned int Bounds::width() const +{ + return _width; +} + +void Bounds::width(unsigned int width) +{ + _width = width; +} + +unsigned int Bounds::height() const +{ + return _height; +} + +void Bounds::height(unsigned int height) +{ + _height = height; +} + +CoordsValidation Bounds::validate_coords(const IVector2 &coords) const +{ + if (coords.x() >= _width) + { + return CoordsValidation::X_HIGH; + } + + if (coords.y() >= _height) + { + return CoordsValidation::Y_HIGH; + } + + return CoordsValidation::VALID; +} + +const IBounds &Bounds::operator*=(const IBounds &bounds) +{ + _width *= bounds.width(); + _height *= bounds.height(); + + return *this; +} + +const IBounds &Bounds::operator+=(const IBounds &bounds) +{ + _width += bounds.width(); + _height += bounds.height(); + + return *this; +} + +const IBounds &Bounds::operator-=(const IBounds &bounds) +{ + _width -= bounds.width(); + _height -= bounds.height(); + + return *this; +} diff --git a/src/engine/graphics/bounds.hpp b/src/engine/graphics/bounds.hpp new file mode 100644 index 0000000..3f4dd5b --- /dev/null +++ b/src/engine/graphics/bounds.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "interfaces/bounds.hpp" +#include "interfaces/vector2.hpp" + +class Bounds : public IBounds +{ +public: + explicit Bounds(const IBoundsOptions &options); + + [[nodiscard]] unsigned int width() const override; + + void width(unsigned int width) override; + + [[nodiscard]] unsigned int height() const override; + + void height(unsigned int height) override; + + [[nodiscard]] CoordsValidation validate_coords(const IVector2 &coords) const override; + + const IBounds &operator*=(const IBounds &bounds) override; + const IBounds &operator+=(const IBounds &bounds) override; + const IBounds &operator-=(const IBounds &bounds) override; + +private: + unsigned int _width = 0U; + unsigned int _height = 0U; +}; diff --git a/src/engine/graphics/scene.cpp b/src/engine/graphics/scene.cpp new file mode 100644 index 0000000..3f63807 --- /dev/null +++ b/src/engine/graphics/scene.cpp @@ -0,0 +1,57 @@ +#include "scene.hpp" + +#include +#include + +Scene::Scene(IMatrixFactory matrix_factory) + : _is_shown(false), _matrix_factory(std::move(matrix_factory)) +{ +} + +void Scene::enter() +{ + if (_is_shown) + { + return; + } + + fmt::print(ENABLE_ALT_BUFFER, fmt::arg("esc", ESC)); + std::cout.flush(); + + _is_shown = true; +} + +void Scene::leave() +{ + if (!_is_shown) + { + return; + } + + fmt::print(DISABLE_ALT_BUFFER, fmt::arg("esc", ESC)); + std::cout.flush(); + + _is_shown = false; +} + +/* +void do_in_statusbar(const std::function &routine) +{ + const auto prev_pos = Cursor::where(); + + const auto window_size = Window::size(); + + Cursor::hide(); + + Cursor::move_to(Vector2({1, window_size.height()})); + + std::cout << fmt::format(EscapeSequences::ERASE_LINE, fmt::arg("esc", ESC)); + std::cout.flush(); + + routine(); + + Cursor::move_to(prev_pos); + + Cursor::show(); +} +*/ diff --git a/src/engine/graphics/scene.hpp b/src/engine/graphics/scene.hpp new file mode 100644 index 0000000..b26ac05 --- /dev/null +++ b/src/engine/graphics/scene.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "DI/auto_wirable.hpp" +#include "interfaces/matrix.hpp" +#include "interfaces/scene.hpp" + +#include +#include + +constexpr fmt::string_view ESC = "\x1B"; + +constexpr fmt::string_view ENABLE_ALT_BUFFER = "{esc}[?1049h"; +constexpr fmt::string_view DISABLE_ALT_BUFFER = "{esc}[?1049l"; + +class Scene : public IScene, + public AutoWirable> +{ +public: + explicit Scene(IMatrixFactory matrix_factory); + + void enter() override; + + void leave() override; + + // void do_in_statusbar(const std::function &routine); + +private: + bool _is_shown; + + IMatrixFactory _matrix_factory; +}; diff --git a/src/engine/graphics/string_matrix.cpp b/src/engine/graphics/string_matrix.cpp new file mode 100644 index 0000000..e259e96 --- /dev/null +++ b/src/engine/graphics/string_matrix.cpp @@ -0,0 +1,41 @@ +#include "string_matrix.hpp" + +StringMatrix::StringMatrix(const IBounds &bounds) + : _rows(bounds.height()), _columns(bounds.width()) +{ + _matrix.reserve(bounds.height()); + _matrix.assign(_matrix.capacity(), std::vector(bounds.width())); +}; + +void StringMatrix::fill(std::string_view element) +{ + for (unsigned int row = 0U; row < _matrix.capacity(); row++) + { + std::vector row_vector = _matrix[row]; + + for (unsigned int column = 0U; column < row_vector.capacity(); column++) + { + _matrix[row][column] = element; + } + } +} + +std::string_view StringMatrix::get(const IVector2 &pos) const +{ + return _matrix[pos.y()][pos.x()]; +} + +void StringMatrix::set(const IVector2 &pos, std::string_view element) +{ + _matrix[pos.y()][pos.x()] = element; +} + +unsigned int StringMatrix::rows() const +{ + return _rows; +} + +unsigned int StringMatrix::columns() const +{ + return _columns; +} diff --git a/src/engine/graphics/string_matrix.hpp b/src/engine/graphics/string_matrix.hpp new file mode 100644 index 0000000..662ea7b --- /dev/null +++ b/src/engine/graphics/string_matrix.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include "interfaces/bounds.hpp" +#include "interfaces/matrix.hpp" +#include "interfaces/vector2.hpp" + +#include +#include + +/** + * A Matrix. + */ +class StringMatrix : public IMatrix +{ +public: + /** + * Creates a matrix. + * + * @param bounds The bounds of the matrix + */ + explicit StringMatrix(const IBounds &bounds); + + /** + * Fills the matrix with a element. + * + * @param element A element + */ + void fill(std::string_view element) override; + + /** + * Returns a element of the matrix. + * + * @param pos The position of a element + */ + [[nodiscard]] std::string_view get(const IVector2 &pos) const override; + + /** + * Sets a element of the matrix. + * + * @param pos The position of a element + * @param element A new element + */ + void set(const IVector2 &pos, std::string_view element) override; + + /** + * Returns the number of rows the matrix has. + */ + [[nodiscard]] unsigned int rows() const override; + + /** + * Returns the number of columns the matrix has. + */ + [[nodiscard]] unsigned int columns() const override; + +private: + std::vector> _matrix; + + unsigned int _rows; + unsigned int _columns; +}; diff --git a/src/game/game.cpp b/src/game/game.cpp index e785e18..9b08adc 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -1,9 +1,15 @@ #include "game.hpp" -#include +#include +#include -Game::Game(IVector2Factory vector2_factory) : _vector2_factory(std::move(vector2_factory)) +Game::Game(const std::shared_ptr &scene) : _scene(scene) {} + +void Game::run() { -} + _scene->enter(); -void Game::run() {} + std::this_thread::sleep_for(std::chrono::seconds(3)); + + _scene->leave(); +} diff --git a/src/game/game.hpp b/src/game/game.hpp index 4c7e5e1..6abb349 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -2,15 +2,17 @@ #include "DI/auto_wirable.hpp" #include "interfaces/game.hpp" -#include "interfaces/vector2.hpp" +#include "interfaces/scene.hpp" -class Game : public IGame, public AutoWirable +#include + +class Game : public IGame, public AutoWirable { public: - explicit Game(IVector2Factory vector2_factory); + explicit Game(const std::shared_ptr &scene); void run() override; private: - IVector2Factory _vector2_factory; + const std::shared_ptr &_scene; }; diff --git a/src/interfaces/bounds.hpp b/src/interfaces/bounds.hpp new file mode 100644 index 0000000..9cec97e --- /dev/null +++ b/src/interfaces/bounds.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "interfaces/vector2.hpp" + +#include +#include + +enum CoordsValidation +{ + VALID, + X_HIGH, + Y_HIGH +}; + +class IBounds +{ +public: + [[nodiscard]] virtual unsigned int width() const = 0; + + virtual void width(unsigned int width) = 0; + + [[nodiscard]] virtual unsigned int height() const = 0; + + virtual void height(unsigned int height) = 0; + + [[nodiscard]] virtual CoordsValidation + validate_coords(const IVector2 &coords) const = 0; + + virtual const IBounds &operator*=(const IBounds &bounds) = 0; + virtual const IBounds &operator+=(const IBounds &bounds) = 0; + virtual const IBounds &operator-=(const IBounds &bounds) = 0; +}; + +struct IBoundsOptions +{ + unsigned int width; + unsigned int height; +}; + +using IBoundsFactory = + std::function(const IBoundsOptions &options)>; diff --git a/src/interfaces/matrix.hpp b/src/interfaces/matrix.hpp new file mode 100644 index 0000000..5dc5f2e --- /dev/null +++ b/src/interfaces/matrix.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "interfaces/bounds.hpp" +#include "interfaces/vector2.hpp" + +#include +#include + +template +class IMatrix +{ +public: + /** + * Fills the matrix with a element. + * + * @param element A element + */ + virtual void fill(Element element) = 0; + + /** + * Returns a element of the matrix. + * + * @param pos The position of a element + */ + [[nodiscard]] virtual Element get(const IVector2 &pos) const = 0; + + /** + * Sets a element of the matrix. + * + * @param pos The position of a element + * @param element A new element + */ + virtual void set(const IVector2 &pos, Element element) = 0; + + /** + * Returns the number of rows the matrix has. + */ + [[nodiscard]] virtual unsigned int rows() const = 0; + + /** + * Returns the number of columns the matrix has. + */ + [[nodiscard]] virtual unsigned int columns() const = 0; +}; + +template +using IMatrixFactory = + std::function>(const IBounds &bounds)>; diff --git a/src/interfaces/scene.hpp b/src/interfaces/scene.hpp new file mode 100644 index 0000000..8b34dae --- /dev/null +++ b/src/interfaces/scene.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "interfaces/matrix.hpp" + +#include +#include +#include + +class IScene +{ +public: + virtual void enter() = 0; + + virtual void leave() = 0; +}; -- cgit v1.2.3-18-g5258