_import { Storage } from 'points';

/**
 * Class that handles the creation of new {@link Storage}s in Points.
 * @example
 * // js side
 * points.storages.myStorage = [1, 2, 3]
 *
 * // wgsl side
 * let val = myStorage; // value is vec3f(1, 2, 3)
 * @class Storages
 */
export default class Storages {
    #list = [];

    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 Storage does not exist we create it.
                const storage = new Storage({ name: prop, value: 0 });
                target.list.push(storage);
                Reflect.set(target, prop, storage, target);
                return storage;
            },

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

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

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

                // If Storage does not exist we create it.

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

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

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

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

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

MIT

Documentation generated by JSDoc 4.0.5 using Docolatte theme on