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>
namespace dk {
template <typename T, size_t D>
template <size_t D>
class Viewport;
template <size_t D>
@ -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 <typename T, size_t D>
class Layer : public LayerBase<D> {
friend class Viewport<D>;
public:
typedef typename LayerBase<D>::coords coords;
typedef TileStreamer<T, D> 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<T, D> m_activeViewport;
std::vector<T> m_tiles;
};

View file

@ -9,12 +9,15 @@
namespace dk {
namespace implem {
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)
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
template <size_t D>
Vector<CoordinateScalarType, D> buildPastEndCoordinate ( const Vector<CoordinateScalarType, D>& parFrom, const Vector<CoordinateScalarType, D>& parTo ) a_pure;
} //namespace implem
template <typename T, size_t D>
@ -26,7 +29,7 @@ namespace dk {
TileIterator ( void );
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, 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;
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<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_from;
coords m_to;
coords m_areafrom;
coords m_areato;
coords m_total;
std::vector<T>* m_data;
};
} //namespace dk

View file

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

View file

@ -6,28 +6,36 @@
#include "components/layer.hpp"
namespace dk {
template <size_t D>
class Tyler;
template <typename T, size_t D>
class Layer;
template <typename T, size_t D>
template <size_t D>
class Viewport {
public:
typedef Vector<CoordinateScalarType, D> coords;
typedef typename Layer<T, D>::iterator iterator;
explicit Viewport ( Layer<T, D>& parLayer );
Viewport ( Layer<T, D>& parLayer, const coords& parSize, const coords& parPos );
explicit Viewport ( Tyler<D>& parTyler );
Viewport ( Tyler<D>& 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 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:
coords m_size;
coords m_position;
Layer<T, D>& m_layer;
Tyler<D>& m_tyler;
};
} //namespace dk

View file

@ -28,11 +28,9 @@ namespace dk {
template <typename T, size_t D>
Layer<T, D>::Layer (const coords& parCount, const coords& parTileSize, const coords& parMasterTileSize, streamer_type&& parStreamer) :
LayerBase<D>(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 <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();
const auto area = implem::area<D>(parCount);
const auto area = implem::area<D>(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);
}
}

View file

@ -20,6 +20,16 @@ namespace dk {
return parPos.y() * parSize.x() + parPos.x();
}
#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
template <typename T, size_t D>
@ -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 <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_from(parFrom),
m_to(parTo),
m_areafrom(parAreaFrom),
m_areato(parAreaTo),
m_total(parTotal),
m_data(parData)
{
DK_ASSERT(parData);

View file

@ -39,4 +39,13 @@ namespace dk {
m_layers.push_back(LayerPtr(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

View file

@ -1,15 +1,52 @@
namespace dk {
template <typename T, size_t D>
Viewport<T, D>::Viewport (Layer<T, D>& parLayer) :
m_layer(parLayer)
template <size_t D>
Viewport<D>::Viewport (Tyler<D>& parTyler) :
m_tyler(parTyler)
{
}
template <typename T, size_t D>
Viewport<T, D>::Viewport (Layer<T, D>& parLayer, const coords& parSize, const coords& parPos) :
template <size_t D>
Viewport<D>::Viewport (Tyler<D>& 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 <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

View file

@ -15,16 +15,21 @@ int main() {
std::cout << "Loading " << map1 << '\n';
auto bottom_layer = &tiler.push_layer<int>(dk::Layer<int, 2>::streamer_type(ifstreamptr(new std::ifstream(map1))));
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));
//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));
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';
}
}
}