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:
parent
1c5cb6299c
commit
ea71478948
18 changed files with 134 additions and 427 deletions
23
include/doorkeeper/components/basemapsource.hpp
Normal file
23
include/doorkeeper/components/basemapsource.hpp
Normal 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
|
14
include/doorkeeper/components/exception.hpp
Normal file
14
include/doorkeeper/components/exception.hpp
Normal 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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -5,6 +5,5 @@
|
|||
#include "components/tyler.hpp"
|
||||
#include "components/viewport.hpp"
|
||||
#include "components/layer.hpp"
|
||||
#include "components/tilemapdata.hpp"
|
||||
|
||||
#endif
|
||||
|
|
13
include/doorkeeper/doorkeeper2d.hpp
Normal file
13
include/doorkeeper/doorkeeper2d.hpp
Normal 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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
13
include/doorkeeper/implem/maptypes.hpp
Normal file
13
include/doorkeeper/implem/maptypes.hpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef idBDAD2C64DEF94F1A8634605DF7CB1E7B
|
||||
#define idBDAD2C64DEF94F1A8634605DF7CB1E7B
|
||||
|
||||
namespace dk {
|
||||
enum MapTypes {
|
||||
MapType_IsometricStaggered,
|
||||
MapType_Isometric,
|
||||
MapType_Orthogonal,
|
||||
MapType_Hex
|
||||
};
|
||||
} //namespace dk
|
||||
|
||||
#endif
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -8,21 +8,12 @@
|
|||
#include <sstream>
|
||||
|
||||
namespace dkh {
|
||||
namespace {
|
||||
char extractByte ( AsciiMapSource::MapTileType parVal, std::size_t parByte ) a_pure;
|
||||
|
||||
char extractByte (AsciiMapSource::MapTileType parVal, std::size_t parByte) {
|
||||
return static_cast<char>(
|
||||
(parVal >> (parByte * 8)) & 0xFF
|
||||
);
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
AsciiMapSource::AsciiMapSource (const char* parFilename, const coords& parSize) :
|
||||
AsciiMapSource::AsciiMapSource (const char* parFilename, const coords& parSize, dk::MapTypes parMapType) :
|
||||
m_mapSize(parSize),
|
||||
m_bytepos(0)
|
||||
m_bytepos(0),
|
||||
m_mapType(parMapType)
|
||||
{
|
||||
std::ifstream src(parFilename);
|
||||
parse_map_data(src);
|
||||
|
@ -30,9 +21,10 @@ namespace dkh {
|
|||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
AsciiMapSource::AsciiMapSource (const std::string& parFilename, const coords& parSize) :
|
||||
AsciiMapSource::AsciiMapSource (const std::string& parFilename, const coords& parSize, dk::MapTypes parMapType) :
|
||||
m_mapSize(parSize),
|
||||
m_bytepos(0)
|
||||
m_bytepos(0),
|
||||
m_mapType(parMapType)
|
||||
{
|
||||
std::ifstream src(parFilename);
|
||||
parse_map_data(src);
|
||||
|
@ -40,53 +32,14 @@ namespace dkh {
|
|||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
AsciiMapSource::AsciiMapSource (std::istream& parData, const coords& parSize) :
|
||||
AsciiMapSource::AsciiMapSource (std::istream& parData, const coords& parSize, dk::MapTypes parMapType) :
|
||||
m_mapSize(parSize),
|
||||
m_bytepos(0)
|
||||
m_bytepos(0),
|
||||
m_mapType(parMapType)
|
||||
{
|
||||
parse_map_data(parData);
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
AsciiMapSource::int_type AsciiMapSource::underflow() {
|
||||
if (m_bytepos == m_wholedata.size() * DataSize)
|
||||
return traits_type::eof();
|
||||
|
||||
const auto index = m_bytepos / DataSize;
|
||||
const auto byte = m_bytepos % DataSize;
|
||||
return traits_type::to_int_type(extractByte(m_wholedata[index], byte));
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
AsciiMapSource::int_type AsciiMapSource::uflow() {
|
||||
if (m_bytepos == m_wholedata.size() * DataSize)
|
||||
return traits_type::eof();
|
||||
|
||||
const auto retval = underflow();
|
||||
++m_bytepos;
|
||||
return retval;
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
AsciiMapSource::int_type AsciiMapSource::pbackfail (int_type parCh) {
|
||||
if (0 == m_bytepos or (parCh != traits_type::eof() and parCh != traits_type::to_int_type(extractByte(m_wholedata[m_bytepos / DataSize], m_bytepos % DataSize))))
|
||||
return traits_type::eof();
|
||||
|
||||
--m_bytepos;
|
||||
DK_ASSERT(underflow() == traits_type::to_int_type(parCh));
|
||||
return traits_type::to_int_type(parCh);
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
std::streamsize AsciiMapSource::showmanyc() {
|
||||
DK_ASSERT(m_bytepos <= m_wholedata.size() * DataSize);
|
||||
return m_wholedata.size() * DataSize - m_bytepos;
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
void AsciiMapSource::parse_map_data (std::istream& parSrc) {
|
||||
|
@ -128,65 +81,23 @@ namespace dkh {
|
|||
}
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
AsciiMapSource::pos_type AsciiMapSource::seekoff (off_type parOff, std::ios_base::seekdir parDir, std::ios_base::openmode parWhich) {
|
||||
using std::ios;
|
||||
|
||||
if (parWhich & ios::out)
|
||||
return traits_type::eof();
|
||||
|
||||
const std::size_t dataLength = DataSize * m_wholedata.size();
|
||||
if (parWhich & ios::in) {
|
||||
std::size_t desiredPos;
|
||||
|
||||
switch (parDir) {
|
||||
case ios::beg:
|
||||
desiredPos = static_cast<std::size_t>(parOff);
|
||||
break;
|
||||
case ios::cur:
|
||||
desiredPos = static_cast<std::size_t>(m_bytepos + parOff);
|
||||
break;
|
||||
case ios::end:
|
||||
desiredPos = static_cast<std::size_t>(dataLength - parOff);
|
||||
break;
|
||||
default:
|
||||
m_bytepos = static_cast<std::size_t>(dataLength);
|
||||
return traits_type::eof();
|
||||
}
|
||||
if (desiredPos >= dataLength) {
|
||||
m_bytepos = dataLength;
|
||||
return traits_type::eof();
|
||||
}
|
||||
else {
|
||||
m_bytepos = desiredPos;
|
||||
return static_cast<pos_type>(m_bytepos);
|
||||
}
|
||||
}
|
||||
m_bytepos = dataLength;
|
||||
return traits_type::eof();
|
||||
const AsciiMapSource::coords& AsciiMapSource::mapSize() const {
|
||||
return m_mapSize;
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
AsciiMapSource::pos_type AsciiMapSource::seekpos(pos_type parPos, std::ios_base::openmode parWhich) {
|
||||
using std::ios;
|
||||
void AsciiMapSource::fetch (std::vector<MapTileType>& parOut, const coords& parFrom, const coords& parTo) {
|
||||
const std::size_t from = parFrom.x() + parFrom.y() * m_mapSize.x();
|
||||
const std::size_t to = parTo.x() + parTo.y() * m_mapSize.x() + 1;
|
||||
DK_ASSERT(to >= from);
|
||||
parOut.resize(to - from);
|
||||
std::copy(m_wholedata.begin() + from, m_wholedata.begin() + to, parOut.begin());
|
||||
}
|
||||
|
||||
if (parWhich & ios::out)
|
||||
return traits_type::eof();
|
||||
dk::MapTypes AsciiMapSource::mapType() const {
|
||||
return m_mapType;
|
||||
}
|
||||
|
||||
const std::size_t dataLength = DataSize * m_wholedata.size();
|
||||
if (parWhich & ios::in) {
|
||||
if (static_cast<std::size_t>(parPos) >= dataLength) {
|
||||
m_bytepos = dataLength;
|
||||
return traits_type::eof();
|
||||
}
|
||||
else {
|
||||
m_bytepos = static_cast<std::size_t>(parPos);
|
||||
return static_cast<pos_type>(m_bytepos);
|
||||
}
|
||||
}
|
||||
m_bytepos = static_cast<std::size_t>(parPos);
|
||||
return static_cast<pos_type>(m_bytepos);
|
||||
int AsciiMapSource::layersCount() const {
|
||||
return 1;
|
||||
}
|
||||
} //namespace dkh
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "platformstrings.h"
|
||||
#include "doorkeeper/helpers/asciimapsource.hpp"
|
||||
#include "doorkeeper/helpers/tilecoordinates.hpp"
|
||||
#include "doorkeeper/mapreaders/mapstreamraw.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
@ -18,8 +17,7 @@
|
|||
|
||||
template <typename Device, typename Tile>
|
||||
struct LayerWithData {
|
||||
std::unique_ptr<dk::TileMapData<Tile, 2>> tilemap;
|
||||
std::unique_ptr<Device> device;
|
||||
std::unique_ptr<dkh::AsciiMapSource> device;
|
||||
dk::Layer<Tile, 2>* layer;
|
||||
std::string path;
|
||||
};
|
||||
|
@ -46,7 +44,6 @@ namespace {
|
|||
|
||||
int main() {
|
||||
typedef dk::Tyler<2>::coords coords2;
|
||||
using dk::TileMapData;
|
||||
using dkh::AsciiMapSource;
|
||||
|
||||
SDLSimple sdl_init;
|
||||
|
@ -65,7 +62,7 @@ int main() {
|
|||
&SDL_DestroyRenderer
|
||||
);
|
||||
|
||||
dk::Tyler<2> tiler(coords2(10, 8), coords2(64));
|
||||
dk::Tyler<2> tiler(coords2(64));
|
||||
|
||||
LayerWithData<AsciiMapSource, int> bottomLayer;
|
||||
addLayer(tiler, bottomLayer, DATA_PATH"/test.map");
|
||||
|
@ -148,10 +145,8 @@ namespace {
|
|||
|
||||
void addLayer (dk::Tyler<2>& parTiler, LayerWithData<dkh::AsciiMapSource, int>& parLayerInfo, const char* parPath) {
|
||||
parLayerInfo.path = parPath;
|
||||
parLayerInfo.device = std::unique_ptr<dkh::AsciiMapSource>(new dkh::AsciiMapSource(parLayerInfo.path, dkh::AsciiMapSource::coords(10, 8)));
|
||||
std::unique_ptr<dk::MapStreamRaw<int, 2>> stream(new dk::MapStreamRaw<int, 2>(*parLayerInfo.device));
|
||||
parLayerInfo.tilemap = std::unique_ptr<dk::TileMapData<int, 2>>(new dk::TileMapData<int, 2>(std::move(stream)));
|
||||
parLayerInfo.layer = &parTiler.push_layer(*parLayerInfo.tilemap);
|
||||
parLayerInfo.device.reset(new dkh::AsciiMapSource(parLayerInfo.path, dkh::AsciiMapSource::coords(10, 8), dk::MapType_IsometricStaggered));
|
||||
parLayerInfo.layer = &parTiler.push_layer(parLayerInfo.device.get());
|
||||
}
|
||||
|
||||
void printViewport (const dk::Viewport<2>& parView, const dk::Layer<int, 2>& parLayer) {
|
||||
|
|
Loading…
Add table
Reference in a new issue