<commit_before>// Rendering modes

var GL = require('./gl.js');
var GLBuilders = require('./gl_builders.js');
var GLGeometry = require('./gl_geom.js').GLGeometry;
var shader_sources = require('./gl_shaders.js'); // built-in shaders

// Base

var RenderMode = {
    init: function (gl) {
        this.gl = gl;
        this.makeGLProgram();
    },
    refresh: function () {
        this.makeGLProgram();
    },
    defines: {},
    selection: false,
    buildPolygons: function(){}, // build functions are no-ops until overriden
    buildLines: function(){},
    buildPoints: function(){}
};

RenderMode.makeGLProgram = function ()
{
    // Add any custom defines to built-in mode defines
    var defines = {}; // create a new object to avoid mutating a prototype value that may be shared with other modes
    if (this.defines != null) {
        for (var d in this.defines) {
            defines[d] = this.defines[d];
        }
    }
    if (this.shaders != null && this.shaders.defines != null) {
        for (var d in this.shaders.defines) {
            defines[d] = this.shaders.defines[d];
        }
    }

    // Get any custom code transforms
    var transforms = (this.shaders && this.shaders.transforms);

    // Create shader from custom URLs
    if (this.shaders && this.shaders.vertex_url && this.shaders.fragment_url) {
        this.gl_program = GL.Program.createProgramFromURLs(
            this.gl,
            this.shaders.vertex_url,
            this.shaders.fragment_url,
            { defines: defines, transforms: transforms }
        );

        if (this.selection) {
            defines['FEATURE_SELECTION'] = true;
            this.selection_gl_program = new GL.Program(
                this.gl,
                this.gl_program.vertex_shader_source,
                shader_sources['selection_fragment'],
                { defines: defines, transforms: transforms }
            );
        }
    }
    // Create shader from built-in source
    else {
        this.gl_program = new GL.Program(
            this.gl,
            shader_sources[this.vertex_shader_key],
            shader_sources[this.fragment_shader_key],
            { defines: defines, transforms: transforms }
        );

        if (this.selection) {
            defines['FEATURE_SELECTION'] = true;
            this.selection_gl_program = new GL.Program(
                this.gl,
                shader_sources[this.vertex_shader_key],
                shader_sources['selection_fragment'],
                { defines: defines, transforms: transforms }
            );
       }
    }
};

RenderMode.setUniforms = function (options)
{
    options = options || {};

    // Clear main program by default, or selection program if specified
    var gl_program = GL.Program.current;

    // TODO: only update uniforms when changed
    if (this.shaders != null && this.shaders.uniforms != null) {
        for (var u in this.shaders.uniforms) {
            // Single float
            if (typeof this.shaders.uniforms[u] == 'number') {
                gl_program.uniform('1f', u, this.shaders.uniforms[u]);
            }
            else if (typeof this.shaders.uniforms[u] == 'object') {
                // float vectors (vec2, vec3, vec4)
                if (this.shaders.uniforms[u].length >= 2 && this.shaders.uniforms[u].length <= 4) {
                    gl_program.uniform(this.shaders.uniforms[u].length + 'fv', u, this.shaders.uniforms[u]);
                }
                // TODO: support arrays for more than 4 components
                // TODO: assume matrix for (typeof == Float32Array && length == 16)?
                // TODO: support non-float types? (int, texture sampler, etc.)
                // gl_program.uniform('1fv', u, this.shaders.uniforms[u]);
            }
        }
    }
};

RenderMode.update = function ()
{
    this.gl_program.use();

    // Mode-specific animation
    if (typeof this.animation == 'function') {
        this.animation();
    }

    this.setUniforms();
};


var Modes = {};
var ModeManager = {};

