Refactoring in map reading code - part 2/2
This commit is contained in:
parent
436d738620
commit
2e0f59f189
2 changed files with 139 additions and 0 deletions
74
include/implem/mapstreamraw.inl
Normal file
74
include/implem/mapstreamraw.inl
Normal file
|
@ -0,0 +1,74 @@
|
|||
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 <std::size_t D, typename Device>
|
||||
inline
|
||||
typename std::enable_if<Device::MapDimensions == D, std::size_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 <std::size_t D, typename Device>
|
||||
inline
|
||||
typename std::enable_if<HasMapDimensions<Device>::result == false, std::size_t>::type err_mismatching_dimension (const Device*) noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
///---------------------------------------------------------------------
|
||||
///---------------------------------------------------------------------
|
||||
template <std::size_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 <std::size_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, std::size_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, std::size_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
|
65
include/mapreaders/mapstreamraw.hpp
Normal file
65
include/mapreaders/mapstreamraw.hpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
#ifndef id56E2396E102B4E10B20466D6B57A4C66
|
||||
#define id56E2396E102B4E10B20466D6B57A4C66
|
||||
|
||||
#include "mapreaders/mapstreambase.hpp"
|
||||
#include "implem/helpers.hpp"
|
||||
#include <cstddef>
|
||||
#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 <std::size_t D, typename Device>
|
||||
typename std::enable_if<Device::MapDimensions == D, std::size_t>::type err_mismatching_dimension ( const Device* ) noexcept a_pure;
|
||||
|
||||
template <std::size_t D, typename Device>
|
||||
typename std::enable_if<HasMapDimensions<Device>::result == false, std::size_t>::type err_mismatching_dimension ( const Device* ) noexcept a_pure;
|
||||
|
||||
template <std::size_t D, typename Device>
|
||||
typename std::enable_if<Device::MapDimensions == D, Vector<CoordinateScalarType, D>>::type retrieve_map_size_from_device ( Device* parDevice );
|
||||
|
||||
template <std::size_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 <std::size_t D, typename Device>
|
||||
typename Device::coords get_map_size_from_device ( const Device* parDevice );
|
||||
|
||||
template <typename T, std::size_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 "implem/mapstreamraw.inl"
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue