'use strict';

var Extensions = require('../../../../extensions/Extensions.js');
var generateUniformsSync = require('./utils/generateUniformsSync.js');

"use strict";
class GlUniformGroupSystem {
  /** @param renderer - The renderer this System works for. */
  constructor(renderer) {
    /** Cache to holds the generated functions. Stored against UniformObjects unique signature. */
    this._cache = {};
    this._uniformGroupSyncHash = {};
    this._renderer = renderer;
    this.gl = null;
    this._cache = {};
  }
  contextChange(gl) {
    this.gl = gl;
  }
  /**
   * Uploads the uniforms values to the currently bound shader.
   * @param group - the uniforms values that be applied to the current shader
   * @param program
   * @param syncData
   * @param syncData.textureCount
   */
  updateUniformGroup(group, program, syncData) {
    const programData = this._renderer.shader._getProgramData(program);
    if (!group.isStatic || group._dirtyId !== programData.uniformDirtyGroups[group.uid]) {
      programData.uniformDirtyGroups[group.uid] = group._dirtyId;
      const syncFunc = this._getUniformSyncFunction(group, program);
      syncFunc(programData.uniformData, group.uniforms, this._renderer, syncData);
    }
  }
  /**
   * Overridable by the pixi.js/unsafe-eval package to use static syncUniforms instead.
   * @param group
   * @param program
   */
  _getUniformSyncFunction(group, program) {
    return this._uniformGroupSyncHash[group._signature]?.[program._key] || this._createUniformSyncFunction(group, program);
  }
  _createUniformSyncFunction(group, program) {
    const uniformGroupSyncHash = this._uniformGroupSyncHash[group._signature] || (this._uniformGroupSyncHash[group._signature] = {});
    const id = this._getSignature(group, program._uniformData, "u");
    if (!this._cache[id]) {
      this._cache[id] = this._generateUniformsSync(group, program._uniformData);
    }
    uniformGroupSyncHash[program._key] = this._cache[id];
    return uniformGroupSyncHash[program._key];
  }
  _generateUniformsSync(group, uniformData) {
    return generateUniformsSync.generateUniformsSync(group, uniformData);
  }
  /**
   * Takes a uniform group and data and generates a unique signature for them.
   * @param group - The uniform group to get signature of
   * @param group.uniforms
   * @param uniformData - Uniform information generated by the shader
   * @param preFix
   * @returns Unique signature of the uniform group
   */
  _getSignature(group, uniformData, preFix) {
    const uniforms = group.uniforms;
    const strings = [`${preFix}-`];
    for (const i in uniforms) {
      strings.push(i);
      if (uniformData[i]) {
        strings.push(uniformData[i].type);
      }
    }
    return strings.join("-");
  }
  /** Destroys this System and removes all its textures. */
  destroy() {
    this._renderer = null;
    this._cache = null;
  }
}
/** @ignore */
GlUniformGroupSystem.extension = {
  type: [
    Extensions.ExtensionType.WebGLSystem
  ],
  name: "uniformGroup"
};

exports.GlUniformGroupSystem = GlUniformGroupSystem;
//# sourceMappingURL=GlUniformGroupSystem.js.map
