<commit_before>#include "style.h"

#include "scene/scene.h"
#include "scene/sceneLayer.h"
#include "scene/light.h"
#include "tile/tile.h"
#include "gl/vboMesh.h"
#include "view/view.h"

#include "csscolorparser.hpp"

#include <sstream>

std::unordered_map<std::bitset<MAX_LAYERS>, StyleParamMap> Style::s_styleParamMapCache;
std::mutex Style::s_cacheMutex;

using namespace Tangram;

Style::Style(std::string _name, GLenum _drawMode) : m_name(_name), m_drawMode(_drawMode) {
}

Style::~Style() {
    m_layers.clear();
}

uint32_t Style::parseColorProp(const std::string& _colorPropStr) {
    uint32_t color = 0;

    if (_colorPropStr.find(',') != std::string::npos) { // try to parse as comma-separated rgba components
        std::istringstream stream(_colorPropStr);
        std::string token;
        unsigned char i = 0;
        while (std::getline(stream, token, ',') && i < 4) {
            color += (uint32_t(std::stod(token) * 255.)) << (8 * i++);
        }
    } else { // parse as css color or #hex-num
        color = CSSColorParser::parse(_colorPropStr).getInt();
    }
    return color;
}

void Style::build(const std::vector<std::unique_ptr<Light>>& _lights) {

    constructVertexLayout();
    constructShaderProgram();

    switch (m_lightingType) {
        case LightingType::vertex:
            m_shaderProgram->addSourceBlock("defines", "#define TANGRAM_LIGHTING_VERTEX\n", false);
            break;
        case LightingType::fragment:
            m_shaderProgram->addSourceBlock("defines", "#define TANGRAM_LIGHTING_FRAGMENT\n", false);
            break;
        default:
            break;
    }

    m_material->injectOnProgram(m_shaderProgram);

    for (auto& light : _lights) {
        light->injectOnProgram(m_shaderProgram);
    }

}

void Style::setMaterial(const std::shared_ptr<Material>& _material) {

    m_material = _material;

}

void Style::setLightingType(LightingType _type){

    m_lightingType = _type;

}

void Style::addLayer(std::shared_ptr<SceneLayer> _layer) {

    m_layers.push_back(std::move(_layer));

}

void Style::applyLayerFiltering(const Feature& _feature, const Context& _ctx, std::bitset<MAX_LAYERS>& _uniqueID,
                                   StyleParamMap& _styleParamMapMix, std::shared_ptr<SceneLayer> _uberLayer) const {

    std::vector<std::shared_ptr<SceneLayer>> sLayers;
    sLayers.reserve(_uberLayer->getSublayers().size() + 1);
    sLayers.push_back(_uberLayer);

    auto sLayerItr = sLayers.begin();

    //A BFS traversal of the SceneLayer graph
    while (sLayerItr != sLayers.end()) {

        auto sceneLyr = *sLayerItr;

        if (sceneLyr->getFilter().eval(_feature, _ctx)) { // filter matches

            _uniqueID.set(sceneLyr->getID());

            {
                std::lock_guard<std::mutex> lock(s_cacheMutex);

                if(s_styleParamMapCache.find(_uniqueID) != s_styleParamMapCache.end()) {

                    _styleParamMapMix = s_styleParamMapCache.at(_uniqueID);

                } else {

                    /* update StyleParam with subLayer parameters */
                    auto& layerStyleParamMap = sceneLyr->getStyleParamMap();
                    for(auto& styleParam : layerStyleParamMap) {
                        _styleParamMapMix[styleParam.first] = styleParam.second;
                    }

                    s_styleParamMapCache.emplace(_uniqueID, _styleParamMapMix);
                }
            }

            /* append sLayers with sublayers of this layer */
            auto& ssLayers = sceneLyr->getSublayers();
            sLayerItr = sLayers.insert(sLayers.end(), ssLayers.begin(), ssLayers.end());
        } else {
            sLayerItr++;
        }
    }
}

