From 588b1d0dcc206e82143028bdfb8f6f4a68e7d487 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 16 Nov 2017 13:07:15 -0800 Subject: [PATCH] Use prototypal inheritance to avoid work Introduces a `Properties` class which holds objects containing default values for the layout or paint property set of a given layer type. These objects are immutable, and they are used as the prototypes for the `_values` members of `Transitionable`, `Transitioning`, `Layout`, and `PossiblyEvaluated`. This allows these classes to avoid doing work in the common case where a property has no explicit value set and should be considered to take on the default value: using `for (const property of Object.keys(this._values))`, they can iterate over only the _own_ properties of `_values`, skipping repeated calculation of transitions and possible/final evaluations for defaults, the result of which will always be the same. --- src/render/draw_background.js | 12 +- src/render/draw_symbol.js | 2 +- src/style/light.js | 13 +- src/style/properties.js | 160 ++++++++++++------ src/style/style_layer.js | 5 +- .../style_layer/background_style_layer.js | 8 +- .../background_style_layer_properties.js | 7 +- src/style/style_layer/circle_style_layer.js | 8 +- .../circle_style_layer_properties.js | 7 +- .../style_layer/fill_extrusion_style_layer.js | 8 +- .../fill_extrusion_style_layer_properties.js | 7 +- src/style/style_layer/fill_style_layer.js | 8 +- .../fill_style_layer_properties.js | 7 +- src/style/style_layer/heatmap_style_layer.js | 8 +- .../heatmap_style_layer_properties.js | 7 +- src/style/style_layer/layer_properties.js.ejs | 13 +- src/style/style_layer/line_style_layer.js | 14 +- .../line_style_layer_properties.js | 13 +- src/style/style_layer/raster_style_layer.js | 8 +- .../raster_style_layer_properties.js | 7 +- src/style/style_layer/symbol_style_layer.js | 12 +- .../symbol_style_layer_properties.js | 13 +- src/symbol/projection.js | 3 +- src/symbol/symbol_placement.js | 3 +- 24 files changed, 208 insertions(+), 145 deletions(-) diff --git a/src/render/draw_background.js b/src/render/draw_background.js index a5056fb7af9..fbd06f4f076 100644 --- a/src/render/draw_background.js +++ b/src/render/draw_background.js @@ -30,12 +30,12 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg painter.setDepthSublayer(0); - const properties = new PossiblyEvaluated({ - 'background-color': new PossiblyEvaluatedPropertyValue( - fillLayerPaintProperties['fill-color'], {kind: 'constant', value: color}, globals), - 'background-opacity': new PossiblyEvaluatedPropertyValue( - fillLayerPaintProperties['fill-opacity'], {kind: 'constant', value: opacity}, globals) - }); + const properties = new PossiblyEvaluated(fillLayerPaintProperties); + + (properties._values: any)['background-color'] = new PossiblyEvaluatedPropertyValue( + fillLayerPaintProperties.properties['fill-color'], {kind: 'constant', value: color}, globals); + (properties._values: any)['background-opacity'] = new PossiblyEvaluatedPropertyValue( + fillLayerPaintProperties.properties['fill-opacity'], {kind: 'constant', value: opacity}, globals); let program; if (image) { diff --git a/src/render/draw_symbol.js b/src/render/draw_symbol.js index 4c2d355272a..a43d3e40a60 100644 --- a/src/render/draw_symbol.js +++ b/src/render/draw_symbol.js @@ -152,7 +152,7 @@ function setSymbolDrawState(program, painter, layer, isText, rotateInShader, pit gl.uniform1f(program.uniforms.u_camera_to_center_distance, tr.cameraToCenterDistance); - const size = symbolSize.evaluateSizeForZoom(sizeData, tr.zoom, symbolLayoutProperties[isText ? 'text-size' : 'icon-size']); + const size = symbolSize.evaluateSizeForZoom(sizeData, tr.zoom, symbolLayoutProperties.properties[isText ? 'text-size' : 'icon-size']); if (size.uSizeT !== undefined) gl.uniform1f(program.uniforms.u_size_t, size.uSizeT); if (size.uSize !== undefined) gl.uniform1f(program.uniforms.u_size, size.uSize); diff --git a/src/style/light.js b/src/style/light.js index b14f343fd1b..a6634bf6dfe 100644 --- a/src/style/light.js +++ b/src/style/light.js @@ -11,6 +11,7 @@ const Color = require('../style-spec/util/color'); const interpolate = require('../style-spec/util/interpolate'); const { + Properties, Transitionable, Transitioning, PossiblyEvaluated, @@ -45,19 +46,19 @@ class LightPositionProperty implements Property<[number, number, number], LightP } } -type Properties = {| +type Props = {| "anchor": DataConstantProperty<"map" | "viewport">, "position": LightPositionProperty, "color": DataConstantProperty, "intensity": DataConstantProperty, |}; -const properties: Properties = { +const properties: Properties = new Properties({ "anchor": new DataConstantProperty(styleSpec.light.anchor), "position": new LightPositionProperty(), "color": new DataConstantProperty(styleSpec.light.color), "intensity": new DataConstantProperty(styleSpec.light.intensity), -}; +}); const TRANSITION_SUFFIX = '-transition'; @@ -65,9 +66,9 @@ const TRANSITION_SUFFIX = '-transition'; * Represents the light used to light extruded features. */ class Light extends Evented { - _transitionable: Transitionable; - _transitioning: Transitioning; - properties: PossiblyEvaluated; + _transitionable: Transitionable; + _transitioning: Transitioning; + properties: PossiblyEvaluated; constructor(lightOptions?: LightSpecification) { super(); diff --git a/src/style/properties.js b/src/style/properties.js index 4caa6b4eac5..77cc93ce0da 100644 --- a/src/style/properties.js +++ b/src/style/properties.js @@ -152,8 +152,8 @@ class TransitionablePropertyValue { * * @private */ -type TransitionablePropertyValues - = $Exact<$ObjMap(p: Property) => TransitionablePropertyValue>> +type TransitionablePropertyValues + = $Exact<$ObjMap(p: Property) => TransitionablePropertyValue>> /** * `Transitionable` stores a map of all (property name, `TransitionablePropertyValue`) pairs for paint properties of a @@ -162,14 +162,13 @@ type TransitionablePropertyValues * * @private */ -class Transitionable { - _values: TransitionablePropertyValues; +class Transitionable { + _properties: Properties; + _values: TransitionablePropertyValues; - constructor(properties: Properties) { - const values = this._values = ({}: any); - for (const property in properties) { - values[property] = new TransitionablePropertyValue(properties[property]); - } + constructor(properties: Properties) { + this._properties = properties; + this._values = (Object.create(properties.defaultTransitionablePropertyValues): any); } getValue(name: S): PropertyValueSpecification | void { @@ -177,6 +176,11 @@ class Transitionable { } setValue(name: S, value: PropertyValueSpecification | void) { + if (!this._values.hasOwnProperty(name)) { + this._values[name] = new TransitionablePropertyValue(this._values[name].property); + } + // Note that we do not _remove_ an own property in the case where `value` a value is being reset + // to the default: the transition might still be non-default. this._values[name].value = new PropertyValue(this._values[name].property, value === null ? undefined : value); } @@ -185,12 +189,15 @@ class Transitionable { } setTransition(name: S, value: TransitionSpecification | void) { + if (!this._values.hasOwnProperty(name)) { + this._values[name] = new TransitionablePropertyValue(this._values[name].property); + } this._values[name].transition = value || undefined; } serialize() { const result: any = {}; - for (const property in this._values) { + for (const property of Object.keys(this._values)) { const value = this.getValue(property); if (value !== undefined) { result[property] = value; @@ -204,20 +211,20 @@ class Transitionable { return result; } - transitioned(parameters: TransitionParameters, prior: Transitioning): Transitioning { - const result: any = {}; - for (const property in this._values) { - result[property] = this._values[property].transitioned(parameters, prior._values[property]); + transitioned(parameters: TransitionParameters, prior: Transitioning): Transitioning { + const result = new Transitioning(this._properties); // eslint-disable-line no-use-before-define + for (const property of Object.keys(this._values)) { + result._values[property] = this._values[property].transitioned(parameters, prior._values[property]); } - return new Transitioning(result); // eslint-disable-line no-use-before-define + return result; } - untransitioned(): Transitioning { - const result: any = {}; - for (const property in this._values) { - result[property] = this._values[property].untransitioned(); + untransitioned(): Transitioning { + const result = new Transitioning(this._properties); // eslint-disable-line no-use-before-define + for (const property of Object.keys(this._values)) { + result._values[property] = this._values[property].untransitioned(); } - return new Transitioning(result); // eslint-disable-line no-use-before-define + return result; } } @@ -287,8 +294,8 @@ class TransitioningPropertyValue { * * @private */ -type TransitioningPropertyValues - = $Exact<$ObjMap(p: Property) => TransitioningPropertyValue>> +type TransitioningPropertyValues + = $Exact<$ObjMap(p: Property) => TransitioningPropertyValue>> /** * `Transitioning` stores a map of all (property name, `TransitioningPropertyValue`) pairs for paint properties of a @@ -297,23 +304,25 @@ type TransitioningPropertyValues * * @private */ -class Transitioning { - _values: TransitioningPropertyValues; +class Transitioning { + _properties: Properties; + _values: TransitioningPropertyValues; - constructor(values: TransitioningPropertyValues) { - this._values = values; + constructor(properties: Properties) { + this._properties = properties; + this._values = (Object.create(properties.defaultTransitioningPropertyValues): any); } - possiblyEvaluate(parameters: EvaluationParameters): PossiblyEvaluated { - const result: any = {}; - for (const property in this._values) { - result[property] = this._values[property].possiblyEvaluate(parameters); + possiblyEvaluate(parameters: EvaluationParameters): PossiblyEvaluated { + const result = new PossiblyEvaluated(this._properties); // eslint-disable-line no-use-before-define + for (const property of Object.keys(this._values)) { + result._values[property] = this._values[property].possiblyEvaluate(parameters); } - return new PossiblyEvaluated(result); // eslint-disable-line no-use-before-define + return result; } hasTransition() { - for (const property in this._values) { + for (const property of Object.keys(this._values)) { if (this._values[property].prior) { return true; } @@ -330,8 +339,8 @@ class Transitioning { * * @private */ -type LayoutPropertyValues - = $Exact<$ObjMap(p: Property) => PropertyValue>> +type PropertyValues + = $Exact<$ObjMap(p: Property) => PropertyValue>> /** * Because layout properties are not transitionable, they have a simpler representation and evaluation chain than @@ -344,14 +353,13 @@ type LayoutPropertyValues * * @private */ -class Layout { - _values: LayoutPropertyValues; +class Layout { + _properties: Properties; + _values: PropertyValues; - constructor(properties: Properties) { - const values = this._values = ({}: any); - for (const property in properties) { - values[property] = new PropertyValue(properties[property], undefined); - } + constructor(properties: Properties) { + this._properties = properties; + this._values = (Object.create(properties.defaultPropertyValues): any); } getValue(name: S) { @@ -364,7 +372,7 @@ class Layout { serialize() { const result: any = {}; - for (const property in this._values) { + for (const property of Object.keys(this._values)) { const value = this.getValue(property); if (value !== undefined) { result[property] = value; @@ -373,12 +381,12 @@ class Layout { return result; } - possiblyEvaluate(parameters: EvaluationParameters): PossiblyEvaluated { - const result: any = {}; - for (const property in this._values) { - result[property] = this._values[property].possiblyEvaluate(parameters); + possiblyEvaluate(parameters: EvaluationParameters): PossiblyEvaluated { + const result = new PossiblyEvaluated(this._properties); // eslint-disable-line no-use-before-define + for (const property of Object.keys(this._values)) { + result._values[property] = this._values[property].possiblyEvaluate(parameters); } - return new PossiblyEvaluated(result); // eslint-disable-line no-use-before-define + return result; } } @@ -463,21 +471,23 @@ class PossiblyEvaluatedPropertyValue { * * @private */ -type PossiblyEvaluatedPropertyValues - = $Exact<$ObjMap(p: Property) => R>> +type PossiblyEvaluatedPropertyValues + = $Exact<$ObjMap(p: Property) => R>> /** * `PossiblyEvaluated` stores a map of all (property name, `R`) pairs for paint or layout properties of a * given layer type. */ -class PossiblyEvaluated { - _values: PossiblyEvaluatedPropertyValues; +class PossiblyEvaluated { + _properties: Properties; + _values: PossiblyEvaluatedPropertyValues; - constructor(values: PossiblyEvaluatedPropertyValues) { - this._values = values; + constructor(properties: Properties) { + this._properties = properties; + this._values = (Object.create(properties.defaultPossiblyEvaluatedValues): any); } - get(name: S): $ElementType, S> { + get(name: S): $ElementType, S> { return this._values[name]; } } @@ -631,6 +641,45 @@ class HeatmapColorProperty implements Property { interpolate() {} } +/** + * `Properties` holds objects containing default values for the layout or paint property set of a given + * layer type. These objects are immutable, and they are used as the prototypes for the `_values` members of + * `Transitionable`, `Transitioning`, `Layout`, and `PossiblyEvaluated`. This allows these classes to avoid + * doing work in the common case where a property has no explicit value set and should be considered to take + * on the default value: using `for (const property of Object.keys(this._values))`, they can iterate over + * only the _own_ properties of `_values`, skipping repeated calculation of transitions and possible/final + * evaluations for defaults, the result of which will always be the same. + * + * @private + */ +class Properties { + properties: Props; + defaultPropertyValues: PropertyValues; + defaultTransitionablePropertyValues: TransitionablePropertyValues; + defaultTransitioningPropertyValues: TransitioningPropertyValues; + defaultPossiblyEvaluatedValues: PossiblyEvaluatedPropertyValues; + + constructor(properties: Props) { + this.properties = properties; + this.defaultPropertyValues = ({}: any); + this.defaultTransitionablePropertyValues = ({}: any); + this.defaultTransitioningPropertyValues = ({}: any); + this.defaultPossiblyEvaluatedValues = ({}: any); + + for (const property in properties) { + const prop = properties[property]; + const defaultPropertyValue = this.defaultPropertyValues[property] = + new PropertyValue(prop, undefined); + const defaultTransitionablePropertyValue = this.defaultTransitionablePropertyValues[property] = + new TransitionablePropertyValue(prop); + this.defaultTransitioningPropertyValues[property] = + defaultTransitionablePropertyValue.untransitioned(); + this.defaultPossiblyEvaluatedValues[property] = + defaultPropertyValue.possiblyEvaluate(({}: any)); + } + } +} + module.exports = { PropertyValue, Transitionable, @@ -641,5 +690,6 @@ module.exports = { DataConstantProperty, DataDrivenProperty, CrossFadedProperty, - HeatmapColorProperty + HeatmapColorProperty, + Properties }; diff --git a/src/style/style_layer.js b/src/style/style_layer.js index dcccda7f51a..47332cfc5e2 100644 --- a/src/style/style_layer.js +++ b/src/style/style_layer.js @@ -9,7 +9,8 @@ const Evented = require('../util/evented'); const { Layout, Transitionable, - Transitioning + Transitioning, + Properties } = require('./properties'); import type {Bucket, BucketParameters} from '../data/bucket'; @@ -52,7 +53,7 @@ class StyleLayer extends Evented { bearing: number, pixelsToTileUnits: number) => boolean; - constructor(layer: LayerSpecification, properties: {layout?: any, paint: any}) { + constructor(layer: LayerSpecification, properties: {layout?: Properties<*>, paint: Properties<*>}) { super(); this.id = layer.id; diff --git a/src/style/style_layer/background_style_layer.js b/src/style/style_layer/background_style_layer.js index 69c7b160ffa..4d48cc533f5 100644 --- a/src/style/style_layer/background_style_layer.js +++ b/src/style/style_layer/background_style_layer.js @@ -9,12 +9,12 @@ const { PossiblyEvaluated } = require('../properties'); -import type {PaintProperties} from './background_style_layer_properties'; +import type {PaintProps} from './background_style_layer_properties'; class BackgroundStyleLayer extends StyleLayer { - _transitionablePaint: Transitionable; - _transitioningPaint: Transitioning; - paint: PossiblyEvaluated; + _transitionablePaint: Transitionable; + _transitioningPaint: Transitioning; + paint: PossiblyEvaluated; constructor(layer: LayerSpecification) { super(layer, properties); diff --git a/src/style/style_layer/background_style_layer_properties.js b/src/style/style_layer/background_style_layer_properties.js index cf44ec9213a..d86d3d2d897 100644 --- a/src/style/style_layer/background_style_layer_properties.js +++ b/src/style/style_layer/background_style_layer_properties.js @@ -5,6 +5,7 @@ const styleSpec = require('../../style-spec/reference/latest'); const { + Properties, DataConstantProperty, DataDrivenProperty, CrossFadedProperty, @@ -14,16 +15,16 @@ const { import type Color from '../../style-spec/util/color'; -export type PaintProperties = {| +export type PaintProps = {| "background-color": DataConstantProperty, "background-pattern": CrossFadedProperty, "background-opacity": DataConstantProperty, |}; -const paint: PaintProperties = { +const paint: Properties = new Properties({ "background-color": new DataConstantProperty(styleSpec["paint_background"]["background-color"]), "background-pattern": new CrossFadedProperty(styleSpec["paint_background"]["background-pattern"]), "background-opacity": new DataConstantProperty(styleSpec["paint_background"]["background-opacity"]), -}; +}); module.exports = { paint }; diff --git a/src/style/style_layer/circle_style_layer.js b/src/style/style_layer/circle_style_layer.js index 595efc7da42..fc9cf6e58b9 100644 --- a/src/style/style_layer/circle_style_layer.js +++ b/src/style/style_layer/circle_style_layer.js @@ -14,12 +14,12 @@ const { import type {Bucket, BucketParameters} from '../../data/bucket'; import type Point from '@mapbox/point-geometry'; -import type {PaintProperties} from './circle_style_layer_properties'; +import type {PaintProps} from './circle_style_layer_properties'; class CircleStyleLayer extends StyleLayer { - _transitionablePaint: Transitionable; - _transitioningPaint: Transitioning; - paint: PossiblyEvaluated; + _transitionablePaint: Transitionable; + _transitioningPaint: Transitioning; + paint: PossiblyEvaluated; constructor(layer: LayerSpecification) { super(layer, properties); diff --git a/src/style/style_layer/circle_style_layer_properties.js b/src/style/style_layer/circle_style_layer_properties.js index 624f37491ce..17788b25910 100644 --- a/src/style/style_layer/circle_style_layer_properties.js +++ b/src/style/style_layer/circle_style_layer_properties.js @@ -5,6 +5,7 @@ const styleSpec = require('../../style-spec/reference/latest'); const { + Properties, DataConstantProperty, DataDrivenProperty, CrossFadedProperty, @@ -14,7 +15,7 @@ const { import type Color from '../../style-spec/util/color'; -export type PaintProperties = {| +export type PaintProps = {| "circle-radius": DataDrivenProperty, "circle-color": DataDrivenProperty, "circle-blur": DataDrivenProperty, @@ -28,7 +29,7 @@ export type PaintProperties = {| "circle-stroke-opacity": DataDrivenProperty, |}; -const paint: PaintProperties = { +const paint: Properties = new Properties({ "circle-radius": new DataDrivenProperty(styleSpec["paint_circle"]["circle-radius"]), "circle-color": new DataDrivenProperty(styleSpec["paint_circle"]["circle-color"]), "circle-blur": new DataDrivenProperty(styleSpec["paint_circle"]["circle-blur"]), @@ -40,6 +41,6 @@ const paint: PaintProperties = { "circle-stroke-width": new DataDrivenProperty(styleSpec["paint_circle"]["circle-stroke-width"]), "circle-stroke-color": new DataDrivenProperty(styleSpec["paint_circle"]["circle-stroke-color"]), "circle-stroke-opacity": new DataDrivenProperty(styleSpec["paint_circle"]["circle-stroke-opacity"]), -}; +}); module.exports = { paint }; diff --git a/src/style/style_layer/fill_extrusion_style_layer.js b/src/style/style_layer/fill_extrusion_style_layer.js index 7d8ce5964c4..60051be2a35 100644 --- a/src/style/style_layer/fill_extrusion_style_layer.js +++ b/src/style/style_layer/fill_extrusion_style_layer.js @@ -14,12 +14,12 @@ const { import type {BucketParameters} from '../../data/bucket'; import type Point from '@mapbox/point-geometry'; -import type {PaintProperties} from './fill_extrusion_style_layer_properties'; +import type {PaintProps} from './fill_extrusion_style_layer_properties'; class FillExtrusionStyleLayer extends StyleLayer { - _transitionablePaint: Transitionable; - _transitioningPaint: Transitioning; - paint: PossiblyEvaluated; + _transitionablePaint: Transitionable; + _transitioningPaint: Transitioning; + paint: PossiblyEvaluated; constructor(layer: LayerSpecification) { super(layer, properties); diff --git a/src/style/style_layer/fill_extrusion_style_layer_properties.js b/src/style/style_layer/fill_extrusion_style_layer_properties.js index 5aee8262513..785f2e9a6cd 100644 --- a/src/style/style_layer/fill_extrusion_style_layer_properties.js +++ b/src/style/style_layer/fill_extrusion_style_layer_properties.js @@ -5,6 +5,7 @@ const styleSpec = require('../../style-spec/reference/latest'); const { + Properties, DataConstantProperty, DataDrivenProperty, CrossFadedProperty, @@ -14,7 +15,7 @@ const { import type Color from '../../style-spec/util/color'; -export type PaintProperties = {| +export type PaintProps = {| "fill-extrusion-opacity": DataConstantProperty, "fill-extrusion-color": DataDrivenProperty, "fill-extrusion-translate": DataConstantProperty<[number, number]>, @@ -24,7 +25,7 @@ export type PaintProperties = {| "fill-extrusion-base": DataDrivenProperty, |}; -const paint: PaintProperties = { +const paint: Properties = new Properties({ "fill-extrusion-opacity": new DataConstantProperty(styleSpec["paint_fill-extrusion"]["fill-extrusion-opacity"]), "fill-extrusion-color": new DataDrivenProperty(styleSpec["paint_fill-extrusion"]["fill-extrusion-color"]), "fill-extrusion-translate": new DataConstantProperty(styleSpec["paint_fill-extrusion"]["fill-extrusion-translate"]), @@ -32,6 +33,6 @@ const paint: PaintProperties = { "fill-extrusion-pattern": new CrossFadedProperty(styleSpec["paint_fill-extrusion"]["fill-extrusion-pattern"]), "fill-extrusion-height": new DataDrivenProperty(styleSpec["paint_fill-extrusion"]["fill-extrusion-height"]), "fill-extrusion-base": new DataDrivenProperty(styleSpec["paint_fill-extrusion"]["fill-extrusion-base"]), -}; +}); module.exports = { paint }; diff --git a/src/style/style_layer/fill_style_layer.js b/src/style/style_layer/fill_style_layer.js index 31d47b55ae6..1cbad640f2f 100644 --- a/src/style/style_layer/fill_style_layer.js +++ b/src/style/style_layer/fill_style_layer.js @@ -14,13 +14,13 @@ const { import type {BucketParameters} from '../../data/bucket'; import type Point from '@mapbox/point-geometry'; -import type {PaintProperties} from './fill_style_layer_properties'; +import type {PaintProps} from './fill_style_layer_properties'; import type {EvaluationParameters} from '../properties'; class FillStyleLayer extends StyleLayer { - _transitionablePaint: Transitionable; - _transitioningPaint: Transitioning; - paint: PossiblyEvaluated; + _transitionablePaint: Transitionable; + _transitioningPaint: Transitioning; + paint: PossiblyEvaluated; constructor(layer: LayerSpecification) { super(layer, properties); diff --git a/src/style/style_layer/fill_style_layer_properties.js b/src/style/style_layer/fill_style_layer_properties.js index cad84a0117f..cc428ca8502 100644 --- a/src/style/style_layer/fill_style_layer_properties.js +++ b/src/style/style_layer/fill_style_layer_properties.js @@ -5,6 +5,7 @@ const styleSpec = require('../../style-spec/reference/latest'); const { + Properties, DataConstantProperty, DataDrivenProperty, CrossFadedProperty, @@ -14,7 +15,7 @@ const { import type Color from '../../style-spec/util/color'; -export type PaintProperties = {| +export type PaintProps = {| "fill-antialias": DataConstantProperty, "fill-opacity": DataDrivenProperty, "fill-color": DataDrivenProperty, @@ -24,7 +25,7 @@ export type PaintProperties = {| "fill-pattern": CrossFadedProperty, |}; -const paint: PaintProperties = { +const paint: Properties = new Properties({ "fill-antialias": new DataConstantProperty(styleSpec["paint_fill"]["fill-antialias"]), "fill-opacity": new DataDrivenProperty(styleSpec["paint_fill"]["fill-opacity"]), "fill-color": new DataDrivenProperty(styleSpec["paint_fill"]["fill-color"]), @@ -32,6 +33,6 @@ const paint: PaintProperties = { "fill-translate": new DataConstantProperty(styleSpec["paint_fill"]["fill-translate"]), "fill-translate-anchor": new DataConstantProperty(styleSpec["paint_fill"]["fill-translate-anchor"]), "fill-pattern": new CrossFadedProperty(styleSpec["paint_fill"]["fill-pattern"]), -}; +}); module.exports = { paint }; diff --git a/src/style/style_layer/heatmap_style_layer.js b/src/style/style_layer/heatmap_style_layer.js index 77a27bcd13b..2ea0fd5b83f 100644 --- a/src/style/style_layer/heatmap_style_layer.js +++ b/src/style/style_layer/heatmap_style_layer.js @@ -12,7 +12,7 @@ const { } = require('../properties'); import type Texture from '../../render/texture'; -import type {PaintProperties} from './heatmap_style_layer_properties'; +import type {PaintProps} from './heatmap_style_layer_properties'; class HeatmapStyleLayer extends StyleLayer { @@ -21,9 +21,9 @@ class HeatmapStyleLayer extends StyleLayer { colorRamp: RGBAImage; colorRampTexture: ?Texture; - _transitionablePaint: Transitionable; - _transitioningPaint: Transitioning; - paint: PossiblyEvaluated; + _transitionablePaint: Transitionable; + _transitioningPaint: Transitioning; + paint: PossiblyEvaluated; createBucket(options: any) { return new HeatmapBucket(options); diff --git a/src/style/style_layer/heatmap_style_layer_properties.js b/src/style/style_layer/heatmap_style_layer_properties.js index 044339d1d1d..d6eea888d39 100644 --- a/src/style/style_layer/heatmap_style_layer_properties.js +++ b/src/style/style_layer/heatmap_style_layer_properties.js @@ -5,6 +5,7 @@ const styleSpec = require('../../style-spec/reference/latest'); const { + Properties, DataConstantProperty, DataDrivenProperty, CrossFadedProperty, @@ -14,7 +15,7 @@ const { import type Color from '../../style-spec/util/color'; -export type PaintProperties = {| +export type PaintProps = {| "heatmap-radius": DataConstantProperty, "heatmap-weight": DataDrivenProperty, "heatmap-intensity": DataConstantProperty, @@ -22,12 +23,12 @@ export type PaintProperties = {| "heatmap-opacity": DataConstantProperty, |}; -const paint: PaintProperties = { +const paint: Properties = new Properties({ "heatmap-radius": new DataConstantProperty(styleSpec["paint_heatmap"]["heatmap-radius"]), "heatmap-weight": new DataDrivenProperty(styleSpec["paint_heatmap"]["heatmap-weight"]), "heatmap-intensity": new DataConstantProperty(styleSpec["paint_heatmap"]["heatmap-intensity"]), "heatmap-color": new HeatmapColorProperty(styleSpec["paint_heatmap"]["heatmap-color"]), "heatmap-opacity": new DataConstantProperty(styleSpec["paint_heatmap"]["heatmap-opacity"]), -}; +}); module.exports = { paint }; diff --git a/src/style/style_layer/layer_properties.js.ejs b/src/style/style_layer/layer_properties.js.ejs index e702bc2e691..5cd90983daf 100644 --- a/src/style/style_layer/layer_properties.js.ejs +++ b/src/style/style_layer/layer_properties.js.ejs @@ -10,6 +10,7 @@ const styleSpec = require('../../style-spec/reference/latest'); const { + Properties, DataConstantProperty, DataDrivenProperty, CrossFadedProperty, @@ -19,29 +20,29 @@ const { import type Color from '../../style-spec/util/color'; <% if (layoutProperties.length) { -%> -export type LayoutProperties = {| +export type LayoutProps = {| <% for (const property of layoutProperties) { -%> "<%= property.name %>": <%- propertyType(property) %>, <% } -%> |}; -const layout: LayoutProperties = { +const layout: Properties = new Properties({ <% for (const property of layoutProperties) { -%> "<%= property.name %>": <%- propertyValue(property, 'layout') %>, <% } -%> -}; +}); <% } -%> -export type PaintProperties = {| +export type PaintProps = {| <% for (const property of paintProperties) { -%> "<%= property.name %>": <%- propertyType(property) %>, <% } -%> |}; -const paint: PaintProperties = { +const paint: Properties = new Properties({ <% for (const property of paintProperties) { -%> "<%= property.name %>": <%- propertyValue(property, 'paint') %>, <% } -%> -}; +}); module.exports = { paint<% if (layoutProperties.length) { %>, layout<% } %> }; diff --git a/src/style/style_layer/line_style_layer.js b/src/style/style_layer/line_style_layer.js index 87b74a6b5d2..08d7982bacd 100644 --- a/src/style/style_layer/line_style_layer.js +++ b/src/style/style_layer/line_style_layer.js @@ -17,18 +17,18 @@ const { } = require('../properties'); import type {Bucket, BucketParameters} from '../../data/bucket'; -import type {LayoutProperties, PaintProperties} from './line_style_layer_properties'; +import type {LayoutProps, PaintProps} from './line_style_layer_properties'; import type {EvaluationParameters} from '../properties'; -const lineFloorwidthProperty = new DataDrivenProperty(properties.paint['line-width'].specification, true); +const lineFloorwidthProperty = new DataDrivenProperty(properties.paint.properties['line-width'].specification, true); class LineStyleLayer extends StyleLayer { - _unevaluatedLayout: Layout; - layout: PossiblyEvaluated; + _unevaluatedLayout: Layout; + layout: PossiblyEvaluated; - _transitionablePaint: Transitionable; - _transitioningPaint: Transitioning; - paint: PossiblyEvaluated; + _transitionablePaint: Transitionable; + _transitioningPaint: Transitioning; + paint: PossiblyEvaluated; constructor(layer: LayerSpecification) { super(layer, properties); diff --git a/src/style/style_layer/line_style_layer_properties.js b/src/style/style_layer/line_style_layer_properties.js index e7e005ccc7d..48b9a747793 100644 --- a/src/style/style_layer/line_style_layer_properties.js +++ b/src/style/style_layer/line_style_layer_properties.js @@ -5,6 +5,7 @@ const styleSpec = require('../../style-spec/reference/latest'); const { + Properties, DataConstantProperty, DataDrivenProperty, CrossFadedProperty, @@ -13,21 +14,21 @@ const { import type Color from '../../style-spec/util/color'; -export type LayoutProperties = {| +export type LayoutProps = {| "line-cap": DataConstantProperty<"butt" | "round" | "square">, "line-join": DataDrivenProperty<"bevel" | "round" | "miter">, "line-miter-limit": DataConstantProperty, "line-round-limit": DataConstantProperty, |}; -const layout: LayoutProperties = { +const layout: Properties = new Properties({ "line-cap": new DataConstantProperty(styleSpec["layout_line"]["line-cap"]), "line-join": new DataDrivenProperty(styleSpec["layout_line"]["line-join"]), "line-miter-limit": new DataConstantProperty(styleSpec["layout_line"]["line-miter-limit"]), "line-round-limit": new DataConstantProperty(styleSpec["layout_line"]["line-round-limit"]), -}; +}); -export type PaintProperties = {| +export type PaintProps = {| "line-opacity": DataDrivenProperty, "line-color": DataDrivenProperty, "line-translate": DataConstantProperty<[number, number]>, @@ -40,7 +41,7 @@ export type PaintProperties = {| "line-pattern": CrossFadedProperty, |}; -const paint: PaintProperties = { +const paint: Properties = new Properties({ "line-opacity": new DataDrivenProperty(styleSpec["paint_line"]["line-opacity"]), "line-color": new DataDrivenProperty(styleSpec["paint_line"]["line-color"]), "line-translate": new DataConstantProperty(styleSpec["paint_line"]["line-translate"]), @@ -51,6 +52,6 @@ const paint: PaintProperties = { "line-blur": new DataDrivenProperty(styleSpec["paint_line"]["line-blur"]), "line-dasharray": new CrossFadedProperty(styleSpec["paint_line"]["line-dasharray"]), "line-pattern": new CrossFadedProperty(styleSpec["paint_line"]["line-pattern"]), -}; +}); module.exports = { paint, layout }; diff --git a/src/style/style_layer/raster_style_layer.js b/src/style/style_layer/raster_style_layer.js index 37e1e13d9f9..68968d8b8cf 100644 --- a/src/style/style_layer/raster_style_layer.js +++ b/src/style/style_layer/raster_style_layer.js @@ -9,12 +9,12 @@ const { PossiblyEvaluated } = require('../properties'); -import type {PaintProperties} from './raster_style_layer_properties'; +import type {PaintProps} from './raster_style_layer_properties'; class RasterStyleLayer extends StyleLayer { - _transitionablePaint: Transitionable; - _transitioningPaint: Transitioning; - paint: PossiblyEvaluated; + _transitionablePaint: Transitionable; + _transitioningPaint: Transitioning; + paint: PossiblyEvaluated; constructor(layer: LayerSpecification) { super(layer, properties); diff --git a/src/style/style_layer/raster_style_layer_properties.js b/src/style/style_layer/raster_style_layer_properties.js index ef65654d8be..cf66430a380 100644 --- a/src/style/style_layer/raster_style_layer_properties.js +++ b/src/style/style_layer/raster_style_layer_properties.js @@ -5,6 +5,7 @@ const styleSpec = require('../../style-spec/reference/latest'); const { + Properties, DataConstantProperty, DataDrivenProperty, CrossFadedProperty, @@ -14,7 +15,7 @@ const { import type Color from '../../style-spec/util/color'; -export type PaintProperties = {| +export type PaintProps = {| "raster-opacity": DataConstantProperty, "raster-hue-rotate": DataConstantProperty, "raster-brightness-min": DataConstantProperty, @@ -24,7 +25,7 @@ export type PaintProperties = {| "raster-fade-duration": DataConstantProperty, |}; -const paint: PaintProperties = { +const paint: Properties = new Properties({ "raster-opacity": new DataConstantProperty(styleSpec["paint_raster"]["raster-opacity"]), "raster-hue-rotate": new DataConstantProperty(styleSpec["paint_raster"]["raster-hue-rotate"]), "raster-brightness-min": new DataConstantProperty(styleSpec["paint_raster"]["raster-brightness-min"]), @@ -32,6 +33,6 @@ const paint: PaintProperties = { "raster-saturation": new DataConstantProperty(styleSpec["paint_raster"]["raster-saturation"]), "raster-contrast": new DataConstantProperty(styleSpec["paint_raster"]["raster-contrast"]), "raster-fade-duration": new DataConstantProperty(styleSpec["paint_raster"]["raster-fade-duration"]), -}; +}); module.exports = { paint }; diff --git a/src/style/style_layer/symbol_style_layer.js b/src/style/style_layer/symbol_style_layer.js index 27411f83932..64dcfa17e59 100644 --- a/src/style/style_layer/symbol_style_layer.js +++ b/src/style/style_layer/symbol_style_layer.js @@ -15,17 +15,17 @@ const { } = require('../properties'); import type {BucketParameters} from '../../data/bucket'; -import type {LayoutProperties, PaintProperties} from './symbol_style_layer_properties'; +import type {LayoutProps, PaintProps} from './symbol_style_layer_properties'; import type {Feature} from '../../style-spec/expression'; import type {EvaluationParameters} from '../properties'; class SymbolStyleLayer extends StyleLayer { - _unevaluatedLayout: Layout; - layout: PossiblyEvaluated; + _unevaluatedLayout: Layout; + layout: PossiblyEvaluated; - _transitionablePaint: Transitionable; - _transitioningPaint: Transitioning; - paint: PossiblyEvaluated; + _transitionablePaint: Transitionable; + _transitioningPaint: Transitioning; + paint: PossiblyEvaluated; constructor(layer: LayerSpecification) { super(layer, properties); diff --git a/src/style/style_layer/symbol_style_layer_properties.js b/src/style/style_layer/symbol_style_layer_properties.js index df460116cd6..26445d387be 100644 --- a/src/style/style_layer/symbol_style_layer_properties.js +++ b/src/style/style_layer/symbol_style_layer_properties.js @@ -5,6 +5,7 @@ const styleSpec = require('../../style-spec/reference/latest'); const { + Properties, DataConstantProperty, DataDrivenProperty, CrossFadedProperty, @@ -13,7 +14,7 @@ const { import type Color from '../../style-spec/util/color'; -export type LayoutProperties = {| +export type LayoutProps = {| "symbol-placement": DataConstantProperty<"point" | "line">, "symbol-spacing": DataConstantProperty, "symbol-avoid-edges": DataConstantProperty, @@ -52,7 +53,7 @@ export type LayoutProperties = {| "text-optional": DataConstantProperty, |}; -const layout: LayoutProperties = { +const layout: Properties = new Properties({ "symbol-placement": new DataConstantProperty(styleSpec["layout_symbol"]["symbol-placement"]), "symbol-spacing": new DataConstantProperty(styleSpec["layout_symbol"]["symbol-spacing"]), "symbol-avoid-edges": new DataConstantProperty(styleSpec["layout_symbol"]["symbol-avoid-edges"]), @@ -89,9 +90,9 @@ const layout: LayoutProperties = { "text-allow-overlap": new DataConstantProperty(styleSpec["layout_symbol"]["text-allow-overlap"]), "text-ignore-placement": new DataConstantProperty(styleSpec["layout_symbol"]["text-ignore-placement"]), "text-optional": new DataConstantProperty(styleSpec["layout_symbol"]["text-optional"]), -}; +}); -export type PaintProperties = {| +export type PaintProps = {| "icon-opacity": DataDrivenProperty, "icon-color": DataDrivenProperty, "icon-halo-color": DataDrivenProperty, @@ -108,7 +109,7 @@ export type PaintProperties = {| "text-translate-anchor": DataConstantProperty<"map" | "viewport">, |}; -const paint: PaintProperties = { +const paint: Properties = new Properties({ "icon-opacity": new DataDrivenProperty(styleSpec["paint_symbol"]["icon-opacity"]), "icon-color": new DataDrivenProperty(styleSpec["paint_symbol"]["icon-color"]), "icon-halo-color": new DataDrivenProperty(styleSpec["paint_symbol"]["icon-halo-color"]), @@ -123,6 +124,6 @@ const paint: PaintProperties = { "text-halo-blur": new DataDrivenProperty(styleSpec["paint_symbol"]["text-halo-blur"]), "text-translate": new DataConstantProperty(styleSpec["paint_symbol"]["text-translate"]), "text-translate-anchor": new DataConstantProperty(styleSpec["paint_symbol"]["text-translate-anchor"]), -}; +}); module.exports = { paint, layout }; diff --git a/src/symbol/projection.js b/src/symbol/projection.js index 592ae04c251..705df389324 100644 --- a/src/symbol/projection.js +++ b/src/symbol/projection.js @@ -147,7 +147,8 @@ function updateLineLabels(bucket: SymbolBucket, keepUpright: boolean) { const sizeData = isText ? bucket.textSizeData : bucket.iconSizeData; - const partiallyEvaluatedSize = symbolSize.evaluateSizeForZoom(sizeData, painter.transform.zoom, symbolLayoutProperties[isText ? 'text-size' : 'icon-size']); + const partiallyEvaluatedSize = symbolSize.evaluateSizeForZoom(sizeData, painter.transform.zoom, + symbolLayoutProperties.properties[isText ? 'text-size' : 'icon-size']); const clippingBuffer = [256 / painter.width * 2 + 1, 256 / painter.height * 2 + 1]; diff --git a/src/symbol/symbol_placement.js b/src/symbol/symbol_placement.js index a1bad5c8ad1..629a0aad542 100644 --- a/src/symbol/symbol_placement.js +++ b/src/symbol/symbol_placement.js @@ -153,7 +153,8 @@ function performSymbolPlacement(bucket: SymbolBucket, collisionIndex: CollisionI } } - const partiallyEvaluatedTextSize = symbolSize.evaluateSizeForZoom(bucket.textSizeData, collisionIndex.transform.zoom, symbolLayoutProperties['text-size']); + const partiallyEvaluatedTextSize = symbolSize.evaluateSizeForZoom(bucket.textSizeData, collisionIndex.transform.zoom, + symbolLayoutProperties.properties['text-size']); const pitchWithMap = layout.get('text-pitch-alignment') === 'map'; for (const symbolInstance of bucket.symbolInstances) {