From 7b7e0ba851189848ff1c89761a1609e6a978fb19 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 7 Oct 2022 16:25:43 +0200 Subject: a --- src/chunk.hpp | 17 +++++++-- src/floor-mesh.hpp | 4 ++- src/local-coords.hpp | 32 +++++++++++++++++ src/tile-atlas.hpp | 2 ++ src/tile-defs.hpp | 9 +++++ src/tile-iterator.cpp | 8 +++++ src/tile-iterator.hpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/tile.cpp | 2 -- src/tile.hpp | 26 +------------- 9 files changed, 165 insertions(+), 31 deletions(-) create mode 100644 src/local-coords.hpp create mode 100644 src/tile-defs.hpp create mode 100644 src/tile-iterator.cpp create mode 100644 src/tile-iterator.hpp (limited to 'src') diff --git a/src/chunk.hpp b/src/chunk.hpp index 6c3706b8..a22dc025 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -1,15 +1,18 @@ #pragma once #include "tile.hpp" +#include "tile-iterator.hpp" #include #include namespace Magnum::Examples { template -concept tile_iterator = requires(F fn, Tile& tile) { +concept tile_iterator_fn = requires(F fn, Tile& tile) { { fn.operator()(tile, std::size_t{}, local_coords{}) } -> std::same_as; }; +template class basic_tile_iterator; + struct chunk final { constexpr tile& operator[](local_coords xy) { return _tiles[xy.to_index()]; } @@ -19,16 +22,24 @@ struct chunk final const auto& tiles() const { return _tiles; } auto& tiles() { return _tiles; } - template F> + template F> constexpr inline void foreach_tile(F&& fun) { foreach_tile_(std::forward(fun)); } - template F> + template F> constexpr inline void foreach_const_tile(F&& fun) const { const_cast(this)->foreach_tile_(std::forward(fun)); } + using iterator = basic_tile_iterator; + using const_iterator = basic_tile_iterator; + + constexpr iterator begin() { return iterator{_tiles.data(), 0}; } + constexpr iterator end() { return iterator{_tiles.data(), _tiles.size()}; } + constexpr const_iterator cbegin() const { return const_iterator{_tiles.data(), 0}; } + constexpr const_iterator cend() { return const_iterator{_tiles.data(), _tiles.size()}; } + private: template constexpr void foreach_tile_(F&& fun); diff --git a/src/floor-mesh.hpp b/src/floor-mesh.hpp index 41351fd9..fed5867c 100644 --- a/src/floor-mesh.hpp +++ b/src/floor-mesh.hpp @@ -1,9 +1,10 @@ #pragma once -#include "tile.hpp" +#include "tile-defs.hpp" #include #include #include #include +#include #include #include @@ -11,6 +12,7 @@ namespace Magnum::Examples { struct tile_shader; struct chunk; +struct tile; struct floor_mesh final { diff --git a/src/local-coords.hpp b/src/local-coords.hpp new file mode 100644 index 00000000..d2520a42 --- /dev/null +++ b/src/local-coords.hpp @@ -0,0 +1,32 @@ +#pragma once +#include "compat/assert.hpp" +#include "tile-defs.hpp" +#include +#include +#include + +namespace Magnum::Examples { + +struct local_coords final { + std::uint8_t x = 0, y = 0; + explicit constexpr local_coords(std::size_t idx); + constexpr local_coords() = default; + constexpr local_coords(std::size_t x, std::size_t y); + constexpr local_coords(std::uint8_t x, std::uint8_t y) : x{x}, y{y} {} + constexpr std::size_t to_index() const { return y*TILE_MAX_DIM + x; } +}; + +constexpr local_coords::local_coords(std::size_t index) : + x{(std::uint8_t)(index % TILE_MAX_DIM)}, + y{(std::uint8_t)(index / TILE_MAX_DIM)} +{ + ASSERT(index < TILE_COUNT); +} + +constexpr local_coords::local_coords(std::size_t x, std::size_t y) + : x{(std::uint8_t)x}, y{(std::uint8_t)y} +{ + ASSERT(x <= 0xff && y <= 0xff); +} + +} // namespace Magnum::Examples diff --git a/src/tile-atlas.hpp b/src/tile-atlas.hpp index af9e505b..2d3461cc 100644 --- a/src/tile-atlas.hpp +++ b/src/tile-atlas.hpp @@ -8,6 +8,8 @@ namespace std::filesystem { class path; } namespace Magnum::Examples { +constexpr inline Vector3 TILE_SIZE = { 64, 64, 64 }; + struct tile_atlas final { using quad = std::array; diff --git a/src/tile-defs.hpp b/src/tile-defs.hpp new file mode 100644 index 00000000..40d1809b --- /dev/null +++ b/src/tile-defs.hpp @@ -0,0 +1,9 @@ +#pragma once +#include + +namespace Magnum::Examples { + +constexpr inline std::size_t TILE_MAX_DIM = 16; +constexpr inline std::size_t TILE_COUNT = TILE_MAX_DIM*TILE_MAX_DIM; + +} // namespace Magnum::Examples diff --git a/src/tile-iterator.cpp b/src/tile-iterator.cpp new file mode 100644 index 00000000..ea98a6ee --- /dev/null +++ b/src/tile-iterator.cpp @@ -0,0 +1,8 @@ +#include "tile-iterator.hpp" + +namespace Magnum::Examples { + +template class basic_tile_iterator; +template class basic_tile_iterator; + +} // namespace Magnum::Examples diff --git a/src/tile-iterator.hpp b/src/tile-iterator.hpp new file mode 100644 index 00000000..a0ffa11c --- /dev/null +++ b/src/tile-iterator.hpp @@ -0,0 +1,96 @@ +#pragma once + +#include "local-coords.hpp" +#include "tile.hpp" +#include +#include +#include +#include + +namespace Magnum::Examples { + +template +class basic_tile_iterator; + +struct tile; + +} // namespace Magnum::Examples + +namespace std { + +template +constexpr void swap(Magnum::Examples::basic_tile_iterator& lhs, + Magnum::Examples::basic_tile_iterator& rhs) noexcept; + +} // namespace std + +namespace Magnum::Examples { + +namespace detail { + +template +class tile_tuple_wrapper final { + using value_type = std::tuple; + value_type value; + +public: + constexpr tile_tuple_wrapper(value_type x) : value(x) {} + constexpr value_type& operator*() noexcept { return value; } + constexpr value_type* operator->() noexcept { return &value; } +}; + +} // namespace detail + +template +class basic_tile_iterator final { + T* ptr; + std::size_t pos = 0; + + friend constexpr void swap(basic_tile_iterator& lhs, basic_tile_iterator& rhs) noexcept; + +public: + using value_type = std::tuple; + + explicit constexpr basic_tile_iterator(T* ptr, std::size_t pos) noexcept : ptr(ptr), pos(pos) {} + constexpr ~basic_tile_iterator() noexcept = default; + + constexpr basic_tile_iterator& operator=(const basic_tile_iterator&) noexcept = default; + constexpr basic_tile_iterator& operator++() noexcept { pos++; return *this; } + constexpr basic_tile_iterator operator++(int) noexcept { auto tmp = *this; operator++(); return tmp; } + constexpr value_type operator*() const noexcept { // NOLINT(bugprone-exception-escape) + ASSERT(pos < TILE_COUNT); + return {ptr[pos], pos, local_coords{pos}}; + } + constexpr detail::tile_tuple_wrapper operator->() const noexcept { // NOLINT(bugprone-exception-escape) + return {operator*()}; + } + constexpr auto operator<=>(const basic_tile_iterator&) const noexcept = default; +}; + +template +constexpr void swap(basic_tile_iterator& lhs, basic_tile_iterator& rhs) noexcept +{ + using std::swap; + swap(lhs.ptr, rhs.ptr); + swap(lhs.pos, rhs.ptr); +} + +extern template class basic_tile_iterator; +extern template class basic_tile_iterator; + +} // namespace Magnum::Examples + +namespace std { + +template +class iterator_traits> { + using T = typename Magnum::Examples::basic_tile_iterator::value_type; +public: + using difference_type = std::ptrdiff_t; + using value_type = T; + using reference = T&; + using pointer = T*; + using iterator_category = std::input_iterator_tag; //usually std::forward_iterator_tag or similar +}; + +} // namespace std diff --git a/src/tile.cpp b/src/tile.cpp index fe0e2da3..b1963415 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -2,6 +2,4 @@ namespace Magnum::Examples { - - } // namespace Magnum::Examples diff --git a/src/tile.hpp b/src/tile.hpp index f559ce79..d607a2d3 100644 --- a/src/tile.hpp +++ b/src/tile.hpp @@ -1,18 +1,15 @@ #pragma once #include "compat/defs.hpp" #include "compat/assert.hpp" +#include "tile-defs.hpp" #include #include -#include #include #include namespace Magnum::Examples { struct tile_atlas; -constexpr inline Vector3 TILE_SIZE = { 64, 64, 64 }; -constexpr inline std::size_t TILE_MAX_DIM = 16; -constexpr inline std::size_t TILE_COUNT = TILE_MAX_DIM*TILE_MAX_DIM; struct tile_image final { @@ -34,25 +31,4 @@ struct tile final DECLARE_DEPRECATED_COPY_OPERATOR(tile); }; -struct local_coords final { - std::uint8_t x = 0, y = 0; - explicit constexpr local_coords(std::size_t idx); - constexpr local_coords() = default; - constexpr local_coords(std::size_t x, std::size_t y); - constexpr local_coords(std::uint8_t x, std::uint8_t y) : x{x}, y{y} {} - constexpr std::size_t to_index() const { return y*TILE_MAX_DIM + x; } -}; - -constexpr local_coords::local_coords(std::size_t index) : - x{(std::uint8_t)(index % TILE_MAX_DIM)}, - y{(std::uint8_t)(index / TILE_MAX_DIM)} -{ -} - -constexpr local_coords::local_coords(std::size_t x, std::size_t y) - : x{(std::uint8_t)x}, y{(std::uint8_t)y} -{ - ASSERT(x <= 0xff && y <= 0xff); -} - } //namespace Magnum::Examples -- cgit v1.2.3