<% const type = locals.type; const layoutProperties = locals.layoutProperties; const paintProperties = locals.paintProperties; -%> // This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. #include _layer.hpp> #include _layer_impl.hpp> #include #include #include #include #include #include #include #include namespace mbgl { namespace style { <% let layerCapabilities = {}; let defaults = { caps: { 'Source': 'NotRequired', 'Pass3D': 'NotRequired', 'Layout': 'NotRequired', 'FadingTiles': 'NotRequired' }, require: function(cap) { let copy = Object.assign({}, this); copy.caps = Object.assign({}, this.caps); copy.caps[cap] = 'Required'; return copy; }, finalize: function() { return Object.keys(this.caps).reduce((acc, key) => { acc.push(`${key}::${this.caps[key]}`); return acc; }, []); } }; layerCapabilities['background'] = defaults.finalize(); layerCapabilities['fill'] = defaults.require('Source') .require('Layout') .finalize(); layerCapabilities['fill-extrusion'] = defaults.require('Source') .require('Pass3D') .require('Layout') .finalize(); layerCapabilities['hillshade'] = defaults.require('Source') .require('Pass3D') .finalize(); layerCapabilities['symbol'] = defaults.require('Source') .require('Layout') .require('FadingTiles') .finalize(); layerCapabilities['circle'] = defaults.require('Source').finalize(); layerCapabilities['line'] = layerCapabilities['fill']; layerCapabilities['heatmap'] = layerCapabilities['hillshade']; layerCapabilities['raster'] = layerCapabilities['circle']; %> // static const LayerTypeInfo* <%- camelize(type) %>Layer::Impl::staticTypeInfo() noexcept { const static LayerTypeInfo typeInfo {"<%- type %>", <%-`${layerCapabilities[type].map(cap => `LayerTypeInfo::${cap}`).join(',\n ')}` %> }; return &typeInfo; } <% if (type === 'background') { -%> <%- camelize(type) %>Layer::<%- camelize(type) %>Layer(const std::string& layerID) : Layer(makeMutable(layerID, std::string())) { } <% } else { -%> <%- camelize(type) %>Layer::<%- camelize(type) %>Layer(const std::string& layerID, const std::string& sourceID) : Layer(makeMutable(layerID, sourceID)) { } <% } -%> <%- camelize(type) %>Layer::<%- camelize(type) %>Layer(Immutable impl_) : Layer(std::move(impl_)) { } <%- camelize(type) %>Layer::~<%- camelize(type) %>Layer() = default; const <%- camelize(type) %>Layer::Impl& <%- camelize(type) %>Layer::impl() const { return static_cast(*baseImpl); } Mutable<<%- camelize(type) %>Layer::Impl> <%- camelize(type) %>Layer::mutableImpl() const { return makeMutable(impl()); } std::unique_ptr <%- camelize(type) %>Layer::cloneRef(const std::string& id_) const { auto impl_ = mutableImpl(); impl_->id = id_; impl_->paint = <%- camelize(type) %>PaintProperties::Transitionable(); return std::make_unique<<%- camelize(type) %>Layer>(std::move(impl_)); } <% if (layoutProperties.length) { -%> void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer& writer) const { layout.stringify(writer); } <% } else { -%> void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer&) const { } <% } -%> // Layout properties <% for (const property of layoutProperties) { -%> <%- propertyValueType(property) %> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() { return <%- camelize(property.name) %>::defaultValue(); } const <%- propertyValueType(property) %>& <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const { return impl().layout.get<<%- camelize(property.name) %>>(); } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(const <%- propertyValueType(property) %>& value) { if (value == get<%- camelize(property.name) %>()) return; auto impl_ = mutableImpl(); impl_->layout.get<<%- camelize(property.name) %>>() = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } <% } -%> // Paint properties <% for (const property of paintProperties) { %> <%- propertyValueType(property) %> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() { <% if (property.name === 'heatmap-color') { -%> conversion::Error error; std::string rawValue = R"JSON(<%- JSON.stringify(property.default) %>)JSON"; return *conversion::convertJSON<<%- propertyValueType(property)%>>(rawValue, error); <% } else { -%> return { <%- defaultValue(property) %> }; <% } -%> } const <%- propertyValueType(property) %>& <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const { return impl().paint.template get<<%- camelize(property.name) %>>().value; } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(const <%- propertyValueType(property) %>& value) { if (value == get<%- camelize(property.name) %>()) return; auto impl_ = mutableImpl(); impl_->paint.template get<<%- camelize(property.name) %>>().value = value; <% if (property.name === 'line-width') { -%> impl_->paint.template get().value = value; <% } -%> baseImpl = std::move(impl_); observer->onLayerChanged(*this); } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>Transition(const TransitionOptions& options) { auto impl_ = mutableImpl(); impl_->paint.template get<<%- camelize(property.name) %>>().options = options; baseImpl = std::move(impl_); } TransitionOptions <%- camelize(type) %>Layer::get<%- camelize(property.name) %>Transition() const { return impl().paint.template get<<%- camelize(property.name) %>>().options; } <% } -%> using namespace conversion; optional <%- camelize(type) %>Layer::setPaintProperty(const std::string& name, const Convertible& value) { enum class Property : uint8_t { <% for (const property of paintProperties) { -%> <%- camelize(property.name) %>, <% } -%> <% for (const property of paintProperties) { -%> <%- camelize(property.name) %>Transition, <% } -%> }; MAPBOX_ETERNAL_CONSTEXPR const auto properties = mapbox::eternal::hash_map({ <%- paintProperties.map(p => `{ "${p.name}", static_cast(Property::${camelize(p.name)}) }`).join(',\n ') %>, <%- paintProperties.map(p => `{ "${p.name}-transition", static_cast(Property::${camelize(p.name)}Transition) }`).join(',\n ') %> }); const auto it = properties.find(name.c_str()); if (it == properties.end()) { return Error { "layer doesn't support this property" }; } auto property = static_cast(it->second); <% const paintConversions = {}; for (const property of paintProperties) { const dataDriven = property['property-type'] === 'data-driven' || property['property-type'] === 'cross-faded-data-driven'; const convertTokens = property.name === 'icon-image' || property.name === 'text-field'; const conversion = `optional<${propertyValueType(property)}> typedValue = convert<${propertyValueType(property)}>(value, error, ${dataDriven}, ${convertTokens})`; paintConversions[conversion] = paintConversions[conversion] || []; paintConversions[conversion].push(property); } -%> <% for (const key in paintConversions) { const properties = paintConversions[key]; %> if (<%- properties.map(p => `property == Property::${camelize(p.name)}`).join(' || ') %>) { Error error; <%- key %>; if (!typedValue) { return error; } <% if (properties.length == 1) { %> set<%- camelize(properties[0].name) %>(*typedValue); return nullopt; <% } else for (const property of properties) { %> if (property == Property::<%- camelize(property.name) %>) { set<%- camelize(property.name) %>(*typedValue); return nullopt; } <% } %> } <% } %> Error error; optional transition = convert(value, error); if (!transition) { return error; } <% for (const property of paintProperties) { %> if (property == Property::<%- camelize(property.name) %>Transition) { set<%- camelize(property.name) %>Transition(*transition); return nullopt; } <% } %> return Error { "layer doesn't support this property" }; } optional <%- camelize(type) %>Layer::setLayoutProperty(const std::string& name, const Convertible& value) { if (name == "visibility") { return Layer::setVisibility(value); } <% if (layoutProperties.length) { -%> enum class Property { <% for (const property of layoutProperties) { -%> <%- camelize(property.name) %>, <% } -%> }; MAPBOX_ETERNAL_CONSTEXPR const auto properties = mapbox::eternal::hash_map({ <%- layoutProperties.map(p => `{ "${p.name}", static_cast(Property::${camelize(p.name)}) }`).join(',\n ') %> }); const auto it = properties.find(name.c_str()); if (it == properties.end()) { return Error { "layer doesn't support this property" }; } auto property = static_cast(it->second); <% const layoutConversions = {}; for (const property of layoutProperties) { const dataDriven = property['property-type'] === 'data-driven' || property['property-type'] === 'cross-faded-data-driven'; const convertTokens = property.name === 'icon-image' || property.name === 'text-field'; const conversion = `optional<${propertyValueType(property)}> typedValue = convert<${propertyValueType(property)}>(value, error, ${dataDriven}, ${convertTokens})`; layoutConversions[conversion] = layoutConversions[conversion] || []; layoutConversions[conversion].push(property); } -%> <% for (const key in layoutConversions) { const properties = layoutConversions[key]; %> if (<%- properties.map(p => `property == Property::${camelize(p.name)}`).join(' || ') %>) { Error error; <%- key %>; if (!typedValue) { return error; } <% if (properties.length == 1) { %> set<%- camelize(properties[0].name) %>(*typedValue); return nullopt; <% } else for (const property of properties) { %> if (property == Property::<%- camelize(property.name) %>) { set<%- camelize(property.name) %>(*typedValue); return nullopt; } <% } %> } <% } %> <% } /* if (layoutProperties.length) */ %> return Error { "layer doesn't support this property" }; } Mutable <%- camelize(type) %>Layer::mutableBaseImpl() const { return staticMutableCast(mutableImpl()); } } // namespace style } // namespace mbgl