[core] Trigger Source::Impl::reload when a filter or layout property is modified

This commit is contained in:
John Firebaugh
2016-08-29 13:53:55 -07:00
parent fe2a26225f
commit b4864ca9d5
6 changed files with 107 additions and 43 deletions

View File

@@ -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<CircleLayer>("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<Impl>);
public:
virtual ~Layer();
@@ -43,6 +66,38 @@ public:
return is<T>() ? reinterpret_cast<const T*>(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 <class VectorLayer>
// void operator()(VectorLayer&) { ... }
// };
//
template <class V>
auto accept(V&& visitor) {
switch (type) {
case Type::Fill:
return visitor(*as<FillLayer>());
case Type::Line:
return visitor(*as<LineLayer>());
case Type::Circle:
return visitor(*as<CircleLayer>());
case Type::Symbol:
return visitor(*as<SymbolLayer>());
case Type::Raster:
return visitor(*as<RasterLayer>());
case Type::Background:
return visitor(*as<BackgroundLayer>());
case Type::Custom:
return visitor(*as<CustomLayer>());
}
}
const std::string& getID() const;
// Visibility
@@ -56,22 +111,7 @@ public:
void setMaxZoom(float) const;
// Private implementation
class Impl;
const std::unique_ptr<Impl> baseImpl;
protected:
enum class Type {
Fill,
Line,
Circle,
Symbol,
Raster,
Background,
Custom,
};
const Type type;
Layer(Type, std::unique_ptr<Impl>);
};
} // namespace style

View File

@@ -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",

View File

@@ -619,6 +619,27 @@ void NodeMap::SetPaintProperty(const Nan::FunctionCallbackInfo<v8::Value>& 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 <class VectorLayer>
void operator()(VectorLayer& layer) {
layer.setFilter(filter);
}
};
void NodeMap::SetFilter(const Nan::FunctionCallbackInfo<v8::Value>& info) {
using namespace mbgl::style;
using namespace mbgl::style::conversion;
@@ -650,28 +671,7 @@ void NodeMap::SetFilter(const Nan::FunctionCallbackInfo<v8::Value>& info) {
filter = std::move(*converted);
}
if (layer->is<FillLayer>()) {
layer->as<FillLayer>()->setFilter(filter);
info.GetReturnValue().SetUndefined();
return;
}
if (layer->is<LineLayer>()) {
layer->as<LineLayer>()->setFilter(filter);
info.GetReturnValue().SetUndefined();
return;
}
if (layer->is<SymbolLayer>()) {
layer->as<SymbolLayer>()->setFilter(filter);
info.GetReturnValue().SetUndefined();
return;
}
if (layer->is<CircleLayer>()) {
layer->as<CircleLayer>()->setFilter(filter);
info.GetReturnValue().SetUndefined();
return;
}
Nan::ThrowTypeError("layer doesn't support filters");
layer->accept(SetFilterVisitor { filter });
}
void NodeMap::DumpDebugLogs(const Nan::FunctionCallbackInfo<v8::Value>& info) {

View File

@@ -5,7 +5,7 @@ namespace mbgl {
namespace style {
Layer::Layer(Type type_, std::unique_ptr<Impl> baseImpl_)
: baseImpl(std::move(baseImpl_)), type(type_) {
: type(type_), baseImpl(std::move(baseImpl_)) {
}
Layer::~Layer() = default;

View File

@@ -7,6 +7,10 @@
#include <mbgl/style/layers/custom_layer_impl.hpp>
#include <mbgl/style/layers/background_layer.hpp>
#include <mbgl/style/layers/background_layer_impl.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/style/layers/circle_layer.hpp>
#include <mbgl/style/layers/raster_layer.hpp>
#include <mbgl/style/layer_impl.hpp>
#include <mbgl/style/parser.hpp>
#include <mbgl/style/transition_options.hpp>
@@ -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 <class VectorLayer>
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 {

View File

@@ -115,6 +115,7 @@ private:
double defaultPitch;
std::vector<std::unique_ptr<Layer>>::const_iterator findLayer(const std::string& layerID) const;
void reloadLayerSource(Layer&);
// GlyphStoreObserver implementation.
void onGlyphsLoaded(const FontStack&, const GlyphRange&) override;