// Update built-in mode or create a new one
ModeManager.configureMode = function (name, settings)
{
    Modes[name] = Modes[name] || Object.create(Modes[settings.extends] || RenderMode);<commit_msg>add support for booleans in JS->GLSL uniform translation<commit_after>// Rendering modes

var GL = require('./gl.js');
var GLBuilders = require('./gl_builders.js');
var GLGeometry = require('./gl_geom.js').GLGeometry;
var shader_sources = require('./gl_shaders.js'); // built-in shaders

// Base

var RenderMode = {
    init: function (gl) {
        this.gl = gl;
        this.makeGLProgram();
    },
    refresh: function () {
        this.makeGLProgram();
    },
    defines: {},
    selection: false,
    buildPolygons: function(){}, // build functions are no-ops until overriden
    buildLines: function(){},
    buildPoints: function(){}
};

RenderMode.makeGLProgram = function ()
{
    // Add any custom defines to built-in mode defines
    var defines = {}; // create a new object to avoid mutating a prototype value that may be shared with other modes
    if (this.defines != null) {
        for (var d in this.defines) {
            defines[d] = this.defines[d];
        }
    }
    if (this.shaders != null && this.shaders.defines != null) {
        for (var d in this.shaders.defines) {
            defines[d] = this.shaders.defines[d];
        }
    }

    // Get any custom code transforms
    var transforms = (this.shaders && this.shaders.transforms);

    // Create shader from custom URLs
    if (this.shaders && this.shaders.vertex_url && this.shaders.fragment_url) {
        this.gl_program = GL.Program.createProgramFromURLs(
            this.gl,
            this.shaders.vertex_url,
            this.shaders.fragment_url,
            { defines: defines, transforms: transforms }
        );

        if (this.selection) {
            defines['FEATURE_SELECTION'] = true;
            this.selection_gl_program = new GL.Program(
                this.gl,
                this.gl_program.vertex_shader_source,
                shader_sources['selection_fragment'],
                { defines: defines, transforms: transforms }
            );
        }
    }
    // Create shader from built-in source
    else {
        this.gl_program = new GL.Program(
            this.gl,
            shader_sources[this.vertex_shader_key],
            shader_sources[this.fragment_shader_key],
            { defines: defines, transforms: transforms }
        );

        if (this.selection) {
            defines['FEATURE_SELECTION'] = true;
            this.selection_gl_program = new GL.Program(
                this.gl,
                shader_sources[this.vertex_shader_key],
                shader_sources['selection_fragment'],
                { defines: defines, transforms: transforms }
            );
       }
    }
};

RenderMode.setUniforms = function (options)
{
    options = options || {};

    // Clear main program by default, or selection program if specified
    var gl_program = GL.Program.current;

    // TODO: only update uniforms when changed
    if (this.shaders != null && this.shaders.uniforms != null) {
        for (var u in this.shaders.uniforms) {
            // Single float
            if (typeof this.shaders.uniforms[u] == 'number') {
                gl_program.uniform('1f', u, this.shaders.uniforms[u]);
            }
            else if (typeof this.shaders.uniforms[u] == 'object') {
                // float vectors (vec2, vec3, vec4)
                if (this.shaders.uniforms[u].length >= 2 && this.shaders.uniforms[u].length <= 4) {
                    gl_program.uniform(this.shaders.uniforms[u].length + 'fv', u, this.shaders.uniforms[u]);
                }
                // TODO: support arrays for more than 4 components
                // TODO: assume matrix for (typeof == Float32Array && length == 16)?
                // TODO: support non-float types? (int, texture sampler, etc.)
                // gl_program.uniform('1fv', u, this.shaders.uniforms[u]);
            }
            // Boolean
            else if (typeof this.shaders.uniforms[u] == 'boolean') {
                gl_program.uniform('1i', u, this.shaders.uniforms[u]);
            }
        }
    }
};

RenderMode.update = function ()
{
    this.gl_program.use();

    // Mode-specific animation
    if (typeof this.animation == 'function') {
        this.animation();
    }

    this.setUniforms();
};


var Modes = {};
var ModeManager = {};

// Update built-in mode or create a new one
ModeManager.configureMode = function (name, settings)
{
    Modes[name] = Modes[name] || Object.create(Modes[settings.extends] || RenderMode);
{'fraction_non_alphanumeric': 0.12482694970004615, 'fraction_numerical': 0.002884171665897554, 'mean_word_length': 2.042822042822043, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '873601', 'n_tokens_mistral': 2547, 'n_tokens_neox': 2471, 'n_words': 587}