diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/mbgl/map/mode.hpp | 3 | ||||
-rw-r--r-- | include/mbgl/style/conversion/custom_geometry_source_options.hpp | 64 | ||||
-rw-r--r-- | include/mbgl/style/layer.hpp | 4 | ||||
-rw-r--r-- | include/mbgl/style/source.hpp | 4 | ||||
-rw-r--r-- | include/mbgl/style/sources/custom_geometry_source.hpp | 56 | ||||
-rw-r--r-- | include/mbgl/style/sources/geojson_source.hpp | 2 | ||||
-rw-r--r-- | include/mbgl/style/types.hpp | 3 | ||||
-rw-r--r-- | include/mbgl/tile/tile_id.hpp | 6 | ||||
-rw-r--r-- | include/mbgl/util/any.hpp | 10 | ||||
-rw-r--r-- | include/mbgl/util/unique_any.hpp | 275 |
10 files changed, 408 insertions, 19 deletions
diff --git a/include/mbgl/map/mode.hpp b/include/mbgl/map/mode.hpp index 256d152e43..4ee289d855 100644 --- a/include/mbgl/map/mode.hpp +++ b/include/mbgl/map/mode.hpp @@ -11,7 +11,8 @@ using EnumType = uint32_t; enum class MapMode : EnumType { Continuous, // continually updating map - Still, // a once-off still image + Static, // a once-off still image of an arbitrary viewport + Tile // a once-off still image of a single tile }; // We can choose to constrain the map both horizontally or vertically, or only diff --git a/include/mbgl/style/conversion/custom_geometry_source_options.hpp b/include/mbgl/style/conversion/custom_geometry_source_options.hpp new file mode 100644 index 0000000000..73b141e799 --- /dev/null +++ b/include/mbgl/style/conversion/custom_geometry_source_options.hpp @@ -0,0 +1,64 @@ +#pragma once + +#include <mbgl/style/conversion.hpp> +#include <mbgl/style/sources/custom_geometry_source.hpp> + +namespace mbgl { +namespace style { +namespace conversion { + +template <> +struct Converter<CustomGeometrySource::Options> { + + template <class V> + optional<CustomGeometrySource::Options> operator()(const V& value, Error& error) const { + CustomGeometrySource::Options options; + + const auto minzoomValue = objectMember(value, "minzoom"); + if (minzoomValue) { + if (toNumber(*minzoomValue)) { + options.zoomRange.min = static_cast<uint8_t>(*toNumber(*minzoomValue)); + } else { + error = { "GeoJSON source minzoom value must be a number" }; + return {}; + } + } + + const auto maxzoomValue = objectMember(value, "maxzoom"); + if (maxzoomValue) { + if (toNumber(*maxzoomValue)) { + options.zoomRange.max = static_cast<uint8_t>(*toNumber(*maxzoomValue)); + } else { + error = { "GeoJSON source maxzoom value must be a number" }; + return {}; + } + } + + const auto bufferValue = objectMember(value, "buffer"); + if (bufferValue) { + if (toNumber(*bufferValue)) { + options.tileOptions.buffer = static_cast<uint16_t>(*toNumber(*bufferValue)); + } else { + error = { "GeoJSON source buffer value must be a number" }; + return {}; + } + } + + const auto toleranceValue = objectMember(value, "tolerance"); + if (toleranceValue) { + if (toNumber(*toleranceValue)) { + options.tileOptions.tolerance = static_cast<double>(*toNumber(*toleranceValue)); + } else { + error = { "GeoJSON source tolerance value must be a number" }; + return {}; + } + } + + return { options }; + } + +}; + +} // namespace conversion +} // namespace style +} // namespace mbgl diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp index c6a3c0e735..eb2dbf830b 100644 --- a/include/mbgl/style/layer.hpp +++ b/include/mbgl/style/layer.hpp @@ -1,7 +1,7 @@ #pragma once #include <mbgl/util/noncopyable.hpp> -#include <mbgl/util/any.hpp> +#include <mbgl/util/unique_any.hpp> #include <mbgl/util/immutable.hpp> #include <mbgl/style/layer_type.hpp> #include <mbgl/style/types.hpp> @@ -126,7 +126,7 @@ public: // For use in SDK bindings, which store a reference to a platform-native peer // object here, so that separately-obtained references to this object share // identical platform-native peers. - any peer; + util::unique_any peer; }; } // namespace style diff --git a/include/mbgl/style/source.hpp b/include/mbgl/style/source.hpp index cec9619451..0b6a6c72d9 100644 --- a/include/mbgl/style/source.hpp +++ b/include/mbgl/style/source.hpp @@ -2,7 +2,7 @@ #include <mbgl/util/noncopyable.hpp> #include <mbgl/util/optional.hpp> -#include <mbgl/util/any.hpp> +#include <mbgl/util/unique_any.hpp> #include <mbgl/util/immutable.hpp> #include <mbgl/style/types.hpp> @@ -76,7 +76,7 @@ public: // For use in SDK bindings, which store a reference to a platform-native peer // object here, so that separately-obtained references to this object share // identical platform-native peers. - any peer; + util::unique_any peer; }; } // namespace style diff --git a/include/mbgl/style/sources/custom_geometry_source.hpp b/include/mbgl/style/sources/custom_geometry_source.hpp new file mode 100644 index 0000000000..a0b990b44b --- /dev/null +++ b/include/mbgl/style/sources/custom_geometry_source.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include <mbgl/style/source.hpp> +#include <mbgl/util/geo.hpp> +#include <mbgl/util/geojson.hpp> +#include <mbgl/util/range.hpp> +#include <mbgl/util/constants.hpp> + +namespace mbgl { + +class OverscaledTileID; +class CanonicalTileID; +template <class T> +class Actor; + +namespace style { + +using TileFunction = std::function<void(const CanonicalTileID&)>; + +class CustomTileLoader; + +class CustomGeometrySource : public Source { +public: + struct TileOptions { + double tolerance = 0.375; + uint16_t tileSize = util::tileSize; + uint16_t buffer = 128; + }; + + struct Options { + TileFunction fetchTileFunction; + TileFunction cancelTileFunction; + Range<uint8_t> zoomRange = { 0, 18}; + TileOptions tileOptions; + }; +public: + CustomGeometrySource(std::string id, CustomGeometrySource::Options options); + ~CustomGeometrySource() final; + void loadDescription(FileSource&) final; + void setTileData(const CanonicalTileID&, const GeoJSON&); + void invalidateTile(const CanonicalTileID&); + void invalidateRegion(const LatLngBounds&); + // Private implementation + class Impl; + const Impl& impl() const; +private: + std::unique_ptr<Actor<CustomTileLoader>> loader; +}; + +template <> +inline bool Source::is<CustomGeometrySource>() const { + return getType() == SourceType::CustomVector; +} + +} // namespace style +} // namespace mbgl diff --git a/include/mbgl/style/sources/geojson_source.hpp b/include/mbgl/style/sources/geojson_source.hpp index 5bdf1ef957..372e7c7a78 100644 --- a/include/mbgl/style/sources/geojson_source.hpp +++ b/include/mbgl/style/sources/geojson_source.hpp @@ -3,6 +3,7 @@ #include <mbgl/style/source.hpp> #include <mbgl/util/geojson.hpp> #include <mbgl/util/optional.hpp> +#include <mbgl/util/constants.hpp> namespace mbgl { @@ -14,6 +15,7 @@ struct GeoJSONOptions { // GeoJSON-VT options uint8_t minzoom = 0; uint8_t maxzoom = 18; + uint16_t tileSize = util::tileSize; uint16_t buffer = 128; double tolerance = 0.375; diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp index 2ed95f08b8..6fe457e181 100644 --- a/include/mbgl/style/types.hpp +++ b/include/mbgl/style/types.hpp @@ -13,7 +13,8 @@ enum class SourceType : uint8_t { GeoJSON, Video, Annotations, - Image + Image, + CustomVector }; enum class VisibilityType : bool { diff --git a/include/mbgl/tile/tile_id.hpp b/include/mbgl/tile/tile_id.hpp index 0457dd3a07..11fb5ce537 100644 --- a/include/mbgl/tile/tile_id.hpp +++ b/include/mbgl/tile/tile_id.hpp @@ -30,9 +30,9 @@ public: CanonicalTileID scaledTo(uint8_t z) const; std::array<CanonicalTileID, 4> children() const; - const uint8_t z; - const uint32_t x; - const uint32_t y; + uint8_t z; + uint32_t x; + uint32_t y; }; ::std::ostream& operator<<(::std::ostream& os, const CanonicalTileID& rhs); diff --git a/include/mbgl/util/any.hpp b/include/mbgl/util/any.hpp deleted file mode 100644 index eea64b188a..0000000000 --- a/include/mbgl/util/any.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include <linb/any.hpp> - -namespace mbgl { - -using linb::any; -using linb::any_cast; - -} // namespace mbgl diff --git a/include/mbgl/util/unique_any.hpp b/include/mbgl/util/unique_any.hpp new file mode 100644 index 0000000000..d488930a03 --- /dev/null +++ b/include/mbgl/util/unique_any.hpp @@ -0,0 +1,275 @@ +#pragma once + +#include <typeinfo> +#include <type_traits> +#include <stdexcept> +namespace mbgl { +namespace util { + +class bad_any_cast : public std::bad_cast { +public: + const char* what() const noexcept override { + return "bad any_cast<>()"; + } +}; +/** + * A variant of `std::any` for non-copyable types. + * + * Use `unique_any` for non-copyable types (e.g. `std::unique_ptr<T>`) + * or to ensure that no copies are made of copyable types that are + * moved in. + * + * `uniqe_any` differs from `std::any` in that it does not support copy construction + * or copy assignment. It also does not require the contained type to be copy + * constructible. + * + * The `any_cast<T>()` methods work similar to `std::any_cast<T>()` except that + * non-copyable types may only be cast to references. + * + * Example usage: + * unique_any u1(3); + * auto u2 = unique_any(std::move(u1)); // u1 is moved from + * int i = any_cast<int>(u2); + * + * unique_any u2; + * u2 = std::unique_ptr<int>(new int); + * std::unique_ptr<int> iPtr = any_cast<std::unique_ptr<int>>(std::move(u2)); + * + * Inspired by linb::any (https://github.com/thelink2012/any) and the + * libc++ implementation (https://github.com/llvm-mirror/libcxx). + */ +class unique_any final +{ +public: + unique_any() = default; + + //Copy constructor (deleted) + unique_any(const unique_any& rhs) = delete; + + unique_any(unique_any&& rhs) : vtable(rhs.vtable) { + if (vtable) { + vtable->move(std::move(rhs.storage), storage); + } + rhs.vtable = nullptr; + } + + // Constructs with a direct-initilizated object of type ValueType + template <typename ValueType, + typename _Vt = std::decay_t<ValueType>, + typename = std::enable_if_t<!std::is_same<_Vt, unique_any>::value> > + unique_any(ValueType&& value) { + create(std::forward<ValueType>(value)); + } + + ~unique_any() { + reset(); + } + + unique_any& operator=(unique_any&& rhs) { + unique_any(std::move(rhs)).swap(*this); + return *this; + } + + template <class ValueType, + typename = std::enable_if_t<!std::is_same<std::decay_t<ValueType>, unique_any>::value> > + unique_any& operator=(ValueType&& rhs) { + unique_any(std::forward<ValueType>(rhs)).swap(*this); + return *this; + } + + void reset() { + if (vtable) { + vtable->destroy(storage); + vtable = nullptr; + } + } + + void swap(unique_any& rhs) { + if (this == &rhs) { + return; + } else { + unique_any tmp(std::move(rhs)); + rhs.vtable = vtable; + if (rhs.vtable) { + rhs.vtable->move(std::move(storage), rhs.storage); + } + vtable = tmp.vtable; + if (vtable) { + vtable->move(std::move(tmp.storage), storage); + } + } + } + + const std::type_info& type() const { + return !has_value()? typeid(void) : vtable->type(); + } + + bool has_value() const { + return vtable != nullptr; + } + +private: + + union Storage { + using StackStorage = std::aligned_storage_t<3*sizeof(void*), std::alignment_of<void*>::value>; + Storage() = default; + + void * dynamic { nullptr }; + StackStorage stack; + }; + + template<typename T> + struct AllocateOnStack : std::integral_constant<bool, + sizeof(T) <= sizeof(Storage::stack) + && std::alignment_of<T>::value <= std::alignment_of<Storage::StackStorage>::value + && std::is_nothrow_move_constructible<T>::value> { + }; + + struct VTable { + virtual ~VTable() = default; + virtual void move(Storage&& src, Storage& dest) = 0; + virtual void destroy(Storage&) = 0; + virtual const std::type_info& type() = 0; + }; + + template <typename ValueType> + struct VTableHeap : public VTable { + void move(Storage&& src, Storage& dest) override { + destroy(dest); + dest.dynamic = src.dynamic; + } + + void destroy(Storage& s) override { + if (s.dynamic) { + delete reinterpret_cast<ValueType*>(s.dynamic); + } + s.dynamic = nullptr; + } + + const std::type_info& type() override { + return typeid(ValueType); + } + }; + + template <typename ValueType> + struct VTableStack : public VTable { + void move(Storage&& src, Storage& dest) override { + auto srcValue = reinterpret_cast<ValueType&&>(src.stack); + new (static_cast<void*>(&dest.stack)) ValueType(std::move(srcValue)); + srcValue.~ValueType(); + } + + void destroy(Storage& s) override { + reinterpret_cast<ValueType&>(s.stack).~ValueType(); + } + + const std::type_info& type() override { + return typeid(ValueType); + } + }; + + template <typename ValueType> + static VTable* vtableForType() { + using VTableType = std::conditional_t<AllocateOnStack<ValueType>::value, VTableStack<ValueType>, VTableHeap<ValueType> >; + static VTableType vtable; + return &vtable; + } + + template <typename ValueType, typename _Vt> + std::enable_if_t<AllocateOnStack<_Vt>::value> + createStorage(ValueType&& value) { + new (static_cast<void*>(&storage.stack)) _Vt(std::forward<ValueType>(value)); + } + + template <typename ValueType, typename _Vt> + std::enable_if_t<!AllocateOnStack<_Vt>::value> + createStorage(ValueType&& value) { + storage.dynamic = static_cast<void*>(new _Vt(std::forward<ValueType>(value))); + } + + template <typename ValueType> + void create(ValueType&& value) { + using _Vt = std::decay_t<ValueType>; + vtable = vtableForType<_Vt>(); + createStorage<ValueType, _Vt>(std::forward<ValueType>(value)); + } + + VTable* vtable { nullptr }; + Storage storage; + +protected: + template<class ValueType> + friend const ValueType* any_cast(const unique_any* operand) ; + + template<class ValueType> + friend ValueType* any_cast(unique_any* operand) ; + + template<typename ValueType, typename _Vt = std::decay_t<ValueType> > + ValueType* cast() + { + return reinterpret_cast<ValueType *>( + AllocateOnStack<_Vt>::value ? &storage.stack : storage.dynamic); + } +}; + +template<typename ValueType> +inline const ValueType* any_cast(const unique_any* any) +{ + return any_cast<ValueType>(const_cast<unique_any *>(any)); +} + +template<typename ValueType> +inline ValueType* any_cast(unique_any* any) +{ + if(any == nullptr || any->type() != typeid(ValueType)) + return nullptr; + else + return any->cast<ValueType>(); +} + +template<typename ValueType, typename _Vt = std::decay_t<ValueType> > +inline ValueType any_cast(const unique_any& any) +{ + static_assert(std::is_constructible<ValueType, const _Vt&>::value, + "any_cast type can't construct copy of contained object"); + auto temp = any_cast<_Vt>(&any); + if (temp == nullptr) { + throw bad_any_cast(); + } + return static_cast<ValueType>(*temp); +} + +template<typename ValueType, typename _Vt = std::decay_t<ValueType> > +inline ValueType any_cast(unique_any& any) +{ + static_assert(std::is_constructible<ValueType, const _Vt&>::value, + "any_cast type can't construct copy of contained object"); + auto temp = any_cast<_Vt>(&any); + if (temp == nullptr) { + throw bad_any_cast(); + } + return static_cast<ValueType>(*temp); +} + +template<typename ValueType, typename _Vt = std::remove_cv_t<ValueType> > +inline ValueType any_cast(unique_any&& any) +{ + auto temp = any_cast<_Vt>(&any); + if (temp == nullptr) { + throw bad_any_cast(); + } + auto retValue = static_cast<ValueType>(std::move(*temp)); + any.reset(); + return std::move(retValue); +} + +} // namespace util +} // namespace mbgl + +namespace std { + +inline void swap(mbgl::util::unique_any& lhs, mbgl::util::unique_any& rhs) { + lhs.swap(rhs); +} + +} // namespace std |