Refactoring in the data loading classes.

Lots of junk code removed, the architecture is now much simpler.
AsciiMapSource works as before.
This commit is contained in:
King_DuckZ 2015-05-25 01:37:20 +02:00
commit ea71478948
18 changed files with 134 additions and 427 deletions

View file

@ -0,0 +1,23 @@
#ifndef id372857FBD20C4DD2A9EDDB3A167682AA
#define id372857FBD20C4DD2A9EDDB3A167682AA
#include "doorkeeper/implem/maptypes.hpp"
#include "doorkeeper/primitivetypes.hpp"
#include <cstdint>
namespace dk {
template <typename T, uint32_t D>
class BaseMapSource {
public:
typedef dk::Vector<dk::CoordinateScalarType, D> coords;
BaseMapSource ( void ) = default;
virtual ~BaseMapSource ( void ) noexcept = default;
virtual void fetch ( std::vector<T>& parOut, const coords& parFrom, const coords& parTo ) = 0;
virtual const coords& mapSize ( void ) const = 0;
virtual MapTypes mapType ( void ) const = 0;
virtual int layersCount ( void ) const = 0;
};
} //namespace dk
#endif

View file

@ -0,0 +1,14 @@
#ifndef idE137842DE628405E9154561168FFEE60
#define idE137842DE628405E9154561168FFEE60
#include <exception>
namespace dk {
class DoorKeeperException : public std::exception {
};
class SizeMismatchException : public DoorKeeperException {
};
} //namespace dk
#endif

View file

@ -3,7 +3,7 @@
#include "doorkeeper/primitivetypes.hpp"
#include "doorkeeper/components/tileiterator.hpp"
#include "doorkeeper/components/tilemapdata.hpp"
#include "doorkeeper/components/basemapsource.hpp"
#include "doorkeeper/implem/helpers.hpp"
#include <algorithm>
#include <vector>
@ -52,7 +52,7 @@ namespace dk {
Layer ( const Layer& ) = delete;
Layer ( Layer&& ) = default;
Layer ( const coords& parTileSize, const coords& parMasterTileSize, TileMapData<T, D>& parTilemap );
Layer ( const coords& parTileSize, const coords& parMasterTileSize, BaseMapSource<T, D>* parTilemap );
virtual ~Layer ( void ) noexcept = default;
Layer& operator= ( const Layer& ) = delete;
@ -64,7 +64,7 @@ namespace dk {
virtual void onPreload ( const coords& parFrom, const coords& parTo );
std::vector<T> m_tiles;
TileMapData<T, D>& m_tilemap;
BaseMapSource<T, D>* m_tilemap;
};
} //namespace dk

View file

@ -1,35 +0,0 @@
#ifndef id8F5106DFABC14263ADF235C56E434207
#define id8F5106DFABC14263ADF235C56E434207
#include "doorkeeper/primitivetypes.hpp"
#include "doorkeeper/implem/compatibility.h"
#include "doorkeeper/implem/vector.hpp"
#include "doorkeeper/implem/helpers.hpp"
#include "doorkeeper/mapreaders/mapstreambase.hpp"
#include <cstddef>
#include <iterator>
#include <memory>
#include <algorithm>
#include <cstdint>
namespace dk {
template <typename T, uint32_t D>
class TileMapData {
public:
typedef Vector<CoordinateScalarType, D> coords;
TileMapData ( void ) = delete;
explicit TileMapData ( std::unique_ptr<MapStreamBase<D>>&& parStream );
~TileMapData ( void ) noexcept = default;
void fetch ( std::vector<T>& parOut, const coords& parFrom, const coords& parTo );
const coords& mapSize ( void ) const;
private:
const std::unique_ptr<MapStreamBase<D>> m_mapstream;
};
} //namespace dk
#include "doorkeeper/implem/tilemapdata.inl"
#endif

View file

