diff --git a/include/components/layer.hpp b/include/components/layer.hpp index 28819f2..7a368bc 100644 --- a/include/components/layer.hpp +++ b/include/components/layer.hpp @@ -8,7 +8,7 @@ #include namespace dk { - template + template class Viewport; template @@ -19,6 +19,9 @@ namespace dk { LayerBase ( const coords& parCount, const coords& parTileSize, const coords& parMasterTileSize ); virtual ~LayerBase ( void ) noexcept = default; + virtual void preload ( const coords& parFrom, const coords& parTo ) = 0; + coords count ( void ) const { return m_mastersize / m_tilesize * m_count; } + protected: coords m_count; coords m_tilesize; @@ -27,6 +30,8 @@ namespace dk { template class Layer : public LayerBase { + friend class Viewport; + public: typedef typename LayerBase::coords coords; typedef TileStreamer streamer_type; @@ -40,11 +45,11 @@ namespace dk { Layer& operator= ( const Layer& ) = delete; iterator begin ( void ); - void setActiveViewport ( const coords& parFrom, const coords& parCount ); + iterator end ( void ); + virtual void preload ( const coords& parFrom, const coords& parTo ); private: streamer_type m_streamer; - Viewport m_activeViewport; std::vector m_tiles; }; diff --git a/include/components/tileiterator.hpp b/include/components/tileiterator.hpp index 02ed2b0..ee61f7e 100644 --- a/include/components/tileiterator.hpp +++ b/include/components/tileiterator.hpp @@ -9,12 +9,15 @@ namespace dk { namespace implem { template - inline size_t get_index_from_pos ( const Vector& parPos, const Vector& parSize ) a_pure; + size_t get_index_from_pos ( const Vector& parPos, const Vector& parSize ) a_pure; #if defined(NDEBUG) template <> - inline size_t get_index_from_pos<2> ( const Vector& parPos, const Vector& parSize ) a_pure; + size_t get_index_from_pos<2> ( const Vector& parPos, const Vector& parSize ) a_pure; #endif + + template + Vector buildPastEndCoordinate ( const Vector& parFrom, const Vector& parTo ) a_pure; } //namespace implem template @@ -26,7 +29,7 @@ namespace dk { TileIterator ( void ); TileIterator ( const TileIterator& parOther ) = default; TileIterator ( std::vector* parData, const coords& parFrom, const coords& parTo ); - TileIterator ( std::vector* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo, const coords& parTotal ); + TileIterator ( std::vector* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo ); ~TileIterator ( void ) = default; const coords& position ( void ) const { return m_pos; } @@ -38,14 +41,13 @@ namespace dk { ptrdiff_t distance_to ( const TileIterator& parOther ); bool equal ( const TileIterator& parOther ) const; T& dereference ( void ) const { return (*m_data)[get_current_index()]; } - size_t get_current_index ( void ) const { return implem::get_index_from_pos(m_pos, m_total); } + size_t get_current_index ( void ) const { return implem::get_index_from_pos(m_pos, m_areato - m_areafrom); } coords m_pos; coords m_from; coords m_to; coords m_areafrom; coords m_areato; - coords m_total; std::vector* m_data; }; } //namespace dk diff --git a/include/components/tyler.hpp b/include/components/tyler.hpp index e3844bf..efd9aea 100644 --- a/include/components/tyler.hpp +++ b/include/components/tyler.hpp @@ -27,6 +27,8 @@ namespace dk { template Layer& push_layer ( typename Layer::streamer_type&& parStreamer, const coords& parSubdiv ); + void preload ( const coords& parFrom, const coords& parTo ); + private: const coords m_size; const coords m_tilesize; diff --git a/include/components/viewport.hpp b/include/components/viewport.hpp index 5c35f61..68834a0 100644 --- a/include/components/viewport.hpp +++ b/include/components/viewport.hpp @@ -6,28 +6,36 @@ #include "components/layer.hpp" namespace dk { + template + class Tyler; + template class Layer; - template + template class Viewport { public: typedef Vector coords; - typedef typename Layer::iterator iterator; - explicit Viewport ( Layer& parLayer ); - Viewport ( Layer& parLayer, const coords& parSize, const coords& parPos ); + explicit Viewport ( Tyler& parTyler ); + Viewport ( Tyler& parTyler, const coords& parSize, const coords& parPos ); ~Viewport ( void ) noexcept = default; Viewport& operator= ( const Viewport& ) = default; - void setSize ( const coords& parSize ) { m_size = parSize; } - void setFrom ( const coords& parFrom ) { m_position = parFrom; } + void setSize ( const coords& parSize ); + void setFrom ( const coords& parFrom ); + void setFromSize ( const coords& parFrom, const coords& parSize ); + + template + typename Layer::iterator begin ( Layer& parLayer ) const; + template + typename Layer::iterator end ( Layer& parLayer ) const; private: coords m_size; coords m_position; - Layer& m_layer; + Tyler& m_tyler; }; } //namespace dk diff --git a/include/implem/layer.inl b/include/implem/layer.inl index 3b9202d..dbdb853 100644 --- a/include/implem/layer.inl +++ b/include/implem/layer.inl @@ -28,11 +28,9 @@ namespace dk { template Layer::Layer (const coords& parCount, const coords& parTileSize, const coords& parMasterTileSize, streamer_type&& parStreamer) : LayerBase(parCount, parTileSize, parMasterTileSize), - m_streamer(std::move(parStreamer)), - m_activeViewport(*this) + m_streamer(std::move(parStreamer)) { DK_ASSERT(m_streamer.tilesCount() == this->m_count); - setActiveViewport(coords(0), parCount); } ///-------------------------------------------------------------------------- @@ -45,12 +43,17 @@ namespace dk { ///-------------------------------------------------------------------------- ///-------------------------------------------------------------------------- template - void Layer::setActiveViewport (const coords& parFrom, const coords& parCount) { + typename Layer::iterator Layer::end() { + return iterator(&m_tiles, implem::buildPastEndCoordinate(coords(0), this->m_count), this->m_count); + } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + template + void Layer::preload (const coords& parFrom, const coords& parTo) { m_tiles.clear(); - const auto area = implem::area(parCount); + const auto area = implem::area(parTo - parFrom); m_tiles.reserve(area); - m_streamer.copy(m_tiles, parFrom, parFrom + parCount); - m_activeViewport.setFrom(parFrom); - m_activeViewport.setSize(parCount); + m_streamer.copy(m_tiles, parFrom, parTo); } } diff --git a/include/implem/tileiterator.inl b/include/implem/tileiterator.inl index 88e3743..57b5633 100644 --- a/include/implem/tileiterator.inl +++ b/include/implem/tileiterator.inl @@ -20,6 +20,16 @@ namespace dk { return parPos.y() * parSize.x() + parPos.x(); } #endif + + template + inline Vector buildPastEndCoordinate (const Vector& parFrom, const Vector& parTo) { + Vector retval; + for (size_t d = 0; d < D - 1; ++d) { + retval[d] = parFrom[d]; + } + retval[D - 1] = parTo[D - 1]; + return retval; + } } //namespace implem template @@ -29,7 +39,6 @@ namespace dk { m_to(CoordinateScalarType()), m_areafrom(CoordinateScalarType()), m_areato(CoordinateScalarType()), - m_total(CoordinateScalarType()), m_data(nullptr) { } @@ -41,20 +50,18 @@ namespace dk { m_to(parTo), m_areafrom(parFrom), m_areato(parTo), - m_total(parTo - parFrom), m_data(parData) { DK_ASSERT(parData); } template - TileIterator::TileIterator (std::vector* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo, const coords& parTotal) : + TileIterator::TileIterator (std::vector* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo) : m_pos(parFrom), m_from(parFrom), m_to(parTo), m_areafrom(parAreaFrom), m_areato(parAreaTo), - m_total(parTotal), m_data(parData) { DK_ASSERT(parData); diff --git a/include/implem/tyler.inl b/include/implem/tyler.inl index ab65344..3fb6907 100644 --- a/include/implem/tyler.inl +++ b/include/implem/tyler.inl @@ -39,4 +39,13 @@ namespace dk { m_layers.push_back(LayerPtr(newLayer)); return *newLayer; } + + ///-------------------------------------------------------------------------- + ///-------------------------------------------------------------------------- + template + void Tyler::preload (const coords& parFrom, const coords& parTo) { + for (auto& layer : m_layers) { + layer->preload(parFrom, parTo); + } + } } //namespace dk diff --git a/include/implem/viewport.inl b/include/implem/viewport.inl index c0fb04b..9c0bd68 100644 --- a/include/implem/viewport.inl +++ b/include/implem/viewport.inl @@ -1,15 +1,52 @@ namespace dk { - template - Viewport::Viewport (Layer& parLayer) : - m_layer(parLayer) + template + Viewport::Viewport (Tyler& parTyler) : + m_tyler(parTyler) { } - template - Viewport::Viewport (Layer& parLayer, const coords& parSize, const coords& parPos) : + template + Viewport::Viewport (Tyler& parTyler, const coords& parSize, const coords& parPos) : m_size(parSize), m_position(parPos), - m_layer(parLayer) + m_tyler(parTyler) { + m_tyler.preload(m_position, m_position + m_size); + } + + template + template + typename Layer::iterator Viewport::begin (Layer& parLayer) const { + typedef typename Layer::iterator IterType; + + return IterType(&parLayer.m_tiles, m_position, m_position + m_size); + } + + template + template + typename Layer::iterator Viewport::end (Layer& parLayer) const { + typedef typename Layer::iterator IterType; + + const auto to(m_position + m_size); + return IterType(&parLayer.m_tiles, implem::buildPastEndCoordinate(m_position, to), to); + } + + template + void Viewport::setSize (const coords& parSize) { + m_size = parSize; + m_tyler.preload(m_position, m_position + m_size); + } + + template + void Viewport::setFrom (const coords& parFrom) { + m_position = parFrom; + m_tyler.preload(m_position, m_position + m_size); + } + + template + void Viewport::setFromSize (const coords& parFrom, const coords& parSize) { + m_position = parFrom; + m_size = parSize; + m_tyler.preload(m_position, m_position + m_size); } } //namespace dk diff --git a/src/main.cpp b/src/main.cpp index 5e40e71..d735d78 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,16 +15,21 @@ int main() { std::cout << "Loading " << map1 << '\n'; auto bottom_layer = &tiler.push_layer(dk::Layer::streamer_type(ifstreamptr(new std::ifstream(map1)))); - std::cout << "Loading " << map2 << '\n'; - tiler.push_layer(dk::Layer::streamer_type(ifstreamptr(new std::ifstream(map2))), dk::Vector(2)); + //std::cout << "Loading " << map2 << '\n'; + //tiler.push_layer(dk::Layer::streamer_type(ifstreamptr(new std::ifstream(map2))), dk::Vector(2)); + dk::Viewport<2> viewport(tiler, Tiler::coords(0), Tiler::coords(10, 6)); + dk::Viewport<2> viewport_small(tiler, Tiler::coords(1), Tiler::coords(9, 5)); { - auto ittest = bottom_layer->begin(); - for (int z = 0; z < 10; ++z) { -#if !defined(NDEBUG) - std::cout << "At tile " << ittest.position() << " value " << *ittest << '\n'; -#endif - ++ittest; + int col = 0; + const auto tilecount = bottom_layer->count(); + for (auto tile : *bottom_layer) { + std::cout << tile; + ++col; + if (col == tilecount.x()) { + col = 0; + std::cout << '\n'; + } } }