[core] Simplify FilterEvaluator and fix crash

Previous implementation was assigning a temporary to FilterEvaluator<T>::extractor.
This commit is contained in:
John Firebaugh
2016-05-03 17:25:08 -07:00
committed by Bruno de Oliveira Abinader
parent 23c4502236
commit a64fe5062f
6 changed files with 30 additions and 46 deletions

View File

@@ -119,7 +119,7 @@ void SymbolBucket::parseFeatures(const GeometryTileLayer& layer, const Filter& f
for (GLsizei i = 0; i < featureCount; i++) {
auto feature = layer.getFeature(i);
FilterEvaluator<GeometryTileFeatureExtractor> evaluator(*feature);
FilterEvaluator evaluator(*feature);
if (!Filter::visit(filter, evaluator))
continue;

View File

@@ -1,54 +1,53 @@
#pragma once
#include <mbgl/style/filter.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <type_traits>
namespace mbgl {
template <class Extractor>
class FilterEvaluator {
public:
FilterEvaluator(const Extractor& extractor_)
: extractor(extractor_) {}
FilterEvaluator(const GeometryTileFeature& feature_)
: feature(feature_) {}
bool operator()(const NullFilter&) const {
return true;
}
bool operator()(const EqualsFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
optional<Value> actual = getValue(filter.key);
return actual && equal(*actual, filter.value);
}
bool operator()(const NotEqualsFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
optional<Value> actual = getValue(filter.key);
return !actual || !equal(*actual, filter.value);
}
bool operator()(const LessThanFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
optional<Value> actual = getValue(filter.key);
return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ < rhs_; });
}
bool operator()(const LessThanEqualsFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
optional<Value> actual = getValue(filter.key);
return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ <= rhs_; });
}
bool operator()(const GreaterThanFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
optional<Value> actual = getValue(filter.key);
return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ > rhs_; });
}
bool operator()(const GreaterThanEqualsFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
optional<Value> actual = getValue(filter.key);
return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ >= rhs_; });
}
bool operator()(const InFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
optional<Value> actual = getValue(filter.key);
if (!actual)
return false;
for (const auto& v: filter.values) {
@@ -60,7 +59,7 @@ public:
}
bool operator()(const NotInFilter& filter) const {
optional<Value> actual = extractor.getValue(filter.key);
optional<Value> actual = getValue(filter.key);
if (!actual)
return true;
for (const auto& v: filter.values) {
@@ -99,6 +98,12 @@ public:
}
private:
optional<Value> getValue(const std::string& key) const {
return key == "$type"
? optional<Value>(uint64_t(feature.getType()))
: feature.getValue(key);
}
template <class Op>
struct Comparator {
const Op& op;
@@ -142,7 +147,7 @@ private:
return compare(lhs, rhs, [] (const auto& lhs_, const auto& rhs_) { return lhs_ == rhs_; });
}
const Extractor& extractor;
const GeometryTileFeature& feature;
};
} // namespace mbgl

View File

@@ -10,7 +10,7 @@ void StyleBucketParameters::eachFilteredFeature(const Filter& filter,
for (std::size_t i = 0; !cancelled() && i < layer.featureCount(); i++) {
auto feature = layer.getFeature(i);
FilterEvaluator<GeometryTileFeatureExtractor> evaluator(*feature);
FilterEvaluator evaluator(*feature);
if (!Filter::visit(filter, evaluator))
continue;

View File

@@ -1,13 +0,0 @@
#include <mbgl/tile/geometry_tile.hpp>
namespace mbgl {
optional<Value> GeometryTileFeatureExtractor::getValue(const std::string& key) const {
if (key == "$type") {
return Value(uint64_t(feature.getType()));
}
return feature.getValue(key);
}
} // namespace mbgl

View File

@@ -80,17 +80,6 @@ public:
virtual std::unique_ptr<AsyncRequest> monitorTile(const Callback&) = 0;
};
class GeometryTileFeatureExtractor {
public:
GeometryTileFeatureExtractor(const GeometryTileFeature& feature_)
: feature(feature_) {}
optional<Value> getValue(const std::string& key) const;
private:
const GeometryTileFeature& feature;
};
} // namespace mbgl
#endif

View File

@@ -13,26 +13,28 @@ using namespace mbgl;
typedef std::multimap<std::string, mbgl::Value> Properties;
class Extractor {
class StubFeature : public GeometryTileFeature {
public:
inline Extractor(const Properties& properties_, FeatureType type_)
inline StubFeature(const Properties& properties_, FeatureType type_)
: properties(properties_)
, type(type_)
{}
optional<Value> getValue(const std::string &key) const {
if (key == "$type")
return Value(uint64_t(type));
optional<Value> getValue(const std::string &key) const override {
auto it = properties.find(key);
if (it == properties.end())
return optional<Value>();
return it->second;
}
FeatureType getType() const {
FeatureType getType() const override {
return type;
}
GeometryCollection getGeometries() const override {
return GeometryCollection();
}
private:
const Properties properties;
FeatureType type;
@@ -45,7 +47,8 @@ Filter parse(const char * expression) {
}
bool evaluate(const Filter& filter, const Properties& properties, FeatureType type = FeatureType::Unknown) {
FilterEvaluator<Extractor> evaluator({properties, type});
StubFeature feature(properties, type);
FilterEvaluator evaluator(feature);
return Filter::visit(filter, evaluator);
}