@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
125 lines (94 loc) • 3.56 kB
JavaScript
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();