summaryrefslogtreecommitdiff
path: root/src/mbgl/style/layers/symbol_layer_impl.cpp
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-10-30 11:06:59 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-11-17 15:13:38 -0800
commit38fcbe21d48186c4630a3b8a76d1b20e156faadd (patch)
tree098f73bfea98deb5202fe1c13b1277e43e322755 /src/mbgl/style/layers/symbol_layer_impl.cpp
parentd4fc66af3924805d40576989c1e139ddafcc4670 (diff)
downloadqtlocation-mapboxgl-38fcbe21d48186c4630a3b8a76d1b20e156faadd.tar.gz
[core] Convert style properties to a tuple-based approach
This converts the style property classes (CirclePaintProperties and so on) to the same tuple-based approach as gl::Attribute and gl::Uniform. The approach is outlined in https://github.com/mapbox/cpp/blob/master/C%2B%2B%20Structural%20Metaprogramming.md. The main advantage of this approach is it allows writing algorithms that work on sets of style properties, without resorting to code generation or manually repetitive code. This lets us iterate on approaches to data-driven properties more easily. Another advantage is that the cascading, unevaluated, and evaluated states of a set of properties exist as independent structures, instead of individual properties holding their own state. This is a more functional approach that makes data flow clearer and reduces state.
Diffstat (limited to 'src/mbgl/style/layers/symbol_layer_impl.cpp')
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.cpp95
1 files changed, 45 insertions, 50 deletions
diff --git a/src/mbgl/style/layers/symbol_layer_impl.cpp b/src/mbgl/style/layers/symbol_layer_impl.cpp
index 0ac9ff832d..957bc1993e 100644
--- a/src/mbgl/style/layers/symbol_layer_impl.cpp
+++ b/src/mbgl/style/layers/symbol_layer_impl.cpp
@@ -10,20 +10,18 @@ void SymbolLayer::Impl::cascade(const CascadeParameters& parameters) {
paint.cascade(parameters);
}
-bool SymbolLayer::Impl::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = paint.recalculate(parameters);
+bool SymbolLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
+ paint.evaluate(parameters);
// text-size and icon-size are layout properties but they also need to be evaluated as paint properties:
- layout.iconSize.calculate(parameters);
- layout.textSize.calculate(parameters);
- iconSize = layout.iconSize;
- textSize = layout.textSize;
+ iconSize = layout.evaluate<IconSize>(parameters);
+ textSize = layout.evaluate<TextSize>(parameters);
- passes = ((paint.iconOpacity > 0 && (paint.iconColor.value.a > 0 || paint.iconHaloColor.value.a > 0) && iconSize > 0)
- || (paint.textOpacity > 0 && (paint.textColor.value.a > 0 || paint.textHaloColor.value.a > 0) && textSize > 0))
+ passes = ((paint.evaluated.get<IconOpacity>() > 0 && (paint.evaluated.get<IconColor>().a > 0 || paint.evaluated.get<IconHaloColor>().a > 0) && iconSize > 0)
+ || (paint.evaluated.get<TextOpacity>() > 0 && (paint.evaluated.get<TextColor>().a > 0 || paint.evaluated.get<TextHaloColor>().a > 0) && textSize > 0))
? RenderPass::Translucent : RenderPass::None;
- return hasTransitions;
+ return paint.hasTransition();
}
std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(BucketParameters&) const {
@@ -32,37 +30,34 @@ std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(BucketParameters&) const
}
std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(BucketParameters& parameters) const {
- SymbolLayoutProperties layoutProperties = layout;
+ PropertyEvaluationParameters p(parameters.tileID.overscaledZ);
+ SymbolLayoutProperties::Evaluated evaluated = layout.evaluate(p);
- CalculationParameters p(parameters.tileID.overscaledZ);
- layoutProperties.recalculate(p);
-
- if (layoutProperties.iconRotationAlignment.value == AlignmentType::Auto) {
- if (layoutProperties.symbolPlacement.value == SymbolPlacementType::Line) {
- layoutProperties.iconRotationAlignment.value = AlignmentType::Map;
+ if (evaluated.get<IconRotationAlignment>() == AlignmentType::Auto) {
+ if (evaluated.get<SymbolPlacement>() == SymbolPlacementType::Line) {
+ evaluated.get<IconRotationAlignment>() = AlignmentType::Map;
} else {
- layoutProperties.iconRotationAlignment.value = AlignmentType::Viewport;
+ evaluated.get<IconRotationAlignment>() = AlignmentType::Viewport;
}
}
- if (layoutProperties.textRotationAlignment.value == AlignmentType::Auto) {
- if (layoutProperties.symbolPlacement.value == SymbolPlacementType::Line) {
- layoutProperties.textRotationAlignment.value = AlignmentType::Map;
+ if (evaluated.get<TextRotationAlignment>() == AlignmentType::Auto) {
+ if (evaluated.get<SymbolPlacement>() == SymbolPlacementType::Line) {
+ evaluated.get<TextRotationAlignment>() = AlignmentType::Map;
} else {
- layoutProperties.textRotationAlignment.value = AlignmentType::Viewport;
+ evaluated.get<TextRotationAlignment>() = AlignmentType::Viewport;
}
}
// If unspecified `text-pitch-alignment` inherits `text-rotation-alignment`
- if (layoutProperties.textPitchAlignment.value == AlignmentType::Auto) {
- layoutProperties.textPitchAlignment.value = layoutProperties.textRotationAlignment.value;
+ if (evaluated.get<TextPitchAlignment>() == AlignmentType::Auto) {
+ evaluated.get<TextPitchAlignment>() = evaluated.get<TextRotationAlignment>();
}
- layoutProperties.textSize.calculate(CalculationParameters(18));
- float textMaxSize = layoutProperties.textSize;
+ float textMaxSize = layout.evaluate<TextSize>(PropertyEvaluationParameters(18));
- layoutProperties.iconSize.calculate(CalculationParameters(p.z + 1));
- layoutProperties.textSize.calculate(CalculationParameters(p.z + 1));
+ evaluated.get<IconSize>() = layout.evaluate<IconSize>(PropertyEvaluationParameters(p.z + 1));
+ evaluated.get<TextSize>() = layout.evaluate<TextSize>(PropertyEvaluationParameters(p.z + 1));
return std::make_unique<SymbolLayout>(id,
parameters.layer.getName(),
@@ -71,40 +66,40 @@ std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(BucketParameters&
parameters.mode,
parameters.layer,
filter,
- layoutProperties,
+ evaluated,
textMaxSize,
*spriteAtlas);
}
-SymbolPropertyValues SymbolLayer::Impl::iconPropertyValues(const SymbolLayoutProperties& layout_) const {
+SymbolPropertyValues SymbolLayer::Impl::iconPropertyValues(const SymbolLayoutProperties::Evaluated& layout_) const {
return SymbolPropertyValues {
- layout_.iconRotationAlignment.value, // icon-pitch-alignment is not yet implemented; inherit the rotation alignment
- layout_.iconRotationAlignment.value,
- layout_.iconSize.value,
- paint.iconOpacity.value,
- paint.iconColor.value,
- paint.iconHaloColor.value,
- paint.iconHaloWidth.value,
- paint.iconHaloBlur.value,
- paint.iconTranslate.value,
- paint.iconTranslateAnchor.value,
+ layout_.get<IconRotationAlignment>(), // icon-pitch-alignment is not yet implemented; inherit the rotation alignment
+ layout_.get<IconRotationAlignment>(),
+ layout_.get<IconSize>(),
+ paint.evaluated.get<IconOpacity>(),
+ paint.evaluated.get<IconColor>(),
+ paint.evaluated.get<IconHaloColor>(),
+ paint.evaluated.get<IconHaloWidth>(),
+ paint.evaluated.get<IconHaloBlur>(),
+ paint.evaluated.get<IconTranslate>(),
+ paint.evaluated.get<IconTranslateAnchor>(),
iconSize,
1.0f
};
}
-SymbolPropertyValues SymbolLayer::Impl::textPropertyValues(const SymbolLayoutProperties& layout_) const {
+SymbolPropertyValues SymbolLayer::Impl::textPropertyValues(const SymbolLayoutProperties::Evaluated& layout_) const {
return SymbolPropertyValues {
- layout_.textPitchAlignment.value,
- layout_.textRotationAlignment.value,
- layout_.textSize.value,
- paint.textOpacity.value,
- paint.textColor.value,
- paint.textHaloColor.value,
- paint.textHaloWidth.value,
- paint.textHaloBlur.value,
- paint.textTranslate.value,
- paint.textTranslateAnchor.value,
+ layout_.get<TextPitchAlignment>(),
+ layout_.get<TextRotationAlignment>(),
+ layout_.get<TextSize>(),
+ paint.evaluated.get<TextOpacity>(),
+ paint.evaluated.get<TextColor>(),
+ paint.evaluated.get<TextHaloColor>(),
+ paint.evaluated.get<TextHaloWidth>(),
+ paint.evaluated.get<TextHaloBlur>(),
+ paint.evaluated.get<TextTranslate>(),
+ paint.evaluated.get<TextTranslateAnchor>(),
textSize,
24.0f
};