UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

125 lines (94 loc) 3.56 kB
import { Cache } from "../../../../core/cache/Cache.js"; import { TextureAttachment } from "./TextureAttachment.js"; import { TextureAttachmentsByMaterialType } from "./TextureAttachmensByMaterialType.js"; import { computeTextureHash } from "./computeTextureHash.js"; import { computeTextureEquality } from "./computeTextureEquality.js"; import { computeMaterialHash } from "./computeMaterialHash.js"; import { computeMaterialEquality } from "./computeMaterialEquality.js"; export class StaticMaterialCache { constructor() { /** * * @type {Cache<Material, Material>} */ this.materialCache = new Cache({ maxWeight: 1000, keyHashFunction: computeMaterialHash, keyEqualityFunction: computeMaterialEquality }); /** * * @type {Cache<Texture, Texture>} */ this.textureCache = new Cache({ maxWeight: 1000, keyHashFunction: computeTextureHash, keyEqualityFunction: computeTextureEquality }); } /** * * @param {Material} material * @returns {Material} */ acquire(material) { const existingMaterial = this.materialCache.get(material); if (existingMaterial !== null) { //console.log("Re-used Material:", existingMaterial); return existingMaterial; } const textureCache = this.textureCache; //patch textures const materialType = material.type; /** * * @type {TextureAttachment[]} */ const attachments = TextureAttachmentsByMaterialType[materialType]; if (attachments !== undefined) { const attachment_count = attachments.length; for (let i = 0; i < attachment_count; i++) { const attachment = attachments[i]; const texture = attachment.read(material); if (texture === null || texture === undefined) { continue; } //check cache const existingTexture = textureCache.get(texture); if (existingTexture !== null) { //console.log('Re-using texture', existingTexture); attachment.write(material, existingTexture); } else { //texture was not in cache, cache it textureCache.put(texture, texture); } } } //doesn't exist, add this.materialCache.put(material, material); // console.log("Unique Material:", material); return material; } /** * * @param {function(string)} error_consumer * @param {*} [thisArg] * @returns {boolean} */ validate(error_consumer, thisArg) { const materials_valid = this.materialCache.validate((message, key, value) => { error_consumer.call(thisArg, `Material error: ${message}. Material ${key}`); }); const textures_valid = this.textureCache.validate((message, key, value) => { error_consumer.call(thisArg, `Texture error: ${message}. Texture ${key}`); }); return materials_valid && textures_valid; } } /** * Global singleton * @readonly * @type {StaticMaterialCache} */ StaticMaterialCache.Global = new StaticMaterialCache();