[core] Simplify FilterEvaluator and fix crash
Previous implementation was assigning a temporary to FilterEvaluator<T>::extractor.
This commit is contained in:
committed by
Bruno de Oliveira Abinader
parent
23c4502236
commit
a64fe5062f
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user