From 3d26574cb4077a8b48071e08f07574964587f747 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Sun, 21 May 2017 20:35:14 +0300 Subject: [android] replace branches on layer types with visitors --- platform/android/src/style/layers/layer.cpp | 91 +++++++++++++--------------- platform/android/src/style/layers/layers.cpp | 82 ++++++++++++------------- 2 files changed, 83 insertions(+), 90 deletions(-) diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp index 5352f9e548..965b304dcf 100644 --- a/platform/android/src/style/layers/layer.cpp +++ b/platform/android/src/style/layers/layer.cpp @@ -98,12 +98,24 @@ namespace android { } } + struct SetFilterEvaluator { + style::Filter filter; + + void operator()(style::BackgroundLayer&) { Log::Warning(mbgl::Event::JNI, "BackgroundLayer doesn't support filters"); } + void operator()(style::CustomLayer&) { Log::Warning(mbgl::Event::JNI, "CustomLayer doesn't support filters"); } + void operator()(style::RasterLayer&) { Log::Warning(mbgl::Event::JNI, "RasterLayer doesn't support filters"); } + + template + void operator()(LayerType& layer) { + layer.setFilter(filter); + } + }; + void Layer::setFilter(jni::JNIEnv& env, jni::Array> jfilter) { using namespace mbgl::style; using namespace mbgl::style::conversion; Value wrapped(env, jfilter); - Filter filter; Error error; optional converted = convert(wrapped, error); @@ -111,62 +123,45 @@ namespace android { mbgl::Log::Error(mbgl::Event::JNI, "Error setting filter: " + error.message); return; } - filter = std::move(*converted); - - if (layer.is()) { - layer.as()->setFilter(filter); - } else if (layer.is()) { - layer.as()->setFilter(filter); - } else if (layer.is()) { - layer.as()->setFilter(filter); - } else if (layer.is()) { - layer.as()->setFilter(filter); - } else if (layer.is()){ - layer.as()->setFilter(filter); - } else { - mbgl::Log::Warning(mbgl::Event::JNI, "Layer doesn't support filters"); - } + + layer.accept(SetFilterEvaluator {std::move(*converted)}); } - void Layer::setSourceLayer(jni::JNIEnv& env, jni::String sourceLayer) { - using namespace mbgl::style; + struct SetSourceLayerEvaluator { + std::string sourceLayer; - std::string layerId = jni::Make(env, sourceLayer); - - if (layer.is()) { - layer.as()->setSourceLayer(layerId); - } else if (layer.is()) { - layer.as()->setSourceLayer(layerId); - } else if (layer.is()) { - layer.as()->setSourceLayer(layerId); - } else if (layer.is()) { - layer.as()->setSourceLayer(layerId); - } else if(layer.is()) { - layer.as()->setSourceLayer(layerId); - } else { - mbgl::Log::Warning(mbgl::Event::JNI, "Layer doesn't support source layer"); + void operator()(style::BackgroundLayer&) { Log::Warning(mbgl::Event::JNI, "BackgroundLayer doesn't support source layer"); } + void operator()(style::CustomLayer&) { Log::Warning(mbgl::Event::JNI, "CustomLayer doesn't support source layer"); } + void operator()(style::RasterLayer&) { Log::Warning(mbgl::Event::JNI, "RasterLayer doesn't support source layer"); } + + template + void operator()(LayerType& layer) { + layer.setSourceLayer(sourceLayer); } + }; + + void Layer::setSourceLayer(jni::JNIEnv& env, jni::String sourceLayer) { + layer.accept(SetSourceLayerEvaluator {jni::Make(env, sourceLayer)}); } - jni::String Layer::getSourceLayer(jni::JNIEnv& env) { - using namespace mbgl::style; + struct GetSourceLayerEvaluator { + std::string noop(std::string layerType) { + Log::Warning(mbgl::Event::JNI, "%s doesn't support source layer", layerType.c_str()); + return {}; + } - std::string sourceLayerId; - if (layer.is()) { - sourceLayerId = layer.as()->getSourceLayer(); - } else if (layer.is()) { - sourceLayerId = layer.as()->getSourceLayer(); - } else if (layer.is()) { - sourceLayerId = layer.as()->getSourceLayer(); - } else if (layer.is()) { - sourceLayerId = layer.as()->getSourceLayer(); - } else if (layer.is()) { - sourceLayerId = layer.as()->getSourceLayer(); - } else { - mbgl::Log::Warning(mbgl::Event::JNI, "Layer doesn't support source layer"); + std::string operator()(style::BackgroundLayer&) { return noop("BackgroundLayer"); } + std::string operator()(style::CustomLayer&) { return noop("CustomLayer"); } + std::string operator()(style::RasterLayer&) { return noop("RasterLayer"); } + + template + std::string operator()(LayerType& layer) { + return layer.getSourceLayer(); } + }; - return jni::Make(env, sourceLayerId); + jni::String Layer::getSourceLayer(jni::JNIEnv& env) { + return jni::Make(env, layer.accept(GetSourceLayerEvaluator())); } jni::jfloat Layer::getMinZoom(jni::JNIEnv&){ diff --git a/platform/android/src/style/layers/layers.cpp b/platform/android/src/style/layers/layers.cpp index 5c49f875ee..9803b6f841 100644 --- a/platform/android/src/style/layers/layers.cpp +++ b/platform/android/src/style/layers/layers.cpp @@ -24,53 +24,51 @@ namespace mbgl { namespace android { -static Layer* initializeLayerPeer(mbgl::Map& map, mbgl::style::Layer& coreLayer) { - if (coreLayer.is()) { - return new BackgroundLayer(map, *coreLayer.as()); - } else if (coreLayer.is()) { - return new CircleLayer(map, *coreLayer.as()); - } else if (coreLayer.is()) { - return new FillExtrusionLayer(map, *coreLayer.as()); - } else if (coreLayer.is()) { - return new FillLayer(map, *coreLayer.as()); - } else if (coreLayer.is()) { - return new LineLayer(map, *coreLayer.as()); - } else if (coreLayer.is()) { - return new RasterLayer(map, *coreLayer.as()); - } else if (coreLayer.is()) { - return new SymbolLayer(map, *coreLayer.as()); - } else if (coreLayer.is()) { - return new CustomLayer(map, *coreLayer.as()); - } else { - return new UnknownLayer(map, coreLayer); +// Mapping from style layers to peer classes +template struct PeerType {}; +template <> struct PeerType { using Type = android::BackgroundLayer; }; +template <> struct PeerType { using Type = android::CircleLayer; }; +template <> struct PeerType { using Type = android::FillExtrusionLayer; }; +template <> struct PeerType { using Type = android::FillLayer; }; +template <> struct PeerType { using Type = android::LineLayer; }; +template <> struct PeerType { using Type = android::RasterLayer; }; +template <> struct PeerType { using Type = android::SymbolLayer; }; +template <> struct PeerType { using Type = android::CustomLayer; }; + +// Inititalizes a non-owning peer +struct LayerPeerIntitializer { + mbgl::Map& map; + + template + Layer* operator()(LayerType& layer) { + return new typename PeerType::Type(map, layer); } -} +}; -template -static PeerType* createPeer(Map& map, std::unique_ptr layer) { - return new PeerType(map, std::move(std::unique_ptr(layer.release()->as()))); +static Layer* initializeLayerPeer(mbgl::Map& map, mbgl::style::Layer& coreLayer) { + Layer* layer = coreLayer.accept(LayerPeerIntitializer {map}); + return layer ? layer : new UnknownLayer(map, coreLayer); } -static Layer* initializeLayerPeer(Map& map, std::unique_ptr coreLayer) { - if (coreLayer->is()) { - return createPeer(map, std::move(coreLayer)); - } else if (coreLayer->is()) { - return createPeer(map, std::move(coreLayer)); - } else if (coreLayer->is()) { - return createPeer(map, std::move(coreLayer)); - } else if (coreLayer->is()) { - return createPeer(map, std::move(coreLayer)); - } else if (coreLayer->is()) { - return createPeer(map, std::move(coreLayer)); - } else if (coreLayer->is()) { - return createPeer(map, std::move(coreLayer)); - } else if (coreLayer->is()) { - return createPeer(map, std::move(coreLayer)); - } else if (coreLayer->is()) { - return createPeer(map, std::move(coreLayer)); - } else { - return new UnknownLayer(map, std::move(coreLayer)); +// Initializes an owning peer +// Only usable once since it needs to pass on ownership +// of the given layer and thus enforced to be an rvalue +struct UniqueLayerPeerIntitializer { + mbgl::Map& map; + std::unique_ptr layer; + + template + Layer* operator()(LayerType&) && { + return new typename PeerType::Type( + map, + std::unique_ptr(layer.release()->as()) + ); } +}; + +static Layer* initializeLayerPeer(Map& map, std::unique_ptr coreLayer) { + Layer* layer = coreLayer->accept(UniqueLayerPeerIntitializer {map, std::move(coreLayer)}); + return layer ? layer : new UnknownLayer(map, std::move(coreLayer)); } jni::jobject* createJavaLayerPeer(jni::JNIEnv& env, Map& map, style::Layer& coreLayer) { -- cgit v1.2.1