From b4864ca9d5a18dda4476baa31e33fe8547d55b40 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 29 Aug 2016 13:53:55 -0700 Subject: [PATCH] [core] Trigger Source::Impl::reload when a filter or layout property is modified --- include/mbgl/style/layer.hpp | 70 ++++++++++++++++++++++++++-------- package.json | 2 +- platform/node/src/node_map.cpp | 44 ++++++++++----------- src/mbgl/style/layer.cpp | 2 +- src/mbgl/style/style.cpp | 31 +++++++++++++-- src/mbgl/style/style.hpp | 1 + 6 files changed, 107 insertions(+), 43 deletions(-) diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp index 1eff9eb3d..925629a34 100644 --- a/include/mbgl/style/layer.hpp +++ b/include/mbgl/style/layer.hpp @@ -8,6 +8,14 @@ namespace mbgl { namespace style { +class FillLayer; +class LineLayer; +class CircleLayer; +class SymbolLayer; +class RasterLayer; +class BackgroundLayer; +class CustomLayer; + /** * The runtime representation of a [layer](https://www.mapbox.com/mapbox-gl-style-spec/#layers) from the Mapbox Style * Specification. @@ -25,6 +33,21 @@ namespace style { * auto circleLayer = std::make_unique("my-circle-layer"); */ class Layer : public mbgl::util::noncopyable { +protected: + enum class Type { + Fill, + Line, + Circle, + Symbol, + Raster, + Background, + Custom, + }; + + class Impl; + const Type type; + Layer(Type, std::unique_ptr); + public: virtual ~Layer(); @@ -43,6 +66,38 @@ public: return is() ? reinterpret_cast(this) : nullptr; } + // Convenience method for dynamic dispatch on the concrete layer type. Using + // method overloading, this allows consolidation of logic common to vector-based + // layers (Fill, Line, Circle, or Symbol). For example: + // + // struct Visitor { + // void operator()(CustomLayer&) { ... } + // void operator()(RasterLayer&) { ... } + // void operator()(BackgroundLayer&) { ... } + // template + // void operator()(VectorLayer&) { ... } + // }; + // + template + auto accept(V&& visitor) { + switch (type) { + case Type::Fill: + return visitor(*as()); + case Type::Line: + return visitor(*as()); + case Type::Circle: + return visitor(*as()); + case Type::Symbol: + return visitor(*as()); + case Type::Raster: + return visitor(*as()); + case Type::Background: + return visitor(*as()); + case Type::Custom: + return visitor(*as()); + } + } + const std::string& getID() const; // Visibility @@ -56,22 +111,7 @@ public: void setMaxZoom(float) const; // Private implementation - class Impl; const std::unique_ptr baseImpl; - -protected: - enum class Type { - Fill, - Line, - Circle, - Symbol, - Raster, - Background, - Custom, - }; - - const Type type; - Layer(Type, std::unique_ptr); }; } // namespace style diff --git a/package.json b/package.json index 67bde9f48..41a269687 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "express": "^4.11.1", "mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#de2ab007455aa2587c552694c68583f94c9f2747", "mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#83b1a3e5837d785af582efd5ed1a212f2df6a4ae", - "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#b8354e386693a4045aa309e1e85507de4d9aadec", + "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#ac0e1907ff628e662dafeb44cdab6e594b59a59b", "mkdirp": "^0.5.1", "node-cmake": "^1.2.1", "request": "^2.72.0", diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index 31259f897..a563264db 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -619,6 +619,27 @@ void NodeMap::SetPaintProperty(const Nan::FunctionCallbackInfo& info) info.GetReturnValue().SetUndefined(); } +struct SetFilterVisitor { + mbgl::style::Filter& filter; + + void operator()(mbgl::style::CustomLayer&) { + Nan::ThrowTypeError("layer doesn't support filters"); + } + + void operator()(mbgl::style::RasterLayer&) { + Nan::ThrowTypeError("layer doesn't support filters"); + } + + void operator()(mbgl::style::BackgroundLayer&) { + Nan::ThrowTypeError("layer doesn't support filters"); + } + + template + void operator()(VectorLayer& layer) { + layer.setFilter(filter); + } +}; + void NodeMap::SetFilter(const Nan::FunctionCallbackInfo& info) { using namespace mbgl::style; using namespace mbgl::style::conversion; @@ -650,28 +671,7 @@ void NodeMap::SetFilter(const Nan::FunctionCallbackInfo& info) { filter = std::move(*converted); } - if (layer->is()) { - layer->as()->setFilter(filter); - info.GetReturnValue().SetUndefined(); - return; - } - if (layer->is()) { - layer->as()->setFilter(filter); - info.GetReturnValue().SetUndefined(); - return; - } - if (layer->is()) { - layer->as()->setFilter(filter); - info.GetReturnValue().SetUndefined(); - return; - } - if (layer->is()) { - layer->as()->setFilter(filter); - info.GetReturnValue().SetUndefined(); - return; - } - - Nan::ThrowTypeError("layer doesn't support filters"); + layer->accept(SetFilterVisitor { filter }); } void NodeMap::DumpDebugLogs(const Nan::FunctionCallbackInfo& info) { diff --git a/src/mbgl/style/layer.cpp b/src/mbgl/style/layer.cpp index 6eff64ae0..4d4e793ec 100644 --- a/src/mbgl/style/layer.cpp +++ b/src/mbgl/style/layer.cpp @@ -5,7 +5,7 @@ namespace mbgl { namespace style { Layer::Layer(Type type_, std::unique_ptr baseImpl_) - : baseImpl(std::move(baseImpl_)), type(type_) { + : type(type_), baseImpl(std::move(baseImpl_)) { } Layer::~Layer() = default; diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 99333b4a7..e797ec7a5 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -7,6 +7,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -483,17 +487,36 @@ void Style::onSpriteError(std::exception_ptr error) { observer->onResourceError(error); } -void Style::onLayerFilterChanged(Layer&) { - // TODO: reload source +struct LayerSourceReloadVisitor { + Style& style; + + void operator()(CustomLayer&) { assert(false); } + void operator()(RasterLayer&) { assert(false); } + void operator()(BackgroundLayer&) { assert(false); } + + template + void operator()(VectorLayer& layer) { + Source* source = style.getSource(layer.getSourceID()); + if (!source) return; + source->baseImpl->reload(); + } +}; + +void Style::reloadLayerSource(Layer& layer) { + layer.accept(LayerSourceReloadVisitor { *this }); +} + +void Style::onLayerFilterChanged(Layer& layer) { + reloadLayerSource(layer); } void Style::onLayerPaintPropertyChanged(Layer&) { observer->onUpdate(Update::RecalculateStyle | Update::Classes); } -void Style::onLayerLayoutPropertyChanged(Layer&) { +void Style::onLayerLayoutPropertyChanged(Layer& layer) { observer->onUpdate(Update::RecalculateStyle); - // TODO: reload source + reloadLayerSource(layer); } void Style::dumpDebugLogs() const { diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 9e9ec1a03..26b96fba2 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -115,6 +115,7 @@ private: double defaultPitch; std::vector>::const_iterator findLayer(const std::string& layerID) const; + void reloadLayerSource(Layer&); // GlyphStoreObserver implementation. void onGlyphsLoaded(const FontStack&, const GlyphRange&) override;