[android] replace branches on layer types with visitors

This commit is contained in:
Ivo van Dongen
2017-05-21 20:35:14 +03:00
committed by Ivo van Dongen
parent 95d2ed7b95
commit 3d26574cb4
2 changed files with 84 additions and 91 deletions

View File

@@ -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 <class LayerType>
void operator()(LayerType& layer) {
layer.setFilter(filter);
}
};
void Layer::setFilter(jni::JNIEnv& env, jni::Array<jni::Object<>> jfilter) {
using namespace mbgl::style;
using namespace mbgl::style::conversion;
Value wrapped(env, jfilter);
Filter filter;
Error error;
optional<Filter> converted = convert<Filter>(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<FillLayer>()) {
layer.as<FillLayer>()->setFilter(filter);
} else if (layer.is<LineLayer>()) {
layer.as<LineLayer>()->setFilter(filter);
} else if (layer.is<SymbolLayer>()) {
layer.as<SymbolLayer>()->setFilter(filter);
} else if (layer.is<CircleLayer>()) {
layer.as<CircleLayer>()->setFilter(filter);
} else if (layer.is<FillExtrusionLayer>()){
layer.as<FillExtrusionLayer>()->setFilter(filter);
} else {
mbgl::Log::Warning(mbgl::Event::JNI, "Layer doesn't support filters");
}
layer.accept(SetFilterEvaluator {std::move(*converted)});
}
struct SetSourceLayerEvaluator {
std::string sourceLayer;
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 <class LayerType>
void operator()(LayerType& layer) {
layer.setSourceLayer(sourceLayer);
}
};
void Layer::setSourceLayer(jni::JNIEnv& env, jni::String sourceLayer) {
using namespace mbgl::style;
std::string layerId = jni::Make<std::string>(env, sourceLayer);
if (layer.is<FillLayer>()) {
layer.as<FillLayer>()->setSourceLayer(layerId);
} else if (layer.is<LineLayer>()) {
layer.as<LineLayer>()->setSourceLayer(layerId);
} else if (layer.is<SymbolLayer>()) {
layer.as<SymbolLayer>()->setSourceLayer(layerId);
} else if (layer.is<CircleLayer>()) {
layer.as<CircleLayer>()->setSourceLayer(layerId);
} else if(layer.is<FillExtrusionLayer>()) {
layer.as<FillExtrusionLayer>()->setSourceLayer(layerId);
} else {
mbgl::Log::Warning(mbgl::Event::JNI, "Layer doesn't support source layer");
}
layer.accept(SetSourceLayerEvaluator {jni::Make<std::string>(env, sourceLayer)});
}
jni::String Layer::getSourceLayer(jni::JNIEnv& env) {
using namespace mbgl::style;
std::string sourceLayerId;
if (layer.is<FillLayer>()) {
sourceLayerId = layer.as<FillLayer>()->getSourceLayer();
} else if (layer.is<LineLayer>()) {
sourceLayerId = layer.as<LineLayer>()->getSourceLayer();
} else if (layer.is<SymbolLayer>()) {
sourceLayerId = layer.as<SymbolLayer>()->getSourceLayer();
} else if (layer.is<CircleLayer>()) {
sourceLayerId = layer.as<CircleLayer>()->getSourceLayer();
} else if (layer.is<FillExtrusionLayer>()) {
sourceLayerId = layer.as<FillExtrusionLayer>()->getSourceLayer();
} else {
mbgl::Log::Warning(mbgl::Event::JNI, "Layer doesn't support source layer");
struct GetSourceLayerEvaluator {
std::string noop(std::string layerType) {
Log::Warning(mbgl::Event::JNI, "%s doesn't support source layer", layerType.c_str());
return {};
}
return jni::Make<jni::String>(env, sourceLayerId);
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 <class LayerType>
std::string operator()(LayerType& layer) {
return layer.getSourceLayer();
}
};
jni::String Layer::getSourceLayer(jni::JNIEnv& env) {
return jni::Make<jni::String>(env, layer.accept(GetSourceLayerEvaluator()));
}
jni::jfloat Layer::getMinZoom(jni::JNIEnv&){

View File

@@ -24,53 +24,51 @@
namespace mbgl {
namespace android {
static Layer* initializeLayerPeer(mbgl::Map& map, mbgl::style::Layer& coreLayer) {
if (coreLayer.is<mbgl::style::BackgroundLayer>()) {
return new BackgroundLayer(map, *coreLayer.as<mbgl::style::BackgroundLayer>());
} else if (coreLayer.is<mbgl::style::CircleLayer>()) {
return new CircleLayer(map, *coreLayer.as<mbgl::style::CircleLayer>());
} else if (coreLayer.is<mbgl::style::FillExtrusionLayer>()) {
return new FillExtrusionLayer(map, *coreLayer.as<mbgl::style::FillExtrusionLayer>());
} else if (coreLayer.is<mbgl::style::FillLayer>()) {
return new FillLayer(map, *coreLayer.as<mbgl::style::FillLayer>());
} else if (coreLayer.is<mbgl::style::LineLayer>()) {
return new LineLayer(map, *coreLayer.as<mbgl::style::LineLayer>());
} else if (coreLayer.is<mbgl::style::RasterLayer>()) {
return new RasterLayer(map, *coreLayer.as<mbgl::style::RasterLayer>());
} else if (coreLayer.is<mbgl::style::SymbolLayer>()) {
return new SymbolLayer(map, *coreLayer.as<mbgl::style::SymbolLayer>());
} else if (coreLayer.is<mbgl::style::CustomLayer>()) {
return new CustomLayer(map, *coreLayer.as<mbgl::style::CustomLayer>());
} else {
return new UnknownLayer(map, coreLayer);
// Mapping from style layers to peer classes
template <class> struct PeerType {};
template <> struct PeerType<style::BackgroundLayer> { using Type = android::BackgroundLayer; };
template <> struct PeerType<style::CircleLayer> { using Type = android::CircleLayer; };
template <> struct PeerType<style::FillExtrusionLayer> { using Type = android::FillExtrusionLayer; };
template <> struct PeerType<style::FillLayer> { using Type = android::FillLayer; };
template <> struct PeerType<style::LineLayer> { using Type = android::LineLayer; };
template <> struct PeerType<style::RasterLayer> { using Type = android::RasterLayer; };
template <> struct PeerType<style::SymbolLayer> { using Type = android::SymbolLayer; };
template <> struct PeerType<style::CustomLayer> { using Type = android::CustomLayer; };
// Inititalizes a non-owning peer
struct LayerPeerIntitializer {
mbgl::Map& map;
template <class LayerType>
Layer* operator()(LayerType& layer) {
return new typename PeerType<LayerType>::Type(map, layer);
}
};
static Layer* initializeLayerPeer(mbgl::Map& map, mbgl::style::Layer& coreLayer) {
Layer* layer = coreLayer.accept(LayerPeerIntitializer {map});
return layer ? layer : new UnknownLayer(map, coreLayer);
}
template <class LayerType, class PeerType>
static PeerType* createPeer(Map& map, std::unique_ptr<mbgl::style::Layer> layer) {
return new PeerType(map, std::move(std::unique_ptr<LayerType>(layer.release()->as<LayerType>())));
}
// 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<style::Layer> layer;
template <class LayerType>
Layer* operator()(LayerType&) && {
return new typename PeerType<LayerType>::Type(
map,
std::unique_ptr<LayerType>(layer.release()->as<LayerType>())
);
}
};
static Layer* initializeLayerPeer(Map& map, std::unique_ptr<mbgl::style::Layer> coreLayer) {
if (coreLayer->is<style::BackgroundLayer>()) {
return createPeer<style::BackgroundLayer, BackgroundLayer>(map, std::move(coreLayer));
} else if (coreLayer->is<style::CircleLayer>()) {
return createPeer<style::CircleLayer, CircleLayer>(map, std::move(coreLayer));
} else if (coreLayer->is<style::FillExtrusionLayer>()) {
return createPeer<style::FillExtrusionLayer, FillExtrusionLayer>(map, std::move(coreLayer));
} else if (coreLayer->is<style::FillLayer>()) {
return createPeer<style::FillLayer, FillLayer>(map, std::move(coreLayer));
} else if (coreLayer->is<style::LineLayer>()) {
return createPeer<style::LineLayer, LineLayer>(map, std::move(coreLayer));
} else if (coreLayer->is<style::RasterLayer>()) {
return createPeer<style::RasterLayer, RasterLayer>(map, std::move(coreLayer));
} else if (coreLayer->is<style::SymbolLayer>()) {
return createPeer<style::SymbolLayer, SymbolLayer>(map, std::move(coreLayer));
} else if (coreLayer->is<mbgl::style::CustomLayer>()) {
return createPeer<style::SymbolLayer, SymbolLayer>(map, std::move(coreLayer));
} else {
return new UnknownLayer(map, std::move(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) {