void Style::addData(TileData& _data, Tile& _tile) {

    std::shared_ptr<VboMesh> mesh(newMesh());<commit_msg>use a single cache lookup per (sub)layer<commit_after>#include "style.h"

#include "scene/scene.h"
#include "scene/sceneLayer.h"
#include "scene/light.h"
#include "tile/tile.h"
#include "gl/vboMesh.h"
#include "view/view.h"

#include "csscolorparser.hpp"

#include <sstream>

std::unordered_map<std::bitset<MAX_LAYERS>, StyleParamMap> Style::s_styleParamMapCache;
std::mutex Style::s_cacheMutex;

using namespace Tangram;

Style::Style(std::string _name, GLenum _drawMode) : m_name(_name), m_drawMode(_drawMode) {
}

Style::~Style() {
    m_layers.clear();
}

uint32_t Style::parseColorProp(const std::string& _colorPropStr) {
    uint32_t color = 0;

    if (_colorPropStr.find(',') != std::string::npos) { // try to parse as comma-separated rgba components
        std::istringstream stream(_colorPropStr);
        std::string token;
        unsigned char i = 0;
        while (std::getline(stream, token, ',') && i < 4) {
            color += (uint32_t(std::stod(token) * 255.)) << (8 * i++);
        }
    } else { // parse as css color or #hex-num
        color = CSSColorParser::parse(_colorPropStr).getInt();
    }
    return color;
}

void Style::build(const std::vector<std::unique_ptr<Light>>& _lights) {

    constructVertexLayout();
    constructShaderProgram();

    switch (m_lightingType) {
        case LightingType::vertex:
            m_shaderProgram->addSourceBlock("defines", "#define TANGRAM_LIGHTING_VERTEX\n", false);
            break;
        case LightingType::fragment:
            m_shaderProgram->addSourceBlock("defines", "#define TANGRAM_LIGHTING_FRAGMENT\n", false);
            break;
        default:
            break;
    }

    m_material->injectOnProgram(m_shaderProgram);

    for (auto& light : _lights) {
        light->injectOnProgram(m_shaderProgram);
    }

}

void Style::setMaterial(const std::shared_ptr<Material>& _material) {

    m_material = _material;

}

void Style::setLightingType(LightingType _type){

    m_lightingType = _type;

}

void Style::addLayer(std::shared_ptr<SceneLayer> _layer) {

    m_layers.push_back(std::move(_layer));

}

void Style::applyLayerFiltering(const Feature& _feature, const Context& _ctx, std::bitset<MAX_LAYERS>& _uniqueID,
                                   StyleParamMap& _styleParamMapMix, std::shared_ptr<SceneLayer> _uberLayer) const {

    std::vector<std::shared_ptr<SceneLayer>> sLayers;
    sLayers.reserve(_uberLayer->getSublayers().size() + 1);
    sLayers.push_back(_uberLayer);

    auto sLayerItr = sLayers.begin();

    // A BFS traversal of the SceneLayer graph
    while (sLayerItr != sLayers.end()) {

        auto sceneLyr = *sLayerItr;

        if (sceneLyr->getFilter().eval(_feature, _ctx)) { // filter matches

            _uniqueID.set(sceneLyr->getID());
            {
                std::lock_guard<std::mutex> lock(s_cacheMutex);

                // Get or create cache entry
                auto& entry = s_styleParamMapCache[_uniqueID];

                if (!entry.empty()) {
                    _styleParamMapMix = entry;

                } else {
                    // Update StyleParam with subLayer parameters

                    auto& layerStyleParamMap = sceneLyr->getStyleParamMap();
                    for(auto& styleParam : layerStyleParamMap) {
                        _styleParamMapMix[styleParam.first] = styleParam.second;
                    }
                    entry = _styleParamMapMix;
                }
            }

            // Append sLayers with sublayers of this layer
            auto& ssLayers = sceneLyr->getSublayers();
            sLayerItr = sLayers.insert(sLayers.end(), ssLayers.begin(), ssLayers.end());
        } else {
            sLayerItr++;
        }
    }
}

void Style::addData(TileData& _data, Tile& _tile) {

    std::shared_ptr<VboMesh> mesh(newMesh());
{'fraction_non_alphanumeric': 0.12813114754098362, 'fraction_numerical': 0.0036721311475409837, 'mean_word_length': 2.762210162802171, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6925471', 'n_tokens_mistral': 2477, 'n_tokens_neox': 2371, 'n_words': 435}