@ -2,6 +2,7 @@
#define id6FB3FC97331449038D42AAAB4C01ABA1
#include "doorkeeper/components/layer.hpp"
#include "doorkeeper/components/exception.hpp"
#include <vector>
#include <cassert>
#include <ciso646>
@ -10,7 +11,7 @@
namespace dk {
template <typename T, uint32_t D>
class TileMapData;
class BaseMapSource;
template <uint32_t D>
class Tyler {
@ -20,21 +21,21 @@ namespace dk {
typedef typename LayerBase<D>::coords coords;
Tyler ( void ) = delete;
Tyler ( const coords& parSize, const coords& parTileSize );
explicit Tyler ( const coords& parTileSize );
~Tyler ( void ) noexcept = default;
typename coords::value_type tiles_count ( void ) const;
const coords& map_size ( void ) const { return m_size; }
template <typename T>
Layer<T, D>& push_layer ( TileMapData<T, D>& parTilemap );
Layer<T, D>& push_layer ( BaseMapSource<T, D>* parTilemap );
template <typename T>
Layer<T, D>& push_layer ( TileMapData<T, D>& parTilemap, const coords& parSubdiv );
Layer<T, D>& push_layer ( BaseMapSource<T, D>* parTilemap, const coords& parSubdiv );
void preload ( const coords& parFrom, const coords& parTo );
private:
const coords m_size;
coords m_size;
const coords m_tilesize;
LayerList m_layers;
};

View file

@ -5,6 +5,5 @@
#include "components/tyler.hpp"
#include "components/viewport.hpp"
#include "components/layer.hpp"
#include "components/tilemapdata.hpp"
#endif

View file

@ -0,0 +1,13 @@
#ifndef id6327FA76CFB44F65A459C69096EC65D5
#define id6327FA76CFB44F65A459C69096EC65D5
#include "doorkeeper.hpp"
namespace dk {
typedef Tyler<2>::coords coords2;
typedef Tyler<2> Tyler2d;
template <typename T> using Layer2d = Layer<T, 2>;
typedef Viewport<2> Viewport2d;
} //namespace dk
#endif

View file

@ -3,16 +3,19 @@
#include "doorkeeper/primitivetypes.hpp"
#include "doorkeeper/implem/vector.hpp"
#include <streambuf>
#include "doorkeeper/components/basemapsource.hpp"
#include <vector>
#include <boost/iostreams/categories.hpp> // source_tag
#include <memory>
namespace dkh {
class AsciiMapSource : public std::streambuf {
namespace implem {
typedef int AsciiMapTileType;
} //namespace implem
class AsciiMapSource : public dk::BaseMapSource<implem::AsciiMapTileType, 2> {
public:
typedef dk::Vector<dk::CoordinateScalarType, 2> coords;
typedef int MapTileType;
typedef boost::iostreams::source_tag category;
typedef implem::AsciiMapTileType MapTileType;
enum {
MapDimensions = 2
};
@ -20,22 +23,15 @@ namespace dkh {
AsciiMapSource ( void ) = delete;
AsciiMapSource ( const AsciiMapSource& ) = delete;
AsciiMapSource ( AsciiMapSource&& parOther ) = default;
AsciiMapSource ( const char* parFilename, const coords& parSize );
AsciiMapSource ( const std::string& parFilename, const coords& parSize );
AsciiMapSource ( std::istream& parData, const coords& parSize );
template <typename I>
AsciiMapSource ( I parDataFrom, I parDataTo, const coords& parSize );
~AsciiMapSource ( void ) noexcept = default;
AsciiMapSource ( const char* parFilename, const coords& parSize, dk::MapTypes parMapType );
AsciiMapSource ( const std::string& parFilename, const coords& parSize, dk::MapTypes parMapType );
AsciiMapSource ( std::istream& parData, const coords& parSize, dk::MapTypes parMapType );
virtual ~AsciiMapSource ( void ) noexcept = default;
const coords& mapSize ( void ) const noexcept { return m_mapSize; }
protected:
virtual int_type underflow ( void );
virtual int_type uflow ( void );
virtual int_type pbackfail ( int_type parCh );
virtual std::streamsize showmanyc ( void );
virtual pos_type seekoff ( off_type parOff, std::ios_base::seekdir parDir, std::ios_base::openmode parWhich );
virtual pos_type seekpos( pos_type parPos, std::ios_base::openmode parWhich );
virtual const coords& mapSize ( void ) const;
virtual void fetch ( std::vector<MapTileType>& parOut, const coords& parFrom, const coords& parTo );
virtual dk::MapTypes mapType ( void ) const;
virtual int layersCount ( void ) const;
private:
enum {
@ -47,6 +43,7 @@ namespace dkh {
std::vector<MapTileType> m_wholedata;
const coords m_mapSize;
std::size_t m_bytepos;
const dk::MapTypes m_mapType;
};
} //namespace dkh

View file

@ -26,10 +26,11 @@ namespace dk {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, uint32_t D>
Layer<T, D>::Layer (const coords& parTileSize, const coords& parMasterTileSize, TileMapData<T, D>& parTilemap) :
LayerBase<D>(parTilemap.mapSize(), parTileSize, parMasterTileSize),
Layer<T, D>::Layer (const coords& parTileSize, const coords& parMasterTileSize, BaseMapSource<T, D>* parTilemap) :
LayerBase<D>(parTilemap->mapSize(), parTileSize, parMasterTileSize),
m_tilemap(parTilemap)
{
DK_ASSERT(m_tilemap);
}
///--------------------------------------------------------------------------
@ -51,7 +52,7 @@ namespace dk {
template <typename T, uint32_t D>
void Layer<T, D>::onPreload (const coords& parFrom, const coords& parTo) {
m_tiles.clear();
m_tilemap.fetch(m_tiles, parFrom, parTo);
m_tilemap->fetch(m_tiles, parFrom, parTo);
#if !defined(NDEBUG)
std::cout << "Preloading layer from " << parFrom << " to " << parTo << '\n';
#endif

View file

@ -1,21 +0,0 @@
namespace dk {
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <uint32_t D>
MapStreamBase<D>::MapStreamBase (const coords& parMapSize) :
m_mapSize(parMapSize)
{
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <uint32_t D>
void MapStreamBase<D>::read (char* parOut, std::size_t parOutSize, const coords& parFrom, const coords& parTo) {
DK_ASSERT(parOut);
DK_ASSERT(parOutSize > 0);
DK_ASSERT(this->isReadable());
DK_ASSERT(parFrom < m_mapSize);
DK_ASSERT(parTo <= m_mapSize);
this->dataBlockRequested(parOut, parOutSize, parFrom, parTo);
}
} //namespace dk

View file

@ -1,74 +0,0 @@
namespace dk {
namespace implem {
///---------------------------------------------------------------------
///Only enabled if Device::MapDimensions is defined and is the same
///as D. The function's name is set to give a hint to the user as to
///why the error has occurred (they are trying to construct a
///TileMapData with a set dimension that is different from the one
///hardcoded in the device being passed in). The actual name could be
///something like get_device_dimensions().
///---------------------------------------------------------------------
template <uint32_t D, typename Device>
inline
typename std::enable_if<Device::MapDimensions == D, uint32_t>::type err_mismatching_dimension (const Device*) noexcept {
return Device::MapDimensions;
}
///---------------------------------------------------------------------
///Only enabled if Device::MapDimensions is not defined. The function's
///name is set to give a hint to the user as to why the error has
///occurred (they are trying to construct a TileMapData with a set
///dimension that is different from the one hardcoded in the device
///being passed in). The actual name could be something like
///get_device_dimensions().
///---------------------------------------------------------------------
template <uint32_t D, typename Device>
inline
typename std::enable_if<HasMapDimensions<Device>::result == false, uint32_t>::type err_mismatching_dimension (const Device*) noexcept {
return 0;
}
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <uint32_t D, typename Device>
inline
typename std::enable_if<Device::MapDimensions == D, Vector<CoordinateScalarType, D>>::type retrieve_map_size_from_device (Device* parDevice) {
return parDevice->mapSize();
}
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <uint32_t D, typename Device>
inline
typename std::enable_if<HasMapDimensions<Device>::result == false, Vector<CoordinateScalarType, D>>::type retrieve_map_size_from_device (Device* parDevice) {
return get_map_size_from_device<D>(parDevice);
}
} //namespace implem
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, uint32_t D>
template <typename Device>
MapStreamRaw<T, D>::MapStreamRaw (Device& parDevice) :
MapStreamBase<D>(implem::retrieve_map_size_from_device<D>(&parDevice)),
m_istream(&parDevice),
m_deviceHasDim(D == implem::err_mismatching_dimension<D>(&parDevice))
{
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, uint32_t D>
std::size_t MapStreamRaw<T, D>::dataBlockRequested (char* parOut, std::size_t parOutSize, const coords& parFrom, const coords& parTo) {
DK_ASSERT(parOut);
const std::size_t totalBlocks = implem::area(parTo - parFrom);
const std::size_t storableBlocks = parOutSize / sizeof(T);
const std::size_t readMem = sizeof(T) * std::min(storableBlocks, totalBlocks);
const std::streamoff readPos = static_cast<std::streamoff>(implem::area(parFrom));
m_istream.seekg(readPos, std::ios_base::beg);
m_istream.read(parOut, readMem);
return readMem;
}
} //namespace dk

View file

@ -0,0 +1,13 @@
#ifndef idBDAD2C64DEF94F1A8634605DF7CB1E7B
#define idBDAD2C64DEF94F1A8634605DF7CB1E7B
namespace dk {
enum MapTypes {
MapType_IsometricStaggered,
MapType_Isometric,
MapType_Orthogonal,
MapType_Hex
};
} //namespace dk
#endif

View file

@ -1,34 +0,0 @@
namespace dk {
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, uint32_t D>
TileMapData<T, D>::TileMapData (std::unique_ptr<MapStreamBase<D>>&& parStream) :
m_mapstream(std::move(parStream))
{
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, uint32_t D>
void TileMapData<T, D>::fetch (std::vector<T>& parOut, const coords& parFrom, const coords& parTo) {
DK_ASSERT(parFrom >= coords(0));
DK_ASSERT(parFrom < parTo);
DK_ASSERT(parFrom < m_mapstream->mapSize());
DK_ASSERT(parTo <= m_mapstream->mapSize());
const auto tileCount = implem::area(parTo - parFrom);
parOut.resize(tileCount);
m_mapstream->read(
reinterpret_cast<char*>(parOut.data()),
parOut.size() * sizeof(typename std::vector<T>::value_type),
parFrom,
parTo);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, uint32_t D>
const typename TileMapData<T, D>::coords& TileMapData<T, D>::mapSize() const {
return m_mapstream->mapSize();
}
} //namespace dk

View file

@ -2,11 +2,10 @@ namespace dk {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <uint32_t D>
Tyler<D>::Tyler (const coords& parSize, const coords& parTileSize) :
m_size(parSize),
Tyler<D>::Tyler (const coords& parTileSize) :
m_size(0),
m_tilesize(parTileSize)
{
assert(m_size.x() > 0 and m_size.y() > 0);
}
///--------------------------------------------------------------------------
@ -24,21 +23,25 @@ namespace dk {
///--------------------------------------------------------------------------
template <uint32_t D>
template <typename T>
Layer<T, D>& Tyler<D>::push_layer (TileMapData<T, D>& parTilemap) {
auto newLayer = new Layer<T, D>(m_tilesize, m_tilesize, parTilemap);
DK_ASSERT(newLayer->mapSize() == m_size);
DK_ASSERT(newLayer->count() == m_size);
m_layers.push_back(LayerPtr(newLayer));
return *newLayer;
Layer<T, D>& Tyler<D>::push_layer (BaseMapSource<T, D>* parTilemap) {
return push_layer(parTilemap, coords(static_cast<CoordinateScalarType>(1)));
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <uint32_t D>
template <typename T>
Layer<T, D>& Tyler<D>::push_layer (TileMapData<T, D>& parTilemap, const coords& parSubdiv) {
Layer<T, D>& Tyler<D>::push_layer (BaseMapSource<T, D>* parTilemap, const coords& parSubdiv) {
auto newLayer = new Layer<T, D>(m_tilesize / parSubdiv, m_tilesize, parTilemap);
DK_ASSERT(newLayer->mapSize() == m_size);
if (m_size == coords(0)) {
m_size = newLayer->mapSize();
}
else {
DK_ASSERT(newLayer->mapSize() == m_size);
if (newLayer->mapSize() != m_size) {
throw SizeMismatchException();
}
}
DK_ASSERT(newLayer->count() == m_size * parSubdiv);
m_layers.push_back(LayerPtr(newLayer));
return *newLayer;

View file

@ -1,33 +0,0 @@
#ifndef id3CAE7A32F0C3428EA125F91D261C0029
#define id3CAE7A32F0C3428EA125F91D261C0029
#include "doorkeeper/primitivetypes.hpp"
#include "doorkeeper/implem/vector.hpp"
#include <cstddef>
#include <cstdint>
namespace dk {
template <uint32_t D>
class MapStreamBase {
public:
typedef Vector<CoordinateScalarType, D> coords;
MapStreamBase ( void ) = delete;
explicit MapStreamBase ( const coords& parMapSize );
virtual ~MapStreamBase ( void ) noexcept = default;
virtual bool isReadable ( void ) const = 0;
virtual bool isWriteable ( void ) const = 0;
const coords& mapSize ( void ) const noexcept { return m_mapSize; }
void read ( char* parOut, std::size_t parOutSize, const coords& parFrom, const coords& parTo );
private:
virtual std::size_t dataBlockRequested ( char* parOut, std::size_t parOutSize, const coords& parFrom, const coords& parTo ) = 0;
const coords m_mapSize;
};
} //namespace dk
#include "doorkeeper/implem/mapstreambase.inl"
#endif

View file

@ -1,66 +0,0 @@
#ifndef id56E2396E102B4E10B20466D6B57A4C66
#define id56E2396E102B4E10B20466D6B57A4C66
#include "doorkeeper/mapreaders/mapstreambase.hpp"
#include "doorkeeper/implem/helpers.hpp"
#include <cstddef>
#include <cstdint>
#include <algorithm>
#include <type_traits>
#include <istream>
namespace dk {
namespace implem {
template <typename T>
class HasMapDimensions {
class yes { char m; };
class nope { yes m[2]; };
static yes deduce ( int a, int b = T::MapDimensions );
static nope deduce ( ... );
public:
enum {
result = (sizeof(yes) == sizeof(deduce(1)))
};
};
template <uint32_t D, typename Device>
typename std::enable_if<Device::MapDimensions == D, uint32_t>::type err_mismatching_dimension ( const Device* ) noexcept a_pure;
template <uint32_t D, typename Device>
typename std::enable_if<HasMapDimensions<Device>::result == false, uint32_t>::type err_mismatching_dimension ( const Device* ) noexcept a_pure;
template <uint32_t D, typename Device>
typename std::enable_if<Device::MapDimensions == D, Vector<CoordinateScalarType, D>>::type retrieve_map_size_from_device ( Device* parDevice );
template <uint32_t D, typename Device>
typename std::enable_if<HasMapDimensions<Device>::result == false, Vector<CoordinateScalarType, D>>::type retrieve_map_size_from_device ( Device* parDevice );
} //namespace implem
//Customization point - specialize to enable map size retrieval for Device
template <uint32_t D, typename Device>
typename Device::coords get_map_size_from_device ( const Device* parDevice );
template <typename T, uint32_t D>
class MapStreamRaw : public MapStreamBase<D> {
public:
typedef typename MapStreamBase<D>::coords coords;
MapStreamRaw ( void ) = delete;
template <typename Device>
explicit MapStreamRaw ( Device& parDevice );
virtual ~MapStreamRaw ( void ) noexcept = default;
virtual bool isReadable ( void ) const { return true; }
virtual bool isWriteable ( void ) const { return false; }
private:
virtual std::size_t dataBlockRequested ( char* parOut, std::size_t parOutSize, const coords& parFrom, const coords& parTo );
std::istream m_istream;
const bool m_deviceHasDim;
};
} //namespace dk
#include "doorkeeper/implem/mapstreamraw.inl"
#endif