I can iterate through tiles using viewports.

This commit is contained in:
King_DuckZ 2014-12-14 13:13:10 +01:00
parent e17f77ae05
commit 7bf96669a5
9 changed files with 119 additions and 41 deletions

View file

@ -8,7 +8,7 @@
#include <vector> #include <vector>
namespace dk { namespace dk {
template <typename T, size_t D> template <size_t D>
class Viewport; class Viewport;
template <size_t D> template <size_t D>
@ -19,6 +19,9 @@ namespace dk {
LayerBase ( const coords& parCount, const coords& parTileSize, const coords& parMasterTileSize ); LayerBase ( const coords& parCount, const coords& parTileSize, const coords& parMasterTileSize );
virtual ~LayerBase ( void ) noexcept = default; 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: protected:
coords m_count; coords m_count;
coords m_tilesize; coords m_tilesize;
@ -27,6 +30,8 @@ namespace dk {
template <typename T, size_t D> template <typename T, size_t D>
class Layer : public LayerBase<D> { class Layer : public LayerBase<D> {
friend class Viewport<D>;
public: public:
typedef typename LayerBase<D>::coords coords; typedef typename LayerBase<D>::coords coords;
typedef TileStreamer<T, D> streamer_type; typedef TileStreamer<T, D> streamer_type;
@ -40,11 +45,11 @@ namespace dk {
Layer& operator= ( const Layer& ) = delete; Layer& operator= ( const Layer& ) = delete;
iterator begin ( void ); iterator begin ( void );
void setActiveViewport ( const coords& parFrom, const coords& parCount ); iterator end ( void );
virtual void preload ( const coords& parFrom, const coords& parTo );
private: private:
streamer_type m_streamer; streamer_type m_streamer;
Viewport<T, D> m_activeViewport;
std::vector<T> m_tiles; std::vector<T> m_tiles;
}; };

View file

@ -9,12 +9,15 @@
namespace dk { namespace dk {
namespace implem { namespace implem {
template <size_t D> template <size_t D>
inline size_t get_index_from_pos ( const Vector<CoordinateScalarType, D>& parPos, const Vector<CoordinateScalarType, D>& parSize ) a_pure; size_t get_index_from_pos ( const Vector<CoordinateScalarType, D>& parPos, const Vector<CoordinateScalarType, D>& parSize ) a_pure;
#if defined(NDEBUG) #if defined(NDEBUG)
template <> template <>
inline size_t get_index_from_pos<2> ( const Vector<CoordinateScalarType, 2>& parPos, const Vector<CoordinateScalarType, 2>& parSize ) a_pure; size_t get_index_from_pos<2> ( const Vector<CoordinateScalarType, 2>& parPos, const Vector<CoordinateScalarType, 2>& parSize ) a_pure;
#endif #endif
template <size_t D>
Vector<CoordinateScalarType, D> buildPastEndCoordinate ( const Vector<CoordinateScalarType, D>& parFrom, const Vector<CoordinateScalarType, D>& parTo ) a_pure;
} //namespace implem } //namespace implem
template <typename T, size_t D> template <typename T, size_t D>
@ -26,7 +29,7 @@ namespace dk {
TileIterator ( void ); TileIterator ( void );
TileIterator ( const TileIterator& parOther ) = default; TileIterator ( const TileIterator& parOther ) = default;
TileIterator ( std::vector<T>* parData, const coords& parFrom, const coords& parTo ); TileIterator ( std::vector<T>* parData, const coords& parFrom, const coords& parTo );
TileIterator ( std::vector<T>* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo, const coords& parTotal ); TileIterator ( std::vector<T>* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo );
~TileIterator ( void ) = default; ~TileIterator ( void ) = default;
const coords& position ( void ) const { return m_pos; } const coords& position ( void ) const { return m_pos; }
@ -38,14 +41,13 @@ namespace dk {
ptrdiff_t distance_to ( const TileIterator& parOther ); ptrdiff_t distance_to ( const TileIterator& parOther );
bool equal ( const TileIterator& parOther ) const; bool equal ( const TileIterator& parOther ) const;
T& dereference ( void ) const { return (*m_data)[get_current_index()]; } T& dereference ( void ) const { return (*m_data)[get_current_index()]; }
size_t get_current_index ( void ) const { return implem::get_index_from_pos<D>(m_pos, m_total); } size_t get_current_index ( void ) const { return implem::get_index_from_pos<D>(m_pos, m_areato - m_areafrom); }
coords m_pos; coords m_pos;
coords m_from; coords m_from;
coords m_to; coords m_to;
coords m_areafrom; coords m_areafrom;
coords m_areato; coords m_areato;
coords m_total;
std::vector<T>* m_data; std::vector<T>* m_data;
}; };
} //namespace dk } //namespace dk

View file

@ -27,6 +27,8 @@ namespace dk {
template <typename T> template <typename T>
Layer<T, D>& push_layer ( typename Layer<T, D>::streamer_type&& parStreamer, const coords& parSubdiv ); Layer<T, D>& push_layer ( typename Layer<T, D>::streamer_type&& parStreamer, const coords& parSubdiv );
void preload ( const coords& parFrom, const coords& parTo );
private: private:
const coords m_size; const coords m_size;
const coords m_tilesize; const coords m_tilesize;

View file

@ -6,28 +6,36 @@
#include "components/layer.hpp" #include "components/layer.hpp"
namespace dk { namespace dk {
template <size_t D>
class Tyler;
template <typename T, size_t D> template <typename T, size_t D>
class Layer; class Layer;
template <typename T, size_t D> template <size_t D>
class Viewport { class Viewport {
public: public:
typedef Vector<CoordinateScalarType, D> coords; typedef Vector<CoordinateScalarType, D> coords;
typedef typename Layer<T, D>::iterator iterator;
explicit Viewport ( Layer<T, D>& parLayer ); explicit Viewport ( Tyler<D>& parTyler );
Viewport ( Layer<T, D>& parLayer, const coords& parSize, const coords& parPos ); Viewport ( Tyler<D>& parTyler, const coords& parSize, const coords& parPos );
~Viewport ( void ) noexcept = default; ~Viewport ( void ) noexcept = default;
Viewport& operator= ( const Viewport& ) = default; Viewport& operator= ( const Viewport& ) = default;
void setSize ( const coords& parSize ) { m_size = parSize; } void setSize ( const coords& parSize );
void setFrom ( const coords& parFrom ) { m_position = parFrom; } void setFrom ( const coords& parFrom );
void setFromSize ( const coords& parFrom, const coords& parSize );
template <typename T>
typename Layer<T, D>::iterator begin ( Layer<T, D>& parLayer ) const;
template <typename T>
typename Layer<T, D>::iterator end ( Layer<T, D>& parLayer ) const;
private: private:
coords m_size; coords m_size;
coords m_position; coords m_position;
Layer<T, D>& m_layer; Tyler<D>& m_tyler;
}; };
} //namespace dk } //namespace dk

View file

@ -28,11 +28,9 @@ namespace dk {
template <typename T, size_t D> template <typename T, size_t D>
Layer<T, D>::Layer (const coords& parCount, const coords& parTileSize, const coords& parMasterTileSize, streamer_type&& parStreamer) : Layer<T, D>::Layer (const coords& parCount, const coords& parTileSize, const coords& parMasterTileSize, streamer_type&& parStreamer) :
LayerBase<D>(parCount, parTileSize, parMasterTileSize), LayerBase<D>(parCount, parTileSize, parMasterTileSize),
m_streamer(std::move(parStreamer)), m_streamer(std::move(parStreamer))
m_activeViewport(*this)
{ {
DK_ASSERT(m_streamer.tilesCount() == this->m_count); DK_ASSERT(m_streamer.tilesCount() == this->m_count);
setActiveViewport(coords(0), parCount);
} }
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
@ -45,12 +43,17 @@ namespace dk {
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
///-------------------------------------------------------------------------- ///--------------------------------------------------------------------------
template <typename T, size_t D> template <typename T, size_t D>
void Layer<T, D>::setActiveViewport (const coords& parFrom, const coords& parCount) { typename Layer<T, D>::iterator Layer<T, D>::end() {
return iterator(&m_tiles, implem::buildPastEndCoordinate<D>(coords(0), this->m_count), this->m_count);
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, size_t D>
void Layer<T, D>::preload (const coords& parFrom, const coords& parTo) {
m_tiles.clear(); m_tiles.clear();
const auto area = implem::area<D>(parCount); const auto area = implem::area<D>(parTo - parFrom);
m_tiles.reserve(area); m_tiles.reserve(area);
m_streamer.copy(m_tiles, parFrom, parFrom + parCount); m_streamer.copy(m_tiles, parFrom, parTo);
m_activeViewport.setFrom(parFrom);
m_activeViewport.setSize(parCount);
} }
} }

View file

@ -20,6 +20,16 @@ namespace dk {
return parPos.y() * parSize.x() + parPos.x(); return parPos.y() * parSize.x() + parPos.x();
} }
#endif #endif
template <size_t D>
inline Vector<CoordinateScalarType, D> buildPastEndCoordinate (const Vector<CoordinateScalarType, D>& parFrom, const Vector<CoordinateScalarType, D>& parTo) {
Vector<CoordinateScalarType, D> retval;
for (size_t d = 0; d < D - 1; ++d) {
retval[d] = parFrom[d];
}
retval[D - 1] = parTo[D - 1];
return retval;
}
} //namespace implem } //namespace implem
template <typename T, size_t D> template <typename T, size_t D>
@ -29,7 +39,6 @@ namespace dk {
m_to(CoordinateScalarType()), m_to(CoordinateScalarType()),
m_areafrom(CoordinateScalarType()), m_areafrom(CoordinateScalarType()),
m_areato(CoordinateScalarType()), m_areato(CoordinateScalarType()),
m_total(CoordinateScalarType()),
m_data(nullptr) m_data(nullptr)
{ {
} }
@ -41,20 +50,18 @@ namespace dk {
m_to(parTo), m_to(parTo),
m_areafrom(parFrom), m_areafrom(parFrom),
m_areato(parTo), m_areato(parTo),
m_total(parTo - parFrom),
m_data(parData) m_data(parData)
{ {
DK_ASSERT(parData); DK_ASSERT(parData);
} }
template <typename T, size_t D> template <typename T, size_t D>
TileIterator<T, D>::TileIterator (std::vector<T>* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo, const coords& parTotal) : TileIterator<T, D>::TileIterator (std::vector<T>* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo) :
m_pos(parFrom), m_pos(parFrom),
m_from(parFrom), m_from(parFrom),
m_to(parTo), m_to(parTo),
m_areafrom(parAreaFrom), m_areafrom(parAreaFrom),
m_areato(parAreaTo), m_areato(parAreaTo),
m_total(parTotal),
m_data(parData) m_data(parData)
{ {
DK_ASSERT(parData); DK_ASSERT(parData);

View file

@ -39,4 +39,13 @@ namespace dk {
m_layers.push_back(LayerPtr(newLayer)); m_layers.push_back(LayerPtr(newLayer));
return *newLayer; return *newLayer;
} }
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <size_t D>
void Tyler<D>::preload (const coords& parFrom, const coords& parTo) {
for (auto& layer : m_layers) {
layer->preload(parFrom, parTo);
}
}
} //namespace dk } //namespace dk

View file

@ -1,15 +1,52 @@
namespace dk { namespace dk {
template <typename T, size_t D> template <size_t D>
Viewport<T, D>::Viewport (Layer<T, D>& parLayer) : Viewport<D>::Viewport (Tyler<D>& parTyler) :
m_layer(parLayer) m_tyler(parTyler)
{ {
} }
template <typename T, size_t D> template <size_t D>
Viewport<T, D>::Viewport (Layer<T, D>& parLayer, const coords& parSize, const coords& parPos) : Viewport<D>::Viewport (Tyler<D>& parTyler, const coords& parSize, const coords& parPos) :
m_size(parSize), m_size(parSize),
m_position(parPos), m_position(parPos),
m_layer(parLayer) m_tyler(parTyler)
{ {
m_tyler.preload(m_position, m_position + m_size);
}
template <size_t D>
template <typename T>
typename Layer<T, D>::iterator Viewport<D>::begin (Layer<T, D>& parLayer) const {
typedef typename Layer<T, D>::iterator IterType;
return IterType(&parLayer.m_tiles, m_position, m_position + m_size);
}
template <size_t D>
template <typename T>
typename Layer<T, D>::iterator Viewport<D>::end (Layer<T, D>& parLayer) const {
typedef typename Layer<T, D>::iterator IterType;
const auto to(m_position + m_size);
return IterType(&parLayer.m_tiles, implem::buildPastEndCoordinate(m_position, to), to);
}
template <size_t D>
void Viewport<D>::setSize (const coords& parSize) {
m_size = parSize;
m_tyler.preload(m_position, m_position + m_size);
}
template <size_t D>
void Viewport<D>::setFrom (const coords& parFrom) {
m_position = parFrom;
m_tyler.preload(m_position, m_position + m_size);
}
template <size_t D>
void Viewport<D>::setFromSize (const coords& parFrom, const coords& parSize) {
m_position = parFrom;
m_size = parSize;
m_tyler.preload(m_position, m_position + m_size);
} }
} //namespace dk } //namespace dk

View file

@ -15,16 +15,21 @@ int main() {
std::cout << "Loading " << map1 << '\n'; std::cout << "Loading " << map1 << '\n';
auto bottom_layer = &tiler.push_layer<int>(dk::Layer<int, 2>::streamer_type(ifstreamptr(new std::ifstream(map1)))); auto bottom_layer = &tiler.push_layer<int>(dk::Layer<int, 2>::streamer_type(ifstreamptr(new std::ifstream(map1))));
std::cout << "Loading " << map2 << '\n'; //std::cout << "Loading " << map2 << '\n';
tiler.push_layer<char>(dk::Layer<char, 2>::streamer_type(ifstreamptr(new std::ifstream(map2))), dk::Vector<int, 2>(2)); //tiler.push_layer<char>(dk::Layer<char, 2>::streamer_type(ifstreamptr(new std::ifstream(map2))), dk::Vector<int, 2>(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(); int col = 0;
for (int z = 0; z < 10; ++z) { const auto tilecount = bottom_layer->count();
#if !defined(NDEBUG) for (auto tile : *bottom_layer) {
std::cout << "At tile " << ittest.position() << " value " << *ittest << '\n'; std::cout << tile;
#endif ++col;
++ittest; if (col == tilecount.x()) {
col = 0;
std::cout << '\n';
}
} }
} }