_import { Uniform } from 'points';
import UniformsArray from './UniformsArray.js';

/**
 * Class that handles the creation of new {@link Uniform}s in Points.
 * @example
 * // js side
 * points.uniforms.myUniform = 10
 *
 * // wgsl side
 * let val = params.myUniform; // value is 10.0 f32
 * @class Uniforms
 */
export default class Uniforms {
    #list = new UniformsArray();

    constructor() {
        return new Proxy(this, {
            get(target, prop, receiver) {

                const value = Reflect.get(target, prop, target);

                if (prop === 'list') {
                    return value;
                }

                if (typeof value === 'function') {
                    if (prop === 'find') {
                        return value.bind(target);
                    }
                    if (prop === 'add') {
                        return value.bind(target);
                    }
                }

                if (prop in target) {
                    return value;
                }
                // If Uniform does not exist we create it.
                const uniform = new Uniform({ name: prop });
                target.list.push(uniform);
                Reflect.set(target, prop, uniform, target);
                return uniform;
            },

            set(target, prop, value, receiver) {
                if (prop === 'list') {
                    return Reflect.set(target, prop, value, target);
                }

                const type = typeof value;
                if (type === 'string') {
                    throw `Uniform named '${prop}': No strings allowed or maybe you are adding an array.`;
                }
                if (type === 'object' && !Array.isArray(value)) {
                    throw `Uniform named '${prop}': No objects allowed.`;
                }

                if (prop in target) {
                    const uniform = Reflect.get(target, prop, target);
                    uniform.value = value;
                    return uniform;
                }

                // If Uniform does not exist we create it.

                const uniform = new Uniform({ name: prop, value });
                target.list.push(uniform);
                return Reflect.set(target, prop, uniform, target);
            }
        });
    }

    get list() {
        return this.#list;
    }

    /**
     * List of all {@link Uniform}s
     * @param {Array} value
     * @memberof Uniforms
     */
    set list(value) {
        this.#list = value;
    }

    /**
     * Retrieves a {@link Uniform} by its name.
     * @param {String} name
     * @returns {Uniform}
     * @memberof Uniforms
     */
    find(name) {
        return this[name];
    }

    /**
     * Add a new {@link Uniform}
     * @param {Uniform} uniform
     * @memberof Uniforms
     */
    add(uniform) {
        const { name } = uniform;
        if (this[name]) {
            throw `Uniform named ${name} already exists.`
        }
        this[name] = uniform;
        this.#list.push(uniform);
    }
}

MIT

Documentation generated by JSDoc 4.0.5 using Docolatte theme on