FelixMcFelix/laughing-ironman

View on GitHub
src/Palette/Manager.js

Summary

Maintainability
A
3 hrs
Test Coverage
/* global Palette */
/* global WebGLRenderingContext */
/**
* @classdesc The core part of the system - initialise this to begin using the shader manager.
* @class Palette.Manager
* @param {WebGLRenderingContext} gl - The context all shaders and programs will belong to and be compiled by.
* @author FelixMcFelix (Kyle S.)
*/
Palette.Manager = function(gl){
    /**
    * A reference to the defining WebGLRenderingContext.
    * @name Palette.Manager#context
    * @type WebGLRenderingContext
    * @protected
    * @readonly
    */
    this.context         = gl;
    
    /**
    * An object storing all processed Vertex Shaders.
    * @name Palette.Manager#vertShaders
    * @type Object
    * @protected
    */
    this.vertShaders     = {};
    /**
    * An object storing all processed Fragment Shaders.
    * @name Palette.Manager#fragShaders
    * @type Object
    * @protected
    */
    this.fragShaders    = {};
    /**
    * An object storing all processed Programs.
    * @name Palette.Manager#programs
    * @type Object
    * @protected
    */
    this.programs        = {};

    /**
    * A {@link Palette.ShaderFactory} object utilised by the manager
    * to generate valid shader objects from many sources for use.
    * @name Palette.Manager#shaderFactory
    * @type Palette.ShaderFactory
    * @protected
    * @readonly
    */
    this.shaderFactory    = new Palette.ShaderFactory(this);
};

Palette.Manager.prototype = {
    /**
    * Add a shader into the manager's storage for future access.
    * @method Palette.Manager#addShader
    * @public
    * @param {string|Palette.Shader} shaderRef - URL, JSON or Palette.Shader.
    */
    addShader: function(shaderRef){
        this.shaderFactory.addShader(shaderRef);
    },

    /**
    * Send a draw call to a given vs-fs pair.
    * The work is delegated down to the program's own draw method.
    * @method Palette.Manager#draw
    * @public
    * @param {string|Palette.Shader} vs - The desired Vertex Shader.
    * @param {string|Palette.Shader} fs - The desired Fragment Shader.
    * @param {Float32Array} verts - Vertex list to pass to the GPU.
    * @param {object} [conf1] - A set of attributes to pass down to the fragment shader.
    * @param {object} [conf2] - A set of attributes to pass down to the vertex shader.
    */
    draw: function(vs, fs, verts, conf1, conf2){
        this.getProgram(vs, fs).draw(verts, conf1, conf2);
    },

    /**
    * Request a program object from a known vs-fs pair.
    * @method Palette.Manager#getProgram
    * @public
    * @param {string|Palette.Shader} vs - The desired Vertex Shader.
    * @param {string|Palette.Shader} fs - The desired Fragment Shader.
    * @return {Palette.Program} The {@link Palette.Program} either found or generated. If either shader was not found, NULL is returned.
    */
    getProgram: function(vs, fs){
        var vsName = this.getShaderName(vs);
        var fsName = this.getShaderName(fs);
        var vsObj;
        var fsObj;

        var output;

        this.programs[vsName] = this.programs[vsName] || {};
        this.programs[vsName][fsName] = this.programs[vsName][fsName] || {};

        if(!(this.programs[vsName][fsName] instanceof Palette.Program)){
            if(vs instanceof Palette.Shader){vsObj = vs;} else{vsObj = this.getShader(Palette.Shader.VS, vsName);}
            if(fs instanceof Palette.Shader){fsObj = fs;} else{fsObj = this.getShader(Palette.Shader.FS, fsName);}
            this.programs[vsName][fsName] = new Palette.Program(this.context, vsObj, fsObj);
        }
        output = this.programs[vsName][fsName];

        return output;
    },

    /**
    * Request a shader object from storage using its type and name.
    * @method Palette.Manager#getShader
    * @public
    * @param {int} type - Either Palette.Shader.VS or Palette.Shader.FS.
    * @param {string} name - The shader's identifier.
    * @return {Palette.Shader} The requested {@link Palette.Shader}. If a shader was not found, NULL is returned.
    */
    getShader: function(type, name){
        return (type === Palette.Shader.VS) ? this.vertShaders[name] : this.fragShaders[name];
    },

    /**
    * Ensure that we have a shader's name, for lookup purposes in particular.
    * @method Palette.Manager#getShaderName
    * @public
    * @param {string|Palette.Shader} input - The shader we need to sanity check the name of.
    * @return {string} - The definite name of the shader.
    */
    getShaderName: function(input){
        var output;
        if(input instanceof Palette.Shader){
            output = input.name;
        } else{
            output = input;
        }
        return output;
    }
};

Palette.Manager.prototype.constructor = Palette.Manager;