Compare commits
9 commits
Author | SHA1 | Date | |
---|---|---|---|
fd3ea392ac | |||
2841c606c5 | |||
c02157de57 | |||
5637bf4e5c | |||
4df71e46a1 | |||
eecd1d1649 | |||
bf612bc7fd | |||
a7dd322da6 | |||
9ccbe880a4 |
23 changed files with 1036 additions and 170 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@ cscope.in.out
|
||||||
cscope.po.out
|
cscope.po.out
|
||||||
*.idea/
|
*.idea/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
*.kdev4
|
||||||
|
|
|
@ -10,6 +10,7 @@ add_definitions(
|
||||||
-DWITH_VECTOR_IOSTREAM
|
-DWITH_VECTOR_IOSTREAM
|
||||||
-DUSE_MANUAL_TYPENAMES
|
-DUSE_MANUAL_TYPENAMES
|
||||||
-DVWR_DIM_TYPE=uint32_t
|
-DVWR_DIM_TYPE=uint32_t
|
||||||
|
-DBOOST_RESULT_OF_USE_DECLTYPE
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(Boost 1.53.0 REQUIRED)
|
find_library(Boost 1.53.0 REQUIRED)
|
||||||
|
@ -30,7 +31,7 @@ set(gdb_scripts_path "${CMAKE_CURRENT_SOURCE_DIR}/tools/gdb")
|
||||||
|
|
||||||
#add_subdirectory(lib/sprout)
|
#add_subdirectory(lib/sprout)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(test)
|
#add_subdirectory(test)
|
||||||
add_subdirectory(game)
|
add_subdirectory(game)
|
||||||
#add_subdirectory(tools/mapconv)
|
#add_subdirectory(tools/mapconv)
|
||||||
add_subdirectory(test/gtest-1.7.0)
|
add_subdirectory(test/gtest-1.7.0)
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "doorkeeper/primitivetypes.hpp"
|
#include "doorkeeper/primitivetypes.hpp"
|
||||||
#include "doorkeeper/components/tileiterator.hpp"
|
#include "doorkeeper/components/tileiterator.hpp"
|
||||||
#include "doorkeeper/components/basemapsource.hpp"
|
#include "doorkeeper/components/basemapsource.hpp"
|
||||||
|
#include "doorkeeper/components/viewport.hpp"
|
||||||
#include "doorkeeper/implem/helpers.hpp"
|
#include "doorkeeper/implem/helpers.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -32,9 +33,6 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace dk {
|
namespace dk {
|
||||||
template <uint32_t D>
|
|
||||||
class Viewport;
|
|
||||||
|
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
class LayerBase {
|
class LayerBase {
|
||||||
public:
|
public:
|
||||||
|
@ -44,7 +42,10 @@ namespace dk {
|
||||||
virtual ~LayerBase ( void ) noexcept = default;
|
virtual ~LayerBase ( void ) noexcept = default;
|
||||||
|
|
||||||
void preload ( const coords& parFrom, const coords& parTo );
|
void preload ( const coords& parFrom, const coords& parTo );
|
||||||
const coords& mapSize ( void ) const { return m_count; }
|
const coords& map_size ( void ) const { return m_count; }
|
||||||
|
const coords& tile_size ( void ) const { return m_tilesize; }
|
||||||
|
|
||||||
|
virtual void each_tile ( const Viewport<D>& parViewport ) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
coords m_count;
|
coords m_count;
|
||||||
|
@ -65,10 +66,12 @@ namespace dk {
|
||||||
typedef typename LayerBase<D>::coords coords;
|
typedef typename LayerBase<D>::coords coords;
|
||||||
typedef TileIterator<T, D> iterator;
|
typedef TileIterator<T, D> iterator;
|
||||||
typedef TileIterator<const T, D> const_iterator;
|
typedef TileIterator<const T, D> const_iterator;
|
||||||
|
typedef std::function<void(const Layer<T, D>&, const T&)> EachTileCallback;
|
||||||
|
|
||||||
Layer ( const Layer& ) = delete;
|
Layer ( const Layer& ) = delete;
|
||||||
Layer ( Layer&& ) = default;
|
Layer ( Layer&& ) = default;
|
||||||
Layer ( const coords& parTileSize, BaseMapSource<D>* parTilemap );
|
explicit Layer ( BaseMapSource<D>* parTilemap );
|
||||||
|
Layer ( BaseMapSource<D>* parTilemap, EachTileCallback parEachTile );
|
||||||
virtual ~Layer ( void ) noexcept = default;
|
virtual ~Layer ( void ) noexcept = default;
|
||||||
|
|
||||||
Layer& operator= ( const Layer& ) = delete;
|
Layer& operator= ( const Layer& ) = delete;
|
||||||
|
@ -76,10 +79,13 @@ namespace dk {
|
||||||
iterator begin ( void );
|
iterator begin ( void );
|
||||||
iterator end ( void );
|
iterator end ( void );
|
||||||
|
|
||||||
|
virtual void each_tile ( const Viewport<D>& parViewport ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void onPreload ( const coords& parFrom, const coords& parTo );
|
virtual void onPreload ( const coords& parFrom, const coords& parTo );
|
||||||
|
|
||||||
std::vector<T> m_tiles;
|
std::vector<T> m_tiles;
|
||||||
|
EachTileCallback m_each_tile;
|
||||||
BaseMapSource<D>* m_tilemap;
|
BaseMapSource<D>* m_tilemap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
73
include/doorkeeper/components/layeredviewport.hpp
Normal file
73
include/doorkeeper/components/layeredviewport.hpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of DoorKeeper.
|
||||||
|
*
|
||||||
|
* DoorKeeper is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DoorKeeper is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with DoorKeeper. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef id83407244096746CDBFF64D23F0B1701A
|
||||||
|
#define id83407244096746CDBFF64D23F0B1701A
|
||||||
|
|
||||||
|
#include "doorkeeper/primitivetypes.hpp"
|
||||||
|
#include "doorkeeper/components/viewport.hpp"
|
||||||
|
#include "doorkeeper/components/tyler.hpp"
|
||||||
|
#include "doorkeeper/components/layer.hpp"
|
||||||
|
#include "doorkeeper/implem/iterableviewport.hpp"
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
#include <utility>
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
|
namespace dk {
|
||||||
|
template <uint32_t D>
|
||||||
|
class Tyler;
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
class LayeredViewport {
|
||||||
|
struct ViewportItem;
|
||||||
|
typedef std::vector<ViewportItem> ViewportList;
|
||||||
|
public:
|
||||||
|
typedef VectorT<CoordinateAccumType, D> coords_f;
|
||||||
|
typedef boost::transform_iterator<boost::function<IterableViewport<D>(const LayerBase<D>&)>, typename Tyler<D>::iterator> iterator;
|
||||||
|
typedef boost::transform_iterator<boost::function<const IterableViewport<D>(const LayerBase<D>&)>, typename Tyler<D>::const_iterator> const_iterator;
|
||||||
|
|
||||||
|
LayeredViewport ( const LayeredViewport<D>& ) = delete;
|
||||||
|
LayeredViewport ( LayeredViewport<D>&& parOther );
|
||||||
|
explicit LayeredViewport ( Tyler<D>& parTyler );
|
||||||
|
~LayeredViewport ( void ) noexcept;
|
||||||
|
|
||||||
|
LayeredViewport<D>& operator+= ( const coords_f& parValue );
|
||||||
|
LayeredViewport<D>& operator-= ( const coords_f& parValue );
|
||||||
|
|
||||||
|
void on_layer ( const LayerBase<D>& parLayer, bool parAdded );
|
||||||
|
iterator begin ( void );
|
||||||
|
const_iterator begin ( void ) const;
|
||||||
|
iterator end ( void );
|
||||||
|
const_iterator end ( void ) const;
|
||||||
|
IterableViewport<D> viewport ( const LayerBase<D>& parLayer );
|
||||||
|
const IterableViewport<D> viewport ( const LayerBase<D>& parLayer ) const;
|
||||||
|
|
||||||
|
LayeredViewport<D>& operator= ( const LayeredViewport<D>& ) = delete;
|
||||||
|
LayeredViewport<D>& operator= ( LayeredViewport<D>&& ) = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ViewportList m_views;
|
||||||
|
Tyler<D>* m_tyler;
|
||||||
|
typename Tyler<D>::LayerObsID m_tyler_id;
|
||||||
|
};
|
||||||
|
} //namespace dk
|
||||||
|
|
||||||
|
#include "doorkeeper/implem/layeredviewport.inl"
|
||||||
|
|
||||||
|
#endif
|
|
@ -20,10 +20,13 @@
|
||||||
|
|
||||||
#include "doorkeeper/components/layer.hpp"
|
#include "doorkeeper/components/layer.hpp"
|
||||||
#include "doorkeeper/components/exception.hpp"
|
#include "doorkeeper/components/exception.hpp"
|
||||||
|
#include "doorkeeper/implem/idmanager.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <boost/iterator/indirect_iterator.hpp>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace dk {
|
namespace dk {
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
|
@ -33,29 +36,36 @@ namespace dk {
|
||||||
class Tyler {
|
class Tyler {
|
||||||
typedef std::unique_ptr<LayerBase<D>> LayerPtr;
|
typedef std::unique_ptr<LayerBase<D>> LayerPtr;
|
||||||
typedef std::vector<LayerPtr> LayerList;
|
typedef std::vector<LayerPtr> LayerList;
|
||||||
|
typedef IDManager<7, 9> LayerObsIDManager;
|
||||||
public:
|
public:
|
||||||
typedef typename LayerBase<D>::coords coords;
|
typedef typename LayerBase<D>::coords coords;
|
||||||
|
typedef boost::indirect_iterator<typename LayerList::iterator> iterator;
|
||||||
|
typedef boost::indirect_iterator<typename LayerList::const_iterator> const_iterator;
|
||||||
|
typedef std::function<void(const LayerBase<D>&, bool) noexcept> layer_callback;
|
||||||
|
typedef LayerObsIDManager::value_type LayerObsID;
|
||||||
|
|
||||||
Tyler ( void ) = delete;
|
Tyler ( void );
|
||||||
Tyler ( Tyler&& ) = default;
|
Tyler ( Tyler&& ) = default;
|
||||||
Tyler ( const coords& parMapSize, const coords& parTileSize );
|
|
||||||
~Tyler ( void ) noexcept = default;
|
~Tyler ( void ) noexcept = default;
|
||||||
|
|
||||||
typename coords::scalar_type tiles_count ( void ) const;
|
|
||||||
const coords& map_size ( void ) const { return m_size; }
|
|
||||||
const coords& tile_size ( void ) const { return m_tilesize; }
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Layer<T, D>& push_layer ( BaseMapSource<D>* parTilemap, int parIndex );
|
Layer<T, D>& push_layer ( BaseMapSource<D>* parTilemap, int parIndex );
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void push_layer_void ( BaseMapSource<D>* parTilemap, int parIndex );
|
void push_layer_void ( BaseMapSource<D>* parTilemap, int parIndex );
|
||||||
|
|
||||||
|
iterator begin ( void );
|
||||||
|
const_iterator begin ( void ) const;
|
||||||
|
iterator end ( void );
|
||||||
|
const_iterator end ( void ) const;
|
||||||
|
|
||||||
void preload ( const coords& parFrom, const coords& parTo );
|
void preload ( const coords& parFrom, const coords& parTo );
|
||||||
|
LayerObsID register_for_layeradd ( layer_callback parCallback );
|
||||||
|
void unregister_for_layeradd ( LayerObsID parID );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
coords m_size;
|
LayerObsIDManager m_layerobs_idmanager;
|
||||||
const coords m_tilesize;
|
|
||||||
LayerList m_layers;
|
LayerList m_layers;
|
||||||
|
std::vector<layer_callback> m_layerobs_callbacks;
|
||||||
};
|
};
|
||||||
} //namespace dk
|
} //namespace dk
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include "doorkeeper/primitivetypes.hpp"
|
#include "doorkeeper/primitivetypes.hpp"
|
||||||
#include "doorkeeper/components/tileiterator.hpp"
|
#include "doorkeeper/components/tileiterator.hpp"
|
||||||
#include "doorkeeper/components/layer.hpp"
|
|
||||||
#include "doorkeeper/components/tilecoords.hpp"
|
#include "doorkeeper/components/tilecoords.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -29,8 +28,24 @@ namespace dk {
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
class Tyler;
|
class Tyler;
|
||||||
|
|
||||||
template <typename T, uint32_t D>
|
template <uint32_t D>
|
||||||
class Layer;
|
class LayerBase;
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
struct TileInfo {
|
||||||
|
typedef Vector<D> coords;
|
||||||
|
|
||||||
|
TileInfo ( const LayerBase<D>& parLayer );
|
||||||
|
TileInfo ( const TileInfo<D>& ) = default;
|
||||||
|
TileInfo ( TileInfo<D>&& ) = default;
|
||||||
|
|
||||||
|
bool operator== ( const TileInfo& parOther ) const;
|
||||||
|
TileInfo& operator= ( const TileInfo<D>& ) = default;
|
||||||
|
TileInfo& operator= ( TileInfo<D>&& ) = default;
|
||||||
|
|
||||||
|
coords tile_size;
|
||||||
|
coords map_size;
|
||||||
|
};
|
||||||
|
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
class Viewport {
|
class Viewport {
|
||||||
|
@ -39,37 +54,28 @@ namespace dk {
|
||||||
typedef VectorT<CoordinateAccumType, D> coords_f;
|
typedef VectorT<CoordinateAccumType, D> coords_f;
|
||||||
|
|
||||||
Viewport ( const Viewport& parOther ) = default;
|
Viewport ( const Viewport& parOther ) = default;
|
||||||
explicit Viewport ( Tyler<D>& parTyler );
|
Viewport ( Tyler<D>& parTyler, const TileInfo<D>* parTileInfo );
|
||||||
Viewport ( Tyler<D>& parTyler, const coords& parSize, const coords& parPos );
|
Viewport ( Tyler<D>& parTyler, const TileInfo<D>* parTileInfo, const coords& parPos );
|
||||||
~Viewport ( void ) noexcept = default;
|
~Viewport ( void ) noexcept = default;
|
||||||
|
|
||||||
Viewport& operator= ( const Viewport& ) = default;
|
Viewport& operator= ( const Viewport& ) = default;
|
||||||
|
Viewport& operator= ( Viewport&& ) = default;
|
||||||
Viewport& operator+= ( const coords_f& parValue );
|
Viewport& operator+= ( const coords_f& parValue );
|
||||||
Viewport& operator-= ( const coords_f& parValue );
|
Viewport& operator-= ( const coords_f& parValue );
|
||||||
|
|
||||||
void setFrom ( const coords& parFrom );
|
void setFrom ( const coords& parFrom );
|
||||||
coords size ( void ) const;
|
coords size ( void ) const;
|
||||||
coords pixel_offset ( void ) const;
|
coords pixel_offset ( void ) const;
|
||||||
|
const coords& upper ( void ) const;
|
||||||
template <typename T>
|
const coords& block_position ( void ) const;
|
||||||
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;
|
|
||||||
template <typename T> inline
|
|
||||||
typename Layer<T, D>::const_iterator begin ( const Layer<T, D>& parLayer ) const a_always_inline;
|
|
||||||
template <typename T> inline
|
|
||||||
typename Layer<T, D>::const_iterator end ( const Layer<T, D>& parLayer ) const a_always_inline;
|
|
||||||
template <typename T>
|
|
||||||
typename Layer<T, D>::const_iterator cbegin ( const Layer<T, D>& parLayer ) const;
|
|
||||||
template <typename T>
|
|
||||||
typename Layer<T, D>::const_iterator cend ( const Layer<T, D>& parLayer ) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void clip_pixel_offset ( void );
|
void clip_pixel_offset ( void );
|
||||||
|
|
||||||
TileCoords<D> m_view;
|
TileCoords<D> m_view;
|
||||||
Tyler<D>& m_tyler;
|
|
||||||
coords_f m_pixel_offset;
|
coords_f m_pixel_offset;
|
||||||
|
Tyler<D>* m_tyler;
|
||||||
|
const TileInfo<D>* m_tile_info;
|
||||||
};
|
};
|
||||||
} //namespace dk
|
} //namespace dk
|
||||||
|
|
||||||
|
|
|
@ -22,5 +22,6 @@
|
||||||
#include "components/tyler.hpp"
|
#include "components/tyler.hpp"
|
||||||
#include "components/viewport.hpp"
|
#include "components/viewport.hpp"
|
||||||
#include "components/layer.hpp"
|
#include "components/layer.hpp"
|
||||||
|
#include "components/layeredviewport.hpp"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
83
include/doorkeeper/implem/dktypes.hpp
Normal file
83
include/doorkeeper/implem/dktypes.hpp
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of DoorKeeper.
|
||||||
|
*
|
||||||
|
* DoorKeeper is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DoorKeeper is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with DoorKeeper. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef idA7B80E7E36484499AD624450C00B1DCA
|
||||||
|
#define idA7B80E7E36484499AD624450C00B1DCA
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
namespace dk {
|
||||||
|
namespace implem {
|
||||||
|
class ERROR_inttype_not_available {
|
||||||
|
ERROR_inttype_not_available();
|
||||||
|
};
|
||||||
|
|
||||||
|
template<bool FIRST, typename A, typename B>
|
||||||
|
struct select {
|
||||||
|
typedef A type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename A, typename B>
|
||||||
|
struct select<false, A, B> {
|
||||||
|
typedef B type;
|
||||||
|
};
|
||||||
|
} // namespace implem
|
||||||
|
|
||||||
|
// Retrieves a signed/unsigned integer type with sizeof( T ) == BYTES
|
||||||
|
template<unsigned BYTES, bool SIGNED>
|
||||||
|
struct int_t {
|
||||||
|
typedef typename implem::select<sizeof(signed char) * CHAR_BIT == CHAR_BIT * BYTES, signed char,
|
||||||
|
typename implem::select<sizeof(signed short) * CHAR_BIT == CHAR_BIT * BYTES, signed short,
|
||||||
|
typename implem::select<sizeof(signed int) * CHAR_BIT == CHAR_BIT * BYTES, signed int,
|
||||||
|
typename implem::select<sizeof(signed long) * CHAR_BIT == CHAR_BIT * BYTES, signed long,
|
||||||
|
typename implem::select<sizeof(signed long long) * CHAR_BIT == CHAR_BIT * BYTES, signed long long,
|
||||||
|
implem::ERROR_inttype_not_available>::type>::type>::type>::type>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<unsigned BYTES>
|
||||||
|
struct int_t<BYTES, false> {
|
||||||
|
typedef typename implem::select<sizeof(unsigned char) * CHAR_BIT == CHAR_BIT * BYTES, unsigned char,
|
||||||
|
typename implem::select<sizeof(unsigned short) * CHAR_BIT == CHAR_BIT * BYTES, unsigned short,
|
||||||
|
typename implem::select<sizeof(unsigned int) * CHAR_BIT == CHAR_BIT * BYTES, unsigned int,
|
||||||
|
typename implem::select<sizeof(unsigned long) * CHAR_BIT == CHAR_BIT * BYTES, unsigned long,
|
||||||
|
typename implem::select<sizeof(unsigned long long) * CHAR_BIT == CHAR_BIT * BYTES, unsigned long long,
|
||||||
|
implem::ERROR_inttype_not_available>::type>::type>::type>::type>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Retrieves the smallest unsigned integer type with sizeof( T ) >= BYTES
|
||||||
|
template<unsigned BYTES>
|
||||||
|
struct uint_t_min {
|
||||||
|
typedef typename implem::select<sizeof(unsigned char) * CHAR_BIT >= CHAR_BIT * BYTES, unsigned char,
|
||||||
|
typename implem::select<sizeof(unsigned short) * CHAR_BIT >= CHAR_BIT * BYTES, unsigned short,
|
||||||
|
typename implem::select<sizeof(unsigned int) * CHAR_BIT >= CHAR_BIT * BYTES, unsigned int,
|
||||||
|
typename implem::select<sizeof(unsigned long) * CHAR_BIT >= CHAR_BIT * BYTES, unsigned long,
|
||||||
|
typename implem::select<sizeof(unsigned long long) * CHAR_BIT >= CHAR_BIT * BYTES, unsigned long long,
|
||||||
|
implem::ERROR_inttype_not_available >::type >::type >::type >::type >::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Machine independent definition of sized integer types
|
||||||
|
typedef int_t<1, true>::type i8;
|
||||||
|
typedef int_t<2, true>::type i16;
|
||||||
|
typedef int_t<4, true>::type i32;
|
||||||
|
typedef int_t<8, true>::type i64;
|
||||||
|
typedef int_t<1, false>::type u8;
|
||||||
|
typedef int_t<2, false>::type u16;
|
||||||
|
typedef int_t<4, false>::type u32;
|
||||||
|
typedef int_t<8, false>::type u64;
|
||||||
|
} //namespace dk
|
||||||
|
|
||||||
|
#endif
|
175
include/doorkeeper/implem/idmanager.hpp
Normal file
175
include/doorkeeper/implem/idmanager.hpp
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of DoorKeeper.
|
||||||
|
*
|
||||||
|
* DoorKeeper is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DoorKeeper is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with DoorKeeper. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef idBC27D8C2304944D0856C2C2B012AE57B
|
||||||
|
#define idBC27D8C2304944D0856C2C2B012AE57B
|
||||||
|
|
||||||
|
#include "doorkeeper/primitivetypes.hpp"
|
||||||
|
#include "doorkeeper/implem/saltedid.hpp"
|
||||||
|
#include <boost/numeric/interval.hpp>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace dk {
|
||||||
|
namespace implem {
|
||||||
|
template <typename I>
|
||||||
|
class IDInterval {
|
||||||
|
public:
|
||||||
|
IDInterval ( I parFrom, I parTo ) :
|
||||||
|
m_interval(parFrom, parTo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator< ( const IDInterval& parOther ) const;
|
||||||
|
I lower ( void ) const { return m_interval.lower(); }
|
||||||
|
I upper ( void ) const { return m_interval.upper(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::numeric::interval<I> m_interval;
|
||||||
|
};
|
||||||
|
} //namespace implem
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
class IDManager {
|
||||||
|
public:
|
||||||
|
typedef SaltedID<Salt, Indx> value_type;
|
||||||
|
typedef typename value_type::index_type index_type;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
bit_count = sizeof(value_type) * CHAR_BIT
|
||||||
|
};
|
||||||
|
|
||||||
|
IDManager ( void );
|
||||||
|
|
||||||
|
value_type allocate ( void );
|
||||||
|
void free ( value_type parID );
|
||||||
|
void reset ( void );
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef typename value_type::salt_type salt_type;
|
||||||
|
using id_interval = implem::IDInterval<index_type>;
|
||||||
|
using interval_set = std::set<id_interval>;
|
||||||
|
|
||||||
|
interval_set m_free_intervals;
|
||||||
|
std::vector<salt_type> m_salts;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace implem {
|
||||||
|
template <typename I>
|
||||||
|
bool IDInterval<I>::operator< ( const IDInterval& parOther) const {
|
||||||
|
return (m_interval.lower() < parOther.m_interval.lower()) and
|
||||||
|
(m_interval.upper() < parOther.m_interval.upper());
|
||||||
|
}
|
||||||
|
} //namespace implem
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
IDManager<Salt, Indx>::IDManager() {
|
||||||
|
m_free_intervals.insert(id_interval(1, value_type::max_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
auto IDManager<Salt, Indx>::allocate() -> value_type {
|
||||||
|
DK_ASSERT(not m_free_intervals.empty());
|
||||||
|
auto first = *m_free_intervals.begin();
|
||||||
|
auto free_id = first.lower();
|
||||||
|
m_free_intervals.erase(m_free_intervals.begin());
|
||||||
|
if (first.lower() + 1 <= first.upper()) {
|
||||||
|
m_free_intervals.insert(typename interval_set::value_type(first.lower() + 1, first.upper()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static_cast<index_type>(m_salts.size()) < free_id) {
|
||||||
|
const auto old_size = m_salts.size();
|
||||||
|
m_salts.resize(free_id);
|
||||||
|
std::fill(m_salts.begin() + old_size, m_salts.end(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DK_ASSERT(free_id > 0);
|
||||||
|
const auto salt_index = free_id - 1;
|
||||||
|
if (m_salts[salt_index] < value_type::max_salt) {
|
||||||
|
return value_type(free_id, m_salts[salt_index]++);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return value_type(free_id, m_salts[salt_index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
void IDManager<Salt, Indx>::free (value_type parID) {
|
||||||
|
if (parID.salt() == value_type::max_salt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto id = parID.index();
|
||||||
|
if (0 == id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_salts.size() < id or 0 == id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DK_ASSERT(parID.salt() == m_salts[id - 1] - 1);
|
||||||
|
if (parID.salt() != m_salts[id - 1] - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = m_free_intervals.find(id_interval(id, id));
|
||||||
|
if (it != m_free_intervals.end() and it->lower() <= id and it->upper() > id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
it = m_free_intervals.upper_bound(id_interval(id, id));
|
||||||
|
if (m_free_intervals.end() == it) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto free_interval = *it;
|
||||||
|
|
||||||
|
if (id + 1 != free_interval.lower()) {
|
||||||
|
m_free_intervals.insert(id_interval(id, id));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (m_free_intervals.begin() != it) {
|
||||||
|
auto it_2 = it;
|
||||||
|
--it_2;
|
||||||
|
if (it_2->lower() + 1 == id) {
|
||||||
|
auto free_interval_2 = *it_2;
|
||||||
|
m_free_intervals.erase(it);
|
||||||
|
m_free_intervals.erase(it_2);
|
||||||
|
m_free_intervals.insert(id_interval(free_interval_2.lower(), free_interval.upper()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_free_intervals.erase(it);
|
||||||
|
m_free_intervals.insert(id_interval(id, free_interval.lower()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_free_intervals.erase(it);
|
||||||
|
m_free_intervals.insert(id_interval(id, free_interval.upper()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
void IDManager<Salt, Indx>::reset() {
|
||||||
|
m_free_intervals.clear();
|
||||||
|
m_free_intervals.insert(id_interval(1, value_type::max_index));
|
||||||
|
m_salts.clear();
|
||||||
|
}
|
||||||
|
} //namespace dk
|
||||||
|
|
||||||
|
#endif
|
50
include/doorkeeper/implem/iterableviewport.hpp
Normal file
50
include/doorkeeper/implem/iterableviewport.hpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of DoorKeeper.
|
||||||
|
*
|
||||||
|
* DoorKeeper is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DoorKeeper is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with DoorKeeper. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef idD358B9737CC045D3B35F2B5C2FCF84FA
|
||||||
|
#define idD358B9737CC045D3B35F2B5C2FCF84FA
|
||||||
|
|
||||||
|
#include "doorkeeper/components/viewport.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace dk {
|
||||||
|
template <uint32_t D>
|
||||||
|
class LayerBase;
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
class IterableViewport {
|
||||||
|
public:
|
||||||
|
typedef typename Viewport<D>::coords coords;
|
||||||
|
|
||||||
|
IterableViewport ( const Viewport<D>* parViewport, const LayerBase<D>* parLayerBase ) :
|
||||||
|
m_viewport(parViewport),
|
||||||
|
m_layer(parLayerBase)
|
||||||
|
{
|
||||||
|
DK_ASSERT(m_viewport);
|
||||||
|
DK_ASSERT(m_layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void each_tile ( void ) const { m_layer->each_tile(*m_viewport); }
|
||||||
|
coords size ( void ) const { return m_viewport->size(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Viewport<D>* const m_viewport;
|
||||||
|
const LayerBase<D>* const m_layer;
|
||||||
|
};
|
||||||
|
} //namespace dk
|
||||||
|
|
||||||
|
#endif
|
|
@ -60,8 +60,17 @@ namespace dk {
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
template <typename T, uint32_t D>
|
template <typename T, uint32_t D>
|
||||||
Layer<T, D>::Layer (const coords& parTileSize, BaseMapSource<D>* parTilemap) :
|
Layer<T, D>::Layer (BaseMapSource<D>* parTilemap) :
|
||||||
LayerBase<D>(parTilemap->mapSize(), parTileSize),
|
Layer<T, D>(parTilemap, EachTileCallback(nullptr))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <typename T, uint32_t D>
|
||||||
|
Layer<T, D>::Layer (BaseMapSource<D>* parTilemap, EachTileCallback parEachTile) :
|
||||||
|
LayerBase<D>(parTilemap->mapSize(), parTilemap->tileSize()),
|
||||||
|
m_each_tile(parEachTile),
|
||||||
m_tilemap(parTilemap)
|
m_tilemap(parTilemap)
|
||||||
{
|
{
|
||||||
DK_ASSERT(m_tilemap);
|
DK_ASSERT(m_tilemap);
|
||||||
|
@ -91,4 +100,20 @@ namespace dk {
|
||||||
std::cout << "Preloading layer from " << parFrom << " to " << parTo << '\n';
|
std::cout << "Preloading layer from " << parFrom << " to " << parTo << '\n';
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <typename T, uint32_t D>
|
||||||
|
void Layer<T, D>::each_tile (const Viewport<D>& parViewport) const {
|
||||||
|
if (not m_each_tile) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator it(&m_tiles, m_tilemap->pixel_conv(), parViewport.block_position(), make_past_end_coords(parViewport.upper()));
|
||||||
|
const_iterator it_end(&m_tiles, m_tilemap->pixel_conv(), make_past_end_coords(parViewport.upper()), make_past_end_coords(parViewport.upper()));
|
||||||
|
|
||||||
|
for (; it != it_end; ++it) {
|
||||||
|
m_each_tile(*this, *it);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
159
include/doorkeeper/implem/layeredviewport.inl
Normal file
159
include/doorkeeper/implem/layeredviewport.inl
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of DoorKeeper.
|
||||||
|
*
|
||||||
|
* DoorKeeper is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DoorKeeper is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with DoorKeeper. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace dk {
|
||||||
|
template <uint32_t D>
|
||||||
|
struct LayeredViewport<D>::ViewportItem {
|
||||||
|
ViewportItem ( const TileInfo<D>& parTInfo, Tyler<D>& parTyler );
|
||||||
|
ViewportItem ( ViewportItem&& ) = default;
|
||||||
|
ViewportItem ( const ViewportItem& ) = delete;
|
||||||
|
|
||||||
|
TileInfo<D> tile_info;
|
||||||
|
Viewport<D> viewport;
|
||||||
|
int ref_count;
|
||||||
|
|
||||||
|
bool operator== ( const TileInfo<D>& parOther ) const a_pure;
|
||||||
|
ViewportItem& operator= ( const ViewportItem& ) = default;
|
||||||
|
ViewportItem& operator= ( ViewportItem&& );
|
||||||
|
};
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
LayeredViewport<D>::ViewportItem::ViewportItem (const TileInfo<D>& parTInfo, Tyler<D>& parTyler) :
|
||||||
|
tile_info(parTInfo),
|
||||||
|
viewport(parTyler, &tile_info),
|
||||||
|
ref_count(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
bool LayeredViewport<D>::ViewportItem::operator== (const TileInfo<D>& parOther) const {
|
||||||
|
return tile_info == parOther;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
typename LayeredViewport<D>::ViewportItem& LayeredViewport<D>::ViewportItem::operator= (ViewportItem&& parOther) {
|
||||||
|
tile_info = std::move(parOther.tile_info);
|
||||||
|
viewport = std::move(parOther.viewport);
|
||||||
|
ref_count = parOther.ref_count;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
LayeredViewport<D>::LayeredViewport (LayeredViewport<D>&& parOther) :
|
||||||
|
m_views(std::move(parOther.m_views)),
|
||||||
|
m_tyler(parOther.m_tyler),
|
||||||
|
m_tyler_id(std::move(m_tyler_id))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
LayeredViewport<D>::LayeredViewport (Tyler<D>& parTyler) :
|
||||||
|
m_tyler(&parTyler)
|
||||||
|
{
|
||||||
|
DK_ASSERT(m_tyler);
|
||||||
|
for (const auto& layer : *m_tyler) {
|
||||||
|
this->on_layer(layer, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
using std::placeholders::_1;
|
||||||
|
using std::placeholders::_2;
|
||||||
|
m_tyler_id = m_tyler->register_for_layeradd(std::bind(&LayeredViewport<D>::on_layer, this, _1, _2));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
LayeredViewport<D>::~LayeredViewport() noexcept {
|
||||||
|
m_tyler->unregister_for_layeradd(m_tyler_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
LayeredViewport<D>& LayeredViewport<D>::operator+= (const coords_f& parValue) {
|
||||||
|
for (auto& view : m_views) {
|
||||||
|
view.viewport += parValue;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
LayeredViewport<D>& LayeredViewport<D>::operator-= (const coords_f& parValue) {
|
||||||
|
for (auto& view : m_views) {
|
||||||
|
view.viewport -= parValue;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
void LayeredViewport<D>::on_layer (const LayerBase<D>& parLayer, bool parAdded) {
|
||||||
|
const TileInfo<D> tinfo(parLayer);
|
||||||
|
auto it_found = std::find(m_views.begin(), m_views.end(), tinfo);
|
||||||
|
|
||||||
|
if (parAdded) {
|
||||||
|
if (m_views.end() == it_found) {
|
||||||
|
m_views.emplace_back(ViewportItem(tinfo, *m_tyler));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++it_found->ref_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DK_ASSERT(m_views.end() != it_found);
|
||||||
|
--it_found->ref_count;
|
||||||
|
if (0 == it_found->ref_count) {
|
||||||
|
m_views.erase(it_found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
auto LayeredViewport<D>::begin() -> iterator {
|
||||||
|
IterableViewport<D> (LayeredViewport<D>::*vpfunc)(const LayerBase<D>&) = &LayeredViewport<D>::viewport;
|
||||||
|
boost::function<IterableViewport<D>(const LayerBase<D>&)> functor = boost::bind(vpfunc, this, _1);
|
||||||
|
auto it_beg = m_tyler->begin();
|
||||||
|
return boost::make_transform_iterator(it_beg, functor);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
auto LayeredViewport<D>::begin() const -> const_iterator {
|
||||||
|
const IterableViewport<D> (LayeredViewport<D>::*vpfunc)(const LayerBase<D>&) const = &LayeredViewport<D>::viewport;
|
||||||
|
return const_iterator(m_tyler->begin(), boost::bind(&vpfunc, this, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
auto LayeredViewport<D>::end() -> iterator {
|
||||||
|
IterableViewport<D> (LayeredViewport<D>::*vpfunc)(const LayerBase<D>&) = &LayeredViewport<D>::viewport;
|
||||||
|
boost::function<IterableViewport<D>(const LayerBase<D>&)> functor = boost::bind(vpfunc, this, _1);
|
||||||
|
return boost::make_transform_iterator(m_tyler->end(), functor);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
auto LayeredViewport<D>::end() const -> const_iterator {
|
||||||
|
const IterableViewport<D> (LayeredViewport<D>::*vpfunc)(const LayerBase<D>&) const = &LayeredViewport<D>::viewport;
|
||||||
|
return const_iterator(m_tyler->end(), boost::bind(&vpfunc, this, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
IterableViewport<D> LayeredViewport<D>::viewport (const LayerBase<D>& parLayer) {
|
||||||
|
return const_cast<const LayeredViewport<D>*>(this)->viewport(parLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
const IterableViewport<D> LayeredViewport<D>::viewport (const LayerBase<D>& parLayer) const {
|
||||||
|
const TileInfo<D> tinfo(parLayer);
|
||||||
|
auto it_found = std::find(m_views.begin(), m_views.end(), tinfo);
|
||||||
|
DK_ASSERT(m_views.end() != it_found);
|
||||||
|
return IterableViewport<D>(&it_found->viewport, &parLayer);
|
||||||
|
}
|
||||||
|
} //namespace dk
|
|
@ -19,7 +19,7 @@ namespace dkh {
|
||||||
template <uint32_t D, typename C>
|
template <uint32_t D, typename C>
|
||||||
dk::Tyler<D> map_load (C& parFileOpener, const std::string& parOpen, const PushLayerMapType<D>& parPusher) {
|
dk::Tyler<D> map_load (C& parFileOpener, const std::string& parOpen, const PushLayerMapType<D>& parPusher) {
|
||||||
dk::BaseMapSource<D>* reader = parFileOpener(parOpen);
|
dk::BaseMapSource<D>* reader = parFileOpener(parOpen);
|
||||||
dk::Tyler<D> tyler(reader->mapSize(), reader->tileSize());
|
dk::Tyler<D> tyler;
|
||||||
for (int z = 0; z < reader->layersCount(); ++z) {
|
for (int z = 0; z < reader->layersCount(); ++z) {
|
||||||
implem::call_push_layer<D>(tyler, parPusher, reader, z);
|
implem::call_push_layer<D>(tyler, parPusher, reader, z);
|
||||||
}
|
}
|
||||||
|
|
149
include/doorkeeper/implem/saltedid.hpp
Normal file
149
include/doorkeeper/implem/saltedid.hpp
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of DoorKeeper.
|
||||||
|
*
|
||||||
|
* DoorKeeper is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DoorKeeper is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with DoorKeeper. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef id440C878EF94C4468948A57610C7C9B5A
|
||||||
|
#define id440C878EF94C4468948A57610C7C9B5A
|
||||||
|
|
||||||
|
#include "doorkeeper/primitivetypes.hpp"
|
||||||
|
#include "doorkeeper/implem/dktypes.hpp"
|
||||||
|
#include <ciso646>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace dk {
|
||||||
|
namespace implem {
|
||||||
|
template <unsigned int S>
|
||||||
|
struct uint_t {
|
||||||
|
typedef typename int_t<S / CHAR_BIT, false>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <unsigned int N, unsigned int M=8*CHAR_BIT, bool=(N>=M) or (N%CHAR_BIT==0)>
|
||||||
|
struct RoundToInt {
|
||||||
|
private:
|
||||||
|
enum {
|
||||||
|
v = (N < M ? (N < CHAR_BIT ? CHAR_BIT : N) : M)
|
||||||
|
};
|
||||||
|
static_assert(v > 0, "v must be greater than 0");
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
value = ((((((v - 1) | ((v - 1) >> 1)) | (((v - 1) | ((v - 1) >> 1)) >> 2)) | ((((v - 1) | ((v - 1) >> 1)) | (((v - 1) | ((v - 1) >> 1)) >> 2)) >> 4)) | (((((v - 1) | ((v - 1) >> 1)) | (((v - 1) | ((v - 1) >> 1)) >> 2)) | ((((v - 1) | ((v - 1) >> 1)) | (((v - 1) | ((v - 1) >> 1)) >> 2)) >> 4)) >> 8)) | ((((((v - 1) | ((v - 1) >> 1)) | (((v - 1) | ((v - 1) >> 1)) >> 2)) | ((((v - 1) | ((v - 1) >> 1)) | (((v - 1) | ((v - 1) >> 1)) >> 2)) >> 4)) | (((((v - 1) | ((v - 1) >> 1)) | (((v - 1) | ((v - 1) >> 1)) >> 2)) | ((((v - 1) | ((v - 1) >> 1)) | (((v - 1) | ((v - 1) >> 1)) >> 2)) >> 4)) >> 8)) >> 16)) + 1
|
||||||
|
};
|
||||||
|
static_assert(value <= M, "value must be smaller than M");
|
||||||
|
static_assert(value and not (value bitand (value - 1)), "value must be a power of two");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <unsigned int B>
|
||||||
|
struct FillBits;
|
||||||
|
template <unsigned int B>
|
||||||
|
struct FillBits {
|
||||||
|
enum { value = 1 bitor (FillBits<B - 1>::value << 1) };
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct FillBits<0> {
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
} //namespace implem
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
class SaltedID {
|
||||||
|
static_assert(Salt + Indx <= 64, "Only indices up to 64 bits are currently supported");
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
bit_size = implem::RoundToInt<Salt + Indx>::value,
|
||||||
|
max_index = implem::FillBits<Indx>::value,
|
||||||
|
max_salt = implem::FillBits<Salt>::value
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef typename implem::uint_t<bit_size>::type compound_type;
|
||||||
|
public:
|
||||||
|
typedef typename implem::uint_t<implem::RoundToInt<Salt>::value>::type salt_type;
|
||||||
|
typedef typename implem::uint_t<implem::RoundToInt<Indx>::value>::type index_type;
|
||||||
|
|
||||||
|
SaltedID ( void ) = default;
|
||||||
|
SaltedID ( const SaltedID& ) = default;
|
||||||
|
SaltedID ( SaltedID&& parOther );
|
||||||
|
SaltedID ( index_type parIndex, salt_type parSalt ) :
|
||||||
|
m_data(pack_index_salt(parIndex, parSalt))
|
||||||
|
{
|
||||||
|
DK_ASSERT(index() == parIndex);
|
||||||
|
DK_ASSERT(salt() == parSalt);
|
||||||
|
}
|
||||||
|
|
||||||
|
salt_type salt ( void ) const;
|
||||||
|
index_type index ( void ) const;
|
||||||
|
|
||||||
|
SaltedID& operator+= ( index_type parOther ) { m_data = pack_index_salt(index() + parOther, salt()); return *this; }
|
||||||
|
SaltedID& operator-= ( index_type parOther ) { m_data = pack_index_salt(index() - parOther, salt()); return *this; }
|
||||||
|
SaltedID& operator= ( const SaltedID& parOther ) = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static compound_type pack_index_salt ( index_type parIndex, salt_type parSalt );
|
||||||
|
|
||||||
|
compound_type m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
SaltedID<Salt, Indx>::SaltedID (SaltedID&& parOther) {
|
||||||
|
std::swap(m_data, parOther.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
auto SaltedID<Salt, Indx>::salt() const -> salt_type {
|
||||||
|
return static_cast<salt_type>(m_data bitand implem::FillBits<Salt>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
auto SaltedID<Salt, Indx>::index() const -> index_type {
|
||||||
|
return static_cast<index_type>(m_data >> Salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
auto SaltedID<Salt, Indx>::pack_index_salt (index_type parIndex, salt_type parSalt) -> compound_type {
|
||||||
|
DK_ASSERT(parIndex <= max_index);
|
||||||
|
DK_ASSERT(parSalt <= max_salt);
|
||||||
|
return (static_cast<compound_type>(parIndex) << Salt) bitor parSalt;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
inline bool operator< (const SaltedID<Salt, Indx>& parLeft, const SaltedID<Salt, Indx>& parRight) {
|
||||||
|
return parLeft.index() < parRight.index();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
inline SaltedID<Salt, Indx> operator+ (SaltedID<Salt, Indx> parLeft, typename SaltedID<Salt, Indx>::index_type parRight) {
|
||||||
|
return (parLeft += parRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
inline SaltedID<Salt, Indx> operator+ (typename SaltedID<Salt, Indx>::index_type parLeft, SaltedID<Salt, Indx> parRight) {
|
||||||
|
return (parRight += parLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
inline SaltedID<Salt, Indx> operator- (SaltedID<Salt, Indx> parLeft, typename SaltedID<Salt, Indx>::index_type parRight) {
|
||||||
|
return (parLeft -= parRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned int Salt, unsigned int Indx>
|
||||||
|
inline SaltedID<Salt, Indx> operator- (typename SaltedID<Salt, Indx>::index_type parLeft, SaltedID<Salt, Indx> parRight) {
|
||||||
|
return (parRight -= parLeft);
|
||||||
|
}
|
||||||
|
} //namespace dk
|
||||||
|
|
||||||
|
#endif
|
|
@ -19,21 +19,7 @@ namespace dk {
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
Tyler<D>::Tyler (const coords& parMapSize, const coords& parTileSize) :
|
Tyler<D>::Tyler() {
|
||||||
m_size(parMapSize),
|
|
||||||
m_tilesize(parTileSize)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
|
||||||
///--------------------------------------------------------------------------
|
|
||||||
template <uint32_t D>
|
|
||||||
typename Tyler<D>::coords::scalar_type Tyler<D>::tiles_count() const {
|
|
||||||
typename coords::scalar_type retval = 1;
|
|
||||||
for (uint32_t d = 0; d < D; ++d) {
|
|
||||||
retval *= m_size[d];
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///--------------------------------------------------------------------------
|
///--------------------------------------------------------------------------
|
||||||
|
@ -44,18 +30,14 @@ namespace dk {
|
||||||
//TODO: store the index
|
//TODO: store the index
|
||||||
(void)parIndex;
|
(void)parIndex;
|
||||||
|
|
||||||
auto newLayer = new Layer<T, D>(m_tilesize, parTilemap);
|
auto newLayer = new Layer<T, D>(parTilemap);
|
||||||
if (m_size == coords(0)) {
|
m_layers.push_back(LayerPtr(newLayer));
|
||||||
m_size = newLayer->mapSize();
|
|
||||||
}
|
for (auto& callback : m_layerobs_callbacks) {
|
||||||
else {
|
if (nullptr != callback) {
|
||||||
DK_ASSERT(newLayer->mapSize() == m_size);
|
callback(*newLayer, true);
|
||||||
if (newLayer->mapSize() != m_size) {
|
|
||||||
throw SizeMismatchException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DK_ASSERT(newLayer->mapSize() == m_size);
|
|
||||||
m_layers.push_back(LayerPtr(newLayer));
|
|
||||||
return *newLayer;
|
return *newLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,4 +57,59 @@ namespace dk {
|
||||||
layer->preload(parFrom, parTo);
|
layer->preload(parFrom, parTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <uint32_t D>
|
||||||
|
auto Tyler<D>::begin() -> iterator {
|
||||||
|
return iterator(m_layers.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <uint32_t D>
|
||||||
|
auto Tyler<D>::begin() const -> const_iterator {
|
||||||
|
return const_iterator(m_layers.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <uint32_t D>
|
||||||
|
auto Tyler<D>::end() -> iterator {
|
||||||
|
return iterator(m_layers.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <uint32_t D>
|
||||||
|
auto Tyler<D>::end() const -> const_iterator {
|
||||||
|
return const_iterator(m_layers.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <uint32_t D>
|
||||||
|
auto Tyler<D>::register_for_layeradd (layer_callback parCallback) -> LayerObsID {
|
||||||
|
auto retval = m_layerobs_idmanager.allocate();
|
||||||
|
DK_ASSERT(retval.index() > 0);
|
||||||
|
if (retval.index() > m_layerobs_callbacks.size()) {
|
||||||
|
DK_ASSERT(retval.index() == m_layerobs_callbacks.size() + 1);
|
||||||
|
m_layerobs_callbacks.resize(retval.index());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DK_ASSERT(retval.salt() > 0);
|
||||||
|
}
|
||||||
|
m_layerobs_callbacks[retval.index() - 1] = parCallback;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
///--------------------------------------------------------------------------
|
||||||
|
template <uint32_t D>
|
||||||
|
void Tyler<D>::unregister_for_layeradd (LayerObsID parID) {
|
||||||
|
DK_ASSERT(parID.index() <= m_layerobs_callbacks.size());
|
||||||
|
DK_ASSERT(nullptr != m_layerobs_callbacks[parID.index() - 1]);
|
||||||
|
m_layerobs_callbacks[parID.index() - 1] = nullptr;
|
||||||
|
m_layerobs_idmanager.free(parID);
|
||||||
|
}
|
||||||
} //namespace dk
|
} //namespace dk
|
||||||
|
|
|
@ -17,68 +17,47 @@
|
||||||
|
|
||||||
namespace dk {
|
namespace dk {
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
Viewport<D>::Viewport (Tyler<D>& parTyler) :
|
TileInfo<D>::TileInfo (const LayerBase<D>& parLayer) :
|
||||||
m_tyler(parTyler),
|
tile_size(parLayer.tile_size()),
|
||||||
m_pixel_offset(0)
|
map_size(parLayer.map_size())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
Viewport<D>::Viewport (Tyler<D>& parTyler, const coords& parSize, const coords& parPos) :
|
bool TileInfo<D>::operator== (const TileInfo& parOther) const {
|
||||||
m_view(parPos, parSize - 1),
|
return tile_size == parOther.tile_size and map_size == parOther.map_size;
|
||||||
m_tyler(parTyler),
|
}
|
||||||
m_pixel_offset(0)
|
|
||||||
|
template <uint32_t D>
|
||||||
|
Viewport<D>::Viewport (Tyler<D>& parTyler, const TileInfo<D>* parTileInfo) :
|
||||||
|
m_view(parTileInfo->map_size - 1),
|
||||||
|
m_pixel_offset(0),
|
||||||
|
m_tyler(&parTyler),
|
||||||
|
m_tile_info(parTileInfo)
|
||||||
{
|
{
|
||||||
DK_ASSERT(parPos < parPos + parSize); //parSize > 0
|
DK_ASSERT(parTileInfo);
|
||||||
DK_ASSERT(parSize + parPos <= parTyler.map_size());
|
DK_ASSERT(m_tyler);
|
||||||
m_tyler.preload(m_view.position(), m_view.position() + this->size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
template <typename T>
|
Viewport<D>::Viewport (Tyler<D>& parTyler, const TileInfo<D>* parTileInfo, const coords& parPos) :
|
||||||
typename Layer<T, D>::iterator Viewport<D>::begin (Layer<T, D>& parLayer) const {
|
m_view(parPos, parTileInfo->map_size - 1),
|
||||||
typedef typename Layer<T, D>::iterator IterType;
|
m_pixel_offset(0),
|
||||||
return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), m_view.position(), m_view.upper());
|
m_tyler(&parTyler),
|
||||||
}
|
m_tile_info(parTileInfo)
|
||||||
|
{
|
||||||
template <uint32_t D>
|
DK_ASSERT(parTileInfo);
|
||||||
template <typename T>
|
DK_ASSERT(parPos < parPos + m_tile_info->map_size); //parSize > 0
|
||||||
typename Layer<T, D>::iterator Viewport<D>::end (Layer<T, D>& parLayer) const {
|
DK_ASSERT(m_tile_info->map_size + parPos <= m_tile_info->map_size);
|
||||||
typedef typename Layer<T, D>::iterator IterType;
|
DK_ASSERT(m_tyler);
|
||||||
return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), make_past_end_coords<D>(m_view.upper()), make_past_end_coords<D>(m_view.upper()));
|
m_tyler->preload(m_view.position(), m_view.position() + this->size());
|
||||||
}
|
|
||||||
|
|
||||||
template <uint32_t D>
|
|
||||||
template <typename T>
|
|
||||||
typename Layer<T, D>::const_iterator Viewport<D>::begin (const Layer<T, D>& parLayer) const {
|
|
||||||
return this->cbegin(parLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <uint32_t D>
|
|
||||||
template <typename T>
|
|
||||||
typename Layer<T, D>::const_iterator Viewport<D>::end (const Layer<T, D>& parLayer) const {
|
|
||||||
return this->cend(parLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <uint32_t D>
|
|
||||||
template <typename T>
|
|
||||||
typename Layer<T, D>::const_iterator Viewport<D>::cbegin (const Layer<T, D>& parLayer) const {
|
|
||||||
typedef typename Layer<T, D>::const_iterator IterType;
|
|
||||||
return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), m_view.position(), m_view.upper());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <uint32_t D>
|
|
||||||
template <typename T>
|
|
||||||
typename Layer<T, D>::const_iterator Viewport<D>::cend (const Layer<T, D>& parLayer) const {
|
|
||||||
typedef typename Layer<T, D>::const_iterator IterType;
|
|
||||||
return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), make_past_end_coords<D>(m_view.upper()), make_past_end_coords<D>(m_view.upper()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
void Viewport<D>::setFrom (const coords& parFrom) {
|
void Viewport<D>::setFrom (const coords& parFrom) {
|
||||||
DK_ASSERT(this->size() + parFrom <= m_tyler.map_size());
|
DK_ASSERT(this->size() + parFrom <= m_tile_info->map_size);
|
||||||
m_view.set_position(parFrom);
|
m_view.set_position(parFrom);
|
||||||
m_tyler.preload(m_view.position(), m_view.position() + this->size());
|
m_tyler->preload(m_view.position(), m_view.position() + this->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
|
@ -102,7 +81,7 @@ namespace dk {
|
||||||
|
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
void Viewport<D>::clip_pixel_offset() {
|
void Viewport<D>::clip_pixel_offset() {
|
||||||
const auto& tile_size = m_tyler.tile_size();
|
const auto& tile_size = m_tile_info->tile_size;
|
||||||
for (uint32_t z = 0; z < D; ++z) {
|
for (uint32_t z = 0; z < D; ++z) {
|
||||||
auto offs = static_cast<CoordinateScalarType>(m_pixel_offset[z]);
|
auto offs = static_cast<CoordinateScalarType>(m_pixel_offset[z]);
|
||||||
if (std::abs(offs) >= tile_size[z]) {
|
if (std::abs(offs) >= tile_size[z]) {
|
||||||
|
@ -130,4 +109,14 @@ namespace dk {
|
||||||
auto Viewport<D>::pixel_offset() const -> coords {
|
auto Viewport<D>::pixel_offset() const -> coords {
|
||||||
return static_cast<coords>(m_pixel_offset);
|
return static_cast<coords>(m_pixel_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
auto Viewport<D>::upper() const -> const coords& {
|
||||||
|
return m_view.upper();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
auto Viewport<D>::block_position() const -> const coords& {
|
||||||
|
return m_view.position();
|
||||||
|
}
|
||||||
} //namespace dk
|
} //namespace dk
|
||||||
|
|
|
@ -52,6 +52,8 @@ namespace vwr {
|
||||||
Vec<V1>& assign ( Vec<V1, D>& parLeft, const Vec<V2, D>& parRight );
|
Vec<V1>& assign ( Vec<V1, D>& parLeft, const Vec<V2, D>& parRight );
|
||||||
template <typename V>
|
template <typename V>
|
||||||
Vec<V>& assign_same_type ( Vec<V>& parLeft, const Vec<V>& parRight );
|
Vec<V>& assign_same_type ( Vec<V>& parLeft, const Vec<V>& parRight );
|
||||||
|
template <typename V>
|
||||||
|
Vec<V>& move_same_type ( Vec<V>& parLeft, Vec<V>&& parRight );
|
||||||
|
|
||||||
template <typename T, dim_type I> struct get_offset_enum_from_index;
|
template <typename T, dim_type I> struct get_offset_enum_from_index;
|
||||||
template <typename T> struct get_offset_enum_from_index<T, 0> {
|
template <typename T> struct get_offset_enum_from_index<T, 0> {
|
||||||
|
@ -141,6 +143,7 @@ namespace vwr {
|
||||||
template <typename V>
|
template <typename V>
|
||||||
class VecBase {
|
class VecBase {
|
||||||
friend Vec<V>& assign_same_type<V> ( Vec<V>& parLeft, const Vec<V>& parRight );
|
friend Vec<V>& assign_same_type<V> ( Vec<V>& parLeft, const Vec<V>& parRight );
|
||||||
|
friend Vec<V>& move_same_type<V> ( Vec<V>& parLeft, Vec<V>&& parRight );
|
||||||
public:
|
public:
|
||||||
typedef V vector_type;
|
typedef V vector_type;
|
||||||
typedef typename VectorWrapperInfo<V>::scalar_type scalar_type;
|
typedef typename VectorWrapperInfo<V>::scalar_type scalar_type;
|
||||||
|
@ -150,6 +153,8 @@ namespace vwr {
|
||||||
};
|
};
|
||||||
|
|
||||||
VecBase ( void ) = default;
|
VecBase ( void ) = default;
|
||||||
|
VecBase ( const VecBase& ) = default;
|
||||||
|
VecBase ( VecBase&& ) = default;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
explicit VecBase ( const T& parInit, typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, bool>::type=false );
|
explicit VecBase ( const T& parInit, typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, bool>::type=false );
|
||||||
explicit VecBase ( const vector_type& parInit );
|
explicit VecBase ( const vector_type& parInit );
|
||||||
|
@ -314,10 +319,13 @@ namespace vwr {
|
||||||
dimensions = S
|
dimensions = S
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename... Args>
|
Vec ( void ) = default;
|
||||||
Vec ( Args... parArgs ) : implem::VecBase<V>(std::forward<Args>(parArgs)...)
|
Vec ( const Vec& ) = default;
|
||||||
{
|
Vec ( Vec&& ) = default;
|
||||||
}
|
using implem::VecBase<V>::VecBase;
|
||||||
|
|
||||||
|
Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); }
|
||||||
|
Vec& operator= ( Vec&& parOther ) { return implem::move_same_type(*this, std::move(parOther)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
|
@ -334,12 +342,14 @@ namespace vwr {
|
||||||
|
|
||||||
Vec ( void ) = default;
|
Vec ( void ) = default;
|
||||||
Vec ( const Vec& ) = default;
|
Vec ( const Vec& ) = default;
|
||||||
|
Vec ( Vec&& ) = default;
|
||||||
explicit Vec ( const vector_type& parIn ) : implem::VecBase<V>(parIn) { }
|
explicit Vec ( const vector_type& parIn ) : implem::VecBase<V>(parIn) { }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
explicit Vec ( const typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, T>::type& parX ) : implem::VecBase<V>(parX) { }
|
explicit Vec ( const typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, T>::type& parX ) : implem::VecBase<V>(parX) { }
|
||||||
template <typename V2> Vec ( const Vec<V2, dimensions>& parOther ) { implem::assign(*this, parOther); }
|
template <typename V2> Vec ( const Vec<V2, dimensions>& parOther ) { implem::assign(*this, parOther); }
|
||||||
|
|
||||||
Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); }
|
Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); }
|
||||||
|
Vec& operator= ( Vec&& parOther ) { return implem::move_same_type(*this, std::move(parOther)); }
|
||||||
template <typename V2>
|
template <typename V2>
|
||||||
Vec& operator= ( const Vec<V2, dimensions>& parOther ) { return implem::assign(*this, parOther); }
|
Vec& operator= ( const Vec<V2, dimensions>& parOther ) { return implem::assign(*this, parOther); }
|
||||||
};
|
};
|
||||||
|
@ -360,12 +370,14 @@ namespace vwr {
|
||||||
|
|
||||||
Vec ( void ) = default;
|
Vec ( void ) = default;
|
||||||
Vec ( const Vec& ) = default;
|
Vec ( const Vec& ) = default;
|
||||||
|
Vec ( Vec&& ) = default;
|
||||||
explicit Vec ( const vector_type& parIn ) : implem::VecBase<V>(parIn) { }
|
explicit Vec ( const vector_type& parIn ) : implem::VecBase<V>(parIn) { }
|
||||||
explicit Vec ( const scalar_type parX ) : implem::VecBase<V>(parX) { }
|
explicit Vec ( const scalar_type parX ) : implem::VecBase<V>(parX) { }
|
||||||
Vec ( scalar_type parX, scalar_type parY ) : implem::VecBase<V>(parX, parY) { }
|
Vec ( scalar_type parX, scalar_type parY ) : implem::VecBase<V>(parX, parY) { }
|
||||||
template <typename V2> Vec ( const Vec<V2, dimensions>& parOther ) { implem::assign(*this, parOther); }
|
template <typename V2> Vec ( const Vec<V2, dimensions>& parOther ) { implem::assign(*this, parOther); }
|
||||||
|
|
||||||
Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); }
|
Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); }
|
||||||
|
Vec& operator= ( Vec&& parOther ) { return implem::move_same_type(*this, std::move(parOther)); }
|
||||||
template <typename V2>
|
template <typename V2>
|
||||||
Vec& operator= ( const Vec<V2, dimensions>& parOther ) { return implem::assign(*this, parOther); }
|
Vec& operator= ( const Vec<V2, dimensions>& parOther ) { return implem::assign(*this, parOther); }
|
||||||
Vec& operator= ( const vector_type& parOther ) { this->data() = parOther; return *this; }
|
Vec& operator= ( const vector_type& parOther ) { this->data() = parOther; return *this; }
|
||||||
|
@ -388,12 +400,14 @@ namespace vwr {
|
||||||
|
|
||||||
Vec ( void ) = default;
|
Vec ( void ) = default;
|
||||||
Vec ( const Vec& ) = default;
|
Vec ( const Vec& ) = default;
|
||||||
|
Vec ( Vec&& ) = default;
|
||||||
explicit Vec ( const vector_type& parIn ) : implem::VecBase<V>(parIn) { }
|
explicit Vec ( const vector_type& parIn ) : implem::VecBase<V>(parIn) { }
|
||||||
explicit Vec ( const scalar_type parX ) : implem::VecBase<V>(parX) { }
|
explicit Vec ( const scalar_type parX ) : implem::VecBase<V>(parX) { }
|
||||||
Vec ( scalar_type parX, scalar_type parY, scalar_type parZ ) : implem::VecBase<V>(parX, parY, parZ) { }
|
Vec ( scalar_type parX, scalar_type parY, scalar_type parZ ) : implem::VecBase<V>(parX, parY, parZ) { }
|
||||||
template <typename V2> Vec ( const Vec<V2, dimensions>& parOther ) { implem::assign(*this, parOther); }
|
template <typename V2> Vec ( const Vec<V2, dimensions>& parOther ) { implem::assign(*this, parOther); }
|
||||||
|
|
||||||
Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); }
|
Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); }
|
||||||
|
Vec& operator= ( Vec&& parOther ) { return implem::move_same_type(*this, std::move(parOther)); }
|
||||||
template <typename V2>
|
template <typename V2>
|
||||||
Vec& operator= ( const Vec<V2, dimensions>& parOther ) { return implem::assign(*this, parOther); }
|
Vec& operator= ( const Vec<V2, dimensions>& parOther ) { return implem::assign(*this, parOther); }
|
||||||
Vec& operator= ( const vector_type& parOther ) { this->data() = parOther; return *this; }
|
Vec& operator= ( const vector_type& parOther ) { this->data() = parOther; return *this; }
|
||||||
|
|
|
@ -188,6 +188,12 @@ namespace vwr {
|
||||||
return parLeft;
|
return parLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
Vec<V>& move_same_type (Vec<V>& parLeft, Vec<V>&& parRight) {
|
||||||
|
parLeft.m_wrapped = std::move(parRight.m_wrapped);
|
||||||
|
return parLeft;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
auto Vec3Demotion<V, true>::xy() const -> lower_vector_type {
|
auto Vec3Demotion<V, true>::xy() const -> lower_vector_type {
|
||||||
auto& this_vec = *static_cast<const Vec<V>*>(this);
|
auto& this_vec = *static_cast<const Vec<V>*>(this);
|
||||||
|
|
|
@ -87,7 +87,7 @@ int main() {
|
||||||
&SDL_DestroyRenderer
|
&SDL_DestroyRenderer
|
||||||
);
|
);
|
||||||
|
|
||||||
dk::Tyler<2> tiler(coords2(10, 23), coords2(64));
|
dk::Tyler<2> tiler;
|
||||||
|
|
||||||
LayerWithData<AsciiMapSource, int> bottomLayer;
|
LayerWithData<AsciiMapSource, int> bottomLayer;
|
||||||
addLayer(tiler, bottomLayer, DATA_PATH"/test.map");
|
addLayer(tiler, bottomLayer, DATA_PATH"/test.map");
|
||||||
|
@ -95,13 +95,13 @@ int main() {
|
||||||
LayerWithData<AsciiMapSource, int> topLayer;
|
LayerWithData<AsciiMapSource, int> topLayer;
|
||||||
addLayer(tiler, topLayer, DATA_PATH"/test_2.map");
|
addLayer(tiler, topLayer, DATA_PATH"/test_2.map");
|
||||||
|
|
||||||
|
dk::LayeredViewport<2> view_10_6(tiler);
|
||||||
printViewport(dk::Viewport<2>(tiler, coords2(10, 6), coords2(0)), *bottomLayer.layer);
|
printViewport(dk::Viewport<2>(tiler, coords2(10, 6), coords2(0)), *bottomLayer.layer);
|
||||||
printViewport(dk::Viewport<2>(tiler, coords2(4, 4), coords2(0)), *bottomLayer.layer);
|
printViewport(dk::Viewport<2>(tiler, coords2(4, 4), coords2(0)), *bottomLayer.layer);
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
std::cout << "Map size: " << tiler.map_size() << '\n';
|
std::cout << "Map size: " << bottomLayer.layer->map_size() << '\n';
|
||||||
#endif
|
#endif
|
||||||
std::cout << "Total tiles: " << tiler.tiles_count() << '\n';
|
|
||||||
|
|
||||||
//Load resources
|
//Load resources
|
||||||
SDLTextureUPtr tile_0(nullptr, &SDL_DestroyTexture), tile_1(nullptr, &SDL_DestroyTexture);
|
SDLTextureUPtr tile_0(nullptr, &SDL_DestroyTexture), tile_1(nullptr, &SDL_DestroyTexture);
|
||||||
|
@ -113,7 +113,7 @@ int main() {
|
||||||
//Main loop
|
//Main loop
|
||||||
bool running = true;
|
bool running = true;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
dk::Viewport<2> viewport(tiler, tiler.map_size(), coords2(0));
|
dk::Viewport<2> viewport(tiler, bottomLayer.layer->map_size(), coords2(0));
|
||||||
coords2 tile_size;
|
coords2 tile_size;
|
||||||
SDL_QueryTexture(tile_0.get(), nullptr, nullptr, &tile_size.x(), &tile_size.y());
|
SDL_QueryTexture(tile_0.get(), nullptr, nullptr, &tile_size.x(), &tile_size.y());
|
||||||
do {
|
do {
|
||||||
|
@ -121,7 +121,7 @@ int main() {
|
||||||
viewport.setFrom(coords2(0, y / tile_size.y()));
|
viewport.setFrom(coords2(0, y / tile_size.y()));
|
||||||
draw_tiles(sdl_renderer.get(), tile_0.get(), tile_1.get(), viewport, *bottomLayer.layer, -(y % tile_size.y()));
|
draw_tiles(sdl_renderer.get(), tile_0.get(), tile_1.get(), viewport, *bottomLayer.layer, -(y % tile_size.y()));
|
||||||
//++y;
|
//++y;
|
||||||
if (tile_size.y() * bottomLayer.layer->mapSize().y() == y)
|
if (tile_size.y() * bottomLayer.layer->map_size().y() == y)
|
||||||
y = 0;
|
y = 0;
|
||||||
SDL_RenderPresent(sdl_renderer.get());
|
SDL_RenderPresent(sdl_renderer.get());
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ add_executable(${PROJECT_NAME}
|
||||||
vector.cpp
|
vector.cpp
|
||||||
tileiterator.cpp
|
tileiterator.cpp
|
||||||
asciimapsource.cpp
|
asciimapsource.cpp
|
||||||
|
layeredviewport.cpp
|
||||||
|
saltedid.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
|
|
@ -31,7 +31,7 @@ const dk::CoordinateScalarType asciimapsource::map_width = 10;
|
||||||
const dk::CoordinateScalarType asciimapsource::map_height = 8;
|
const dk::CoordinateScalarType asciimapsource::map_height = 8;
|
||||||
|
|
||||||
asciimapsource::asciimapsource() :
|
asciimapsource::asciimapsource() :
|
||||||
tiler(coords2(map_width, map_height), coords2(tile_size)),
|
tiler(),
|
||||||
layer(nullptr)
|
layer(nullptr)
|
||||||
{
|
{
|
||||||
std::istringstream iss((std::string(map_data)));
|
std::istringstream iss((std::string(map_data)));
|
||||||
|
@ -44,70 +44,70 @@ void asciimapsource::SetUp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(asciimapsource, load) {
|
TEST_F(asciimapsource, load) {
|
||||||
dk::Viewport<2> full_view(tiler, tiler.map_size(), coords2(0));
|
dk::LayeredViewport<2> full_view(tiler);
|
||||||
|
|
||||||
EXPECT_EQ(coords2(map_width, map_height), tiler.map_size());
|
|
||||||
|
|
||||||
dk::CoordinateDistType index = 0;
|
dk::CoordinateDistType index = 0;
|
||||||
int data_index = 0;
|
int data_index = 0;
|
||||||
full_view.setFrom(coords2(0));
|
for (const auto& viewport : full_view) {
|
||||||
for (auto itTile = full_view.begin(*layer), itTileEND = full_view.end(*layer); itTile != itTileEND; ++itTile) {
|
EXPECT_EQ(coords2(map_width, map_height), viewport.size());
|
||||||
EXPECT_EQ(index, dk::to_index(itTile->raw_coords()));
|
viewport.each_tile();
|
||||||
EXPECT_LT(index, sizeof(map_data));
|
//for (const auto& tile : viewport) {
|
||||||
ASSERT_LT(data_index, sizeof(map_data));
|
// EXPECT_EQ(index, dk::to_index(tile.raw_coords()));
|
||||||
const auto expected_value = static_cast<dk::CoordinateScalarType>(map_data[data_index] - '0');
|
// EXPECT_LT(index, sizeof(map_data));
|
||||||
EXPECT_EQ(expected_value, itTile->data());
|
// ASSERT_LT(data_index, sizeof(map_data));
|
||||||
++index;
|
// const auto expected_value = static_cast<dk::CoordinateScalarType>(map_data[data_index] - '0');
|
||||||
++data_index;
|
// EXPECT_EQ(expected_value, tile.data());
|
||||||
if (map_data[data_index] == '\n') {
|
// ++index;
|
||||||
++data_index;
|
// ++data_index;
|
||||||
}
|
// if (map_data[data_index] == '\n') {
|
||||||
|
// ++data_index;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
EXPECT_EQ(map_width * map_height, index);
|
EXPECT_EQ(map_width * map_height, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(asciimapsource, coordinates) {
|
TEST_F(asciimapsource, coordinates) {
|
||||||
const coords2 tsize(tile_size);
|
const coords2 tsize(tile_size);
|
||||||
dk::Viewport<2> full_view(tiler, tiler.map_size(), coords2(0));
|
dk::LayeredViewport<2> full_view(tiler);
|
||||||
dk::PixelConvSquare<2> iso_conv((tsize));
|
dk::PixelConvSquare<2> iso_conv((tsize));
|
||||||
dk::PixelConvDiamond diamond_conv(tsize, true, false);
|
dk::PixelConvDiamond diamond_conv(tsize, true, false);
|
||||||
dk::PixelConvDiamond diamond_conv2(tsize, true, true);
|
dk::PixelConvDiamond diamond_conv2(tsize, true, true);
|
||||||
|
|
||||||
full_view.setFrom(coords2(0));
|
//for (auto itTile = full_view.begin(*layer), itTileEND = full_view.end(*layer); itTile != itTileEND; ++itTile) {
|
||||||
for (auto itTile = full_view.begin(*layer), itTileEND = full_view.end(*layer); itTile != itTileEND; ++itTile) {
|
// //Check isometric coordinates
|
||||||
//Check isometric coordinates
|
// {
|
||||||
{
|
// const coords2 expected_coords(tsize * itTile->block_position());
|
||||||
const coords2 expected_coords(tsize * itTile->block_position());
|
// const auto returned_coords(iso_conv.to_pixel(itTile->block_position(), coords2(0)));
|
||||||
const auto returned_coords(iso_conv.to_pixel(itTile->block_position(), coords2(0)));
|
// EXPECT_EQ(expected_coords, returned_coords);
|
||||||
EXPECT_EQ(expected_coords, returned_coords);
|
// EXPECT_EQ(expected_coords, itTile->screen_position());
|
||||||
EXPECT_EQ(expected_coords, itTile->screen_position());
|
// }
|
||||||
}
|
//
|
||||||
|
// //Check staggered diamond coordinates, second row reentrant
|
||||||
//Check staggered diamond coordinates, second row reentrant
|
// {
|
||||||
{
|
// const auto xoffs = (itTile->block_position().y() % 2 == 0 ? 0 : tsize.x() / 2);
|
||||||
const auto xoffs = (itTile->block_position().y() % 2 == 0 ? 0 : tsize.x() / 2);
|
// const coords2 expected_coords(
|
||||||
const coords2 expected_coords(
|
// xoffs + itTile->block_position().x() * tsize.x(),
|
||||||
xoffs + itTile->block_position().x() * tsize.x(),
|
// itTile->block_position().y() * tsize.y()
|
||||||
itTile->block_position().y() * tsize.y()
|
// );
|
||||||
);
|
// const auto returned_coords(diamond_conv.to_pixel(itTile->block_position(), coords2(0)));
|
||||||
const auto returned_coords(diamond_conv.to_pixel(itTile->block_position(), coords2(0)));
|
// EXPECT_EQ(expected_coords, returned_coords);
|
||||||
EXPECT_EQ(expected_coords, returned_coords);
|
// }
|
||||||
}
|
//
|
||||||
|
// //Check staggered diamond coordinates, first row reentrant
|
||||||
//Check staggered diamond coordinates, first row reentrant
|
// {
|
||||||
{
|
// const auto xoffs = (itTile->block_position().y() % 2 == 1 ? 0 : tsize.x() / 2);
|
||||||
const auto xoffs = (itTile->block_position().y() % 2 == 1 ? 0 : tsize.x() / 2);
|
// const coords2 expected_coords(
|
||||||
const coords2 expected_coords(
|
// xoffs + itTile->block_position().x() * tsize.x(),
|
||||||
xoffs + itTile->block_position().x() * tsize.x(),
|
// itTile->block_position().y() * tsize.y()
|
||||||
itTile->block_position().y() * tsize.y()
|
// );
|
||||||
);
|
// const auto returned_coords(diamond_conv2.to_pixel(itTile->block_position(), coords2(0)));
|
||||||
const auto returned_coords(diamond_conv2.to_pixel(itTile->block_position(), coords2(0)));
|
// EXPECT_EQ(expected_coords, returned_coords);
|
||||||
EXPECT_EQ(expected_coords, returned_coords);
|
// }
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
full_view += dk::VectorT<dk::CoordinateAccumType, 2>(2.5f, -3.1f);
|
full_view += dk::VectorT<dk::CoordinateAccumType, 2>(2.5f, -3.1f);
|
||||||
EXPECT_EQ(coords2(2, -3), full_view.pixel_offset());
|
//EXPECT_EQ(coords2(2, -3), full_view.pixel_offset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
test/unit/layeredviewport.cpp
Normal file
25
test/unit/layeredviewport.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of DoorKeeper.
|
||||||
|
*
|
||||||
|
* DoorKeeper is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DoorKeeper is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with DoorKeeper. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include "doorkeeper/components/layeredviewport.hpp"
|
||||||
|
#include "doorkeeper/components/tyler.hpp"
|
||||||
|
|
||||||
|
TEST(components, layeredviewport) {
|
||||||
|
dk::Tyler<3> tiler;
|
||||||
|
dk::LayeredViewport<3> lview(tiler);
|
||||||
|
}
|
54
test/unit/saltedid.cpp
Normal file
54
test/unit/saltedid.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of DoorKeeper.
|
||||||
|
*
|
||||||
|
* DoorKeeper is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* DoorKeeper is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with DoorKeeper. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include "doorkeeper/implem/idmanager.hpp"
|
||||||
|
|
||||||
|
TEST(components, saltedid) {
|
||||||
|
typedef dk::IDManager<5, 11> id_manager_t;
|
||||||
|
id_manager_t idman;
|
||||||
|
|
||||||
|
EXPECT_EQ(2, sizeof(idman.allocate()));
|
||||||
|
EXPECT_EQ(1, sizeof(id_manager_t::value_type::salt_type));
|
||||||
|
EXPECT_EQ(2, sizeof(id_manager_t::value_type::index_type));
|
||||||
|
EXPECT_EQ(16, id_manager_t::bit_count);
|
||||||
|
|
||||||
|
for (unsigned int z = 0; z < 20; ++z) {
|
||||||
|
auto index = idman.allocate();
|
||||||
|
EXPECT_EQ(0, index.salt());
|
||||||
|
EXPECT_EQ(z + 1, index.index());
|
||||||
|
}
|
||||||
|
auto free_index = idman.allocate();
|
||||||
|
EXPECT_EQ(0, free_index.salt());
|
||||||
|
for (unsigned int z = 0; z < 20; ++z) {
|
||||||
|
auto index = idman.allocate();
|
||||||
|
EXPECT_EQ(0, index.salt());
|
||||||
|
EXPECT_EQ(z + 22, index.index());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int z = 0; z < (1 << 5) - 1; ++z) {
|
||||||
|
idman.free(free_index);
|
||||||
|
free_index = idman.allocate();
|
||||||
|
EXPECT_EQ(z + 1, free_index.salt());
|
||||||
|
EXPECT_EQ(21, free_index.index());
|
||||||
|
}
|
||||||
|
|
||||||
|
idman.free(free_index);
|
||||||
|
free_index = idman.allocate();
|
||||||
|
EXPECT_EQ(0, free_index.salt());
|
||||||
|
EXPECT_EQ(42, free_index.index());
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue