minerender 2.1.0-alpha.7 → 2.1.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bundle.js CHANGED
@@ -38,14 +38,6 @@ var MineRender = (() => {
38
38
  mod
39
39
  ));
40
40
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
41
- var __decorateClass = (decorators, target, key, kind) => {
42
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
43
- for (var i4 = decorators.length - 1, decorator; i4 >= 0; i4--)
44
- if (decorator = decorators[i4])
45
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
46
- if (kind && result) __defProp(target, key, result);
47
- return result;
48
- };
49
41
 
50
42
  // ../../node_modules/esbuild-plugin-polyfill-node/polyfills/__dirname.js
51
43
  var init_dirname = __esm({
@@ -47262,11 +47254,14 @@ return ${compiler2.callType("value", tagType)}
47262
47254
  static open(name2) {
47263
47255
  return Env.provider.openCache(name2, _PersistentCache.VERSION);
47264
47256
  }
47257
+ /** Loads a missing entry and stores only non-nullish results. */
47265
47258
  async getOrLoad(key, loader) {
47266
47259
  let v5 = await this.get(key);
47267
47260
  if (typeof v5 === "undefined" || v5 === null) {
47268
47261
  v5 = await loader(key);
47269
- await this.put(key, v5);
47262
+ if (typeof v5 !== "undefined" && v5 !== null) {
47263
+ await this.put(key, v5);
47264
+ }
47270
47265
  }
47271
47266
  return v5;
47272
47267
  }
@@ -68077,7 +68072,10 @@ return ${compiler2.callType("value", tagType)}
68077
68072
  init_process2();
68078
68073
 
68079
68074
  // src/cache/Caching.ts
68080
- var Caching = class {
68075
+ var _Caching = class _Caching {
68076
+ static createAssetCache() {
68077
+ return Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68078
+ }
68081
68079
  /** Every cache above, so clear()/end() can never fall out of sync with the field list again. */
68082
68080
  static get all() {
68083
68081
  return [
@@ -68094,7 +68092,10 @@ return ${compiler2.callType("value", tagType)}
68094
68092
  this.rawModelCache,
68095
68093
  this.mergedModelCache,
68096
68094
  this.modelTextureAtlasCache,
68097
- this.blockStateCache
68095
+ this.blockStateCache,
68096
+ this.listAssetCache,
68097
+ this.defaultBlockStatesCache,
68098
+ this.entityModelsCache
68098
68099
  ];
68099
68100
  }
68100
68101
  static clear() {
@@ -68120,20 +68121,24 @@ return ${compiler2.callType("value", tagType)}
68120
68121
  };
68121
68122
  }
68122
68123
  };
68123
- Caching.rawImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(5)).buildAsync();
68124
- Caching.imageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
68125
- Caching.canvasImageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
68126
- Caching.wrappedImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
68127
- Caching.boxGeometryCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(20)).build();
68128
- Caching.textureCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
68129
- Caching.materialCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
68130
- Caching.boxMeshCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
68131
- Caching.textureAssetCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68132
- Caching.textureMetaCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68133
- Caching.rawModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68134
- Caching.mergedModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68135
- Caching.modelTextureAtlasCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68136
- Caching.blockStateCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68124
+ _Caching.rawImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(5)).buildAsync();
68125
+ _Caching.imageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
68126
+ _Caching.canvasImageDataCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
68127
+ _Caching.wrappedImageCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(10)).buildAsync();
68128
+ _Caching.boxGeometryCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(20)).build();
68129
+ _Caching.textureCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
68130
+ _Caching.materialCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
68131
+ _Caching.boxMeshCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).build();
68132
+ _Caching.textureAssetCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68133
+ _Caching.textureMetaCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68134
+ _Caching.rawModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68135
+ _Caching.mergedModelCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68136
+ _Caching.modelTextureAtlasCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68137
+ _Caching.blockStateCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
68138
+ _Caching.listAssetCache = _Caching.createAssetCache();
68139
+ _Caching.defaultBlockStatesCache = _Caching.createAssetCache();
68140
+ _Caching.entityModelsCache = _Caching.createAssetCache();
68141
+ var Caching = _Caching;
68137
68142
 
68138
68143
  // src/Geometries.ts
68139
68144
  var Geometries = class _Geometries {
@@ -68483,29 +68488,41 @@ return ${compiler2.callType("value", tagType)}
68483
68488
  static async loadAsync(src) {
68484
68489
  return new Promise((resolve, reject) => {
68485
68490
  const image = this._createImage();
68486
- image.src = src;
68487
68491
  image.onload = () => resolve(image);
68488
- image.onerror = (err) => reject(err);
68492
+ image.onerror = (err) => reject(err instanceof Error ? err : new Error("Failed to decode image"));
68493
+ image.src = src;
68489
68494
  });
68490
68495
  }
68491
68496
  static loadElement(src, onload, onerr) {
68492
68497
  const image = this._createImage();
68493
- image.src = src;
68494
68498
  if (onload)
68495
68499
  image.onload = onload;
68496
68500
  if (onerr)
68497
68501
  image.onerror = onerr;
68502
+ image.src = src;
68498
68503
  return image;
68499
68504
  }
68500
68505
  static async loadData(src) {
68501
68506
  console.debug(p2, "loadData", src);
68502
- return await this.infoToData(await this.getInfo(src));
68507
+ const image = await this.loadCanvasData(src);
68508
+ return image.data.getImageData(0, 0, image.width, image.height);
68503
68509
  }
68504
68510
  static async loadCanvasData(src) {
68505
- return await this.infoToCanvasData(await this.getInfo(src));
68511
+ const keyStr = serializeImageKey({ src });
68512
+ const info = this.getInfo(src);
68513
+ const cached = Caching.rawImageCache.getIfPresent(keyStr);
68514
+ try {
68515
+ return await this.infoToCanvasData(await info);
68516
+ } catch (err) {
68517
+ if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {
68518
+ Caching.rawImageCache.invalidate(keyStr);
68519
+ }
68520
+ throw err;
68521
+ }
68506
68522
  }
68507
68523
  static async infoToCanvasData(info) {
68508
- const image = await _ImageLoader.loadAsync(info.src);
68524
+ const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
68525
+ const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
68509
68526
  const canvas = createCanvas(info.width, info.height);
68510
68527
  const context = canvas.getContext("2d");
68511
68528
  context.drawImage(image, 0, 0);
@@ -68516,11 +68533,8 @@ return ${compiler2.callType("value", tagType)}
68516
68533
  };
68517
68534
  }
68518
68535
  static async infoToData(info) {
68519
- const image = await _ImageLoader.loadAsync(info.src);
68520
- const canvas = createCanvas(info.width, info.height);
68521
- const context = canvas.getContext("2d");
68522
- context.drawImage(image, 0, 0);
68523
- return context.getImageData(0, 0, canvas.width, canvas.height);
68536
+ const image = await this.infoToCanvasData(info);
68537
+ return image.data.getImageData(0, 0, image.width, image.height);
68524
68538
  }
68525
68539
  static async getData(src) {
68526
68540
  const keyStr = serializeImageKey({ src });
@@ -68535,13 +68549,16 @@ return ${compiler2.callType("value", tagType)}
68535
68549
  });
68536
68550
  }
68537
68551
  static async processResponse(response) {
68538
- const src = response.config.url;
68552
+ const src = response.config?.url;
68539
68553
  const data = Buffer.from(response.data);
68540
68554
  const { width, height, type } = Env.provider.imageSize(data);
68555
+ if (!width || !height) {
68556
+ throw new Error("Invalid or unsupported image dimensions");
68557
+ }
68541
68558
  return {
68542
68559
  src,
68543
- width: width || 0,
68544
- height: height || 0,
68560
+ width,
68561
+ height,
68545
68562
  type,
68546
68563
  data
68547
68564
  };
@@ -68558,15 +68575,7 @@ return ${compiler2.callType("value", tagType)}
68558
68575
  return Requests.genericRequest({
68559
68576
  url: src,
68560
68577
  responseType: "arraybuffer"
68561
- }).then(this.processResponse).catch((err) => {
68562
- return {
68563
- src,
68564
- width: 0,
68565
- height: 0,
68566
- type: void 0,
68567
- data: Buffer.from([0])
68568
- };
68569
- });
68578
+ }).then(this.processResponse);
68570
68579
  }
68571
68580
  static async getInfo(src) {
68572
68581
  const keyStr = serializeImageKey({ src });
@@ -68588,16 +68597,22 @@ return ${compiler2.callType("value", tagType)}
68588
68597
 
68589
68598
  // src/texture/TextureLoader.ts
68590
68599
  var TextureLoader = class {
68600
+ /** Reports whether image loading failed, so cached textures can be retried. */
68601
+ static hasFailed(texture) {
68602
+ return this.failedTextures.has(texture);
68603
+ }
68591
68604
  static createTexture() {
68592
68605
  return new Texture();
68593
68606
  }
68594
68607
  static loadInBackground(src, format2 = RGBAFormat, rotation = 0) {
68595
68608
  const texture = this.createTexture();
68596
68609
  texture.colorSpace = SRGBColorSpace;
68597
- const image = ImageLoader.loadElement(src);
68598
- image.onload = function() {
68610
+ const image = ImageLoader.loadElement(src, () => {
68599
68611
  texture.needsUpdate = true;
68600
- };
68612
+ }, (error) => {
68613
+ this.failedTextures.add(texture);
68614
+ console.warn("Failed to load texture", src, error);
68615
+ });
68601
68616
  texture.image = image;
68602
68617
  texture.format = format2;
68603
68618
  texture.rotation = rotation;
@@ -68607,14 +68622,18 @@ return ${compiler2.callType("value", tagType)}
68607
68622
  const texture = new Texture();
68608
68623
  texture.colorSpace = SRGBColorSpace;
68609
68624
  ImageLoader.getData(src).then((image) => {
68610
- texture.needsUpdate = true;
68611
68625
  texture.image = image;
68626
+ texture.needsUpdate = true;
68627
+ }).catch((error) => {
68628
+ this.failedTextures.add(texture);
68629
+ console.warn("Failed to load texture", src, error);
68612
68630
  });
68613
68631
  texture.format = format2;
68614
68632
  texture.rotation = rotation;
68615
68633
  return Textures.initTextureProps(texture);
68616
68634
  }
68617
68635
  };
68636
+ TextureLoader.failedTextures = /* @__PURE__ */ new WeakSet();
68618
68637
 
68619
68638
  // src/texture/Textures.ts
68620
68639
  var Textures = class _Textures {
@@ -68637,6 +68656,10 @@ return ${compiler2.callType("value", tagType)}
68637
68656
  }
68638
68657
  static getImage(key) {
68639
68658
  const keyStr = serializeTextureKey(key);
68659
+ const cached = Caching.textureCache.peek(keyStr);
68660
+ if (cached && TextureLoader.hasFailed(cached)) {
68661
+ Caching.textureCache.invalidate(keyStr);
68662
+ }
68640
68663
  return Caching.textureCache.get(keyStr, (k4) => {
68641
68664
  return _Textures.createImage(key);
68642
68665
  });
@@ -68781,6 +68804,10 @@ return ${compiler2.callType("value", tagType)}
68781
68804
  }
68782
68805
  static getImage(key) {
68783
68806
  const keyStr = serializeMaterialKey(key);
68807
+ const map = Caching.materialCache.peek(keyStr)?.map;
68808
+ if (map && TextureLoader.hasFailed(map)) {
68809
+ Caching.materialCache.invalidate(keyStr);
68810
+ }
68784
68811
  return Caching.materialCache.get(keyStr, (k4) => {
68785
68812
  return _Materials.createImage(key);
68786
68813
  });
@@ -68974,95 +69001,6 @@ return ${compiler2.callType("value", tagType)}
68974
69001
  }
68975
69002
  };
68976
69003
 
68977
- // ../../node_modules/typescript-memoize/dist/es2015/memoize-decorator.js
68978
- init_dirname();
68979
- init_buffer2();
68980
- init_process2();
68981
- function Memoize(args) {
68982
- let hashFunction;
68983
- let duration;
68984
- let tags;
68985
- if (typeof args === "object") {
68986
- hashFunction = args.hashFunction;
68987
- duration = args.expiring;
68988
- tags = args.tags;
68989
- } else {
68990
- hashFunction = args;
68991
- }
68992
- return (target, propertyKey, descriptor) => {
68993
- if (descriptor.value != null) {
68994
- descriptor.value = getNewFunction(descriptor.value, hashFunction, duration, tags);
68995
- } else if (descriptor.get != null) {
68996
- descriptor.get = getNewFunction(descriptor.get, hashFunction, duration, tags);
68997
- } else {
68998
- throw "Only put a Memoize() decorator on a method or get accessor.";
68999
- }
69000
- };
69001
- }
69002
- var clearCacheTagsMap = /* @__PURE__ */ new Map();
69003
- function getNewFunction(originalMethod, hashFunction, duration = 0, tags) {
69004
- const propMapName = Symbol(`__memoized_map__`);
69005
- return function(...args) {
69006
- let returnedValue;
69007
- if (!this.hasOwnProperty(propMapName)) {
69008
- Object.defineProperty(this, propMapName, {
69009
- configurable: false,
69010
- enumerable: false,
69011
- writable: false,
69012
- value: /* @__PURE__ */ new Map()
69013
- });
69014
- }
69015
- let myMap = this[propMapName];
69016
- if (Array.isArray(tags)) {
69017
- for (const tag of tags) {
69018
- if (clearCacheTagsMap.has(tag)) {
69019
- clearCacheTagsMap.get(tag).push(myMap);
69020
- } else {
69021
- clearCacheTagsMap.set(tag, [myMap]);
69022
- }
69023
- }
69024
- }
69025
- if (hashFunction || args.length > 0 || duration > 0) {
69026
- let hashKey;
69027
- if (hashFunction === true) {
69028
- hashKey = args.map((a4) => a4.toString()).join("!");
69029
- } else if (hashFunction) {
69030
- hashKey = hashFunction.apply(this, args);
69031
- } else {
69032
- hashKey = args[0];
69033
- }
69034
- const timestampKey = `${hashKey}__timestamp`;
69035
- let isExpired = false;
69036
- if (duration > 0) {
69037
- if (!myMap.has(timestampKey)) {
69038
- isExpired = true;
69039
- } else {
69040
- let timestamp = myMap.get(timestampKey);
69041
- isExpired = Date.now() - timestamp > duration;
69042
- }
69043
- }
69044
- if (myMap.has(hashKey) && !isExpired) {
69045
- returnedValue = myMap.get(hashKey);
69046
- } else {
69047
- returnedValue = originalMethod.apply(this, args);
69048
- myMap.set(hashKey, returnedValue);
69049
- if (duration > 0) {
69050
- myMap.set(timestampKey, Date.now());
69051
- }
69052
- }
69053
- } else {
69054
- const hashKey = this;
69055
- if (myMap.has(hashKey)) {
69056
- returnedValue = myMap.get(hashKey);
69057
- } else {
69058
- returnedValue = originalMethod.apply(this, args);
69059
- myMap.set(hashKey, returnedValue);
69060
- }
69061
- }
69062
- return returnedValue;
69063
- };
69064
- }
69065
-
69066
69004
  // src/assets/source/parser/AssetParsers.ts
69067
69005
  init_dirname();
69068
69006
  init_buffer2();
@@ -69079,14 +69017,14 @@ return ${compiler2.callType("value", tagType)}
69079
69017
  })(AssetParser || {});
69080
69018
 
69081
69019
  // src/assets/Models.ts
69082
- var _Models = class _Models {
69020
+ var Models = class _Models {
69083
69021
  // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
69084
69022
  // the library, and would require an EnvProvider before any entry has had a chance to register
69085
69023
  static get PERSISTENT_CACHE() {
69086
69024
  return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-models"));
69087
69025
  }
69088
69026
  static async getItemList() {
69089
- return AssetLoader.get(new AssetKey(
69027
+ const key = new AssetKey(
69090
69028
  DEFAULT_NAMESPACE,
69091
69029
  "_list",
69092
69030
  "models",
@@ -69094,7 +69032,10 @@ return ${compiler2.callType("value", tagType)}
69094
69032
  "assets",
69095
69033
  ".json",
69096
69034
  DEFAULT_ROOT
69097
- ), "list" /* LIST */).then((r5) => r5?.files ?? []);
69035
+ );
69036
+ return Caching.listAssetCache.get(key.serialize(), () => {
69037
+ return AssetLoader.get(key, "list" /* LIST */);
69038
+ }).then((r5) => r5?.files ?? []);
69098
69039
  }
69099
69040
  static async loadAndMerge(key) {
69100
69041
  const model = await this.getRaw(key);
@@ -69141,10 +69082,6 @@ return ${compiler2.callType("value", tagType)}
69141
69082
  return this.PERSISTENT_CACHE.clear();
69142
69083
  }
69143
69084
  };
69144
- __decorateClass([
69145
- Memoize()
69146
- ], _Models, "getItemList", 1);
69147
- var Models = _Models;
69148
69085
 
69149
69086
  // src/assets/BlockStates.ts
69150
69087
  init_dirname();
@@ -69154,8 +69091,9 @@ return ${compiler2.callType("value", tagType)}
69154
69091
  static get PERSISTENT_CACHE() {
69155
69092
  return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-blockstates"));
69156
69093
  }
69094
+ // BlockState names are hardcoded
69157
69095
  static async getList() {
69158
- return AssetLoader.get(new AssetKey(
69096
+ const key = new AssetKey(
69159
69097
  DEFAULT_NAMESPACE,
69160
69098
  "_list",
69161
69099
  "blockstates",
@@ -69163,11 +69101,16 @@ return ${compiler2.callType("value", tagType)}
69163
69101
  "assets",
69164
69102
  ".json",
69165
69103
  DEFAULT_ROOT
69166
- ), "list" /* LIST */).then((r5) => r5?.files ?? []);
69104
+ );
69105
+ return Caching.listAssetCache.get(key.serialize(), () => {
69106
+ return AssetLoader.get(key, "list" /* LIST */);
69107
+ }).then((r5) => r5?.files ?? []);
69167
69108
  }
69168
69109
  static async getDefaultStates() {
69169
69110
  const key = AssetKey.parse("blockstates", "minerender:defaultBlockStates");
69170
- return AssetLoader.get(key, "json" /* JSON */);
69111
+ return Caching.defaultBlockStatesCache.get(key.serialize(), () => {
69112
+ return AssetLoader.get(key, "json" /* JSON */);
69113
+ });
69171
69114
  }
69172
69115
  static async getDefaultState(key) {
69173
69116
  const defaultStates = await this.getDefaultStates();
@@ -69206,12 +69149,6 @@ return ${compiler2.callType("value", tagType)}
69206
69149
  await this.PERSISTENT_CACHE.clear();
69207
69150
  }
69208
69151
  };
69209
- __decorateClass([
69210
- Memoize()
69211
- ], BlockStates, "getList", 1);
69212
- __decorateClass([
69213
- Memoize()
69214
- ], BlockStates, "getDefaultStates", 1);
69215
69152
  var DefaultBlockStates = class {
69216
69153
  };
69217
69154
 
@@ -79068,11 +79005,21 @@ return ${compiler2.callType("value", tagType)}
79068
79005
  return this._persistentMetaCache ?? (this._persistentMetaCache = PersistentCache.open("minerender-texturemeta"));
79069
79006
  }
79070
79007
  static async get(key) {
79071
- const asset = await this.preload(key);
79072
- if (asset) {
79073
- return ImageLoader.infoToCanvasData(asset);
79008
+ const keyStr = key.serialize();
79009
+ const pending = this.preload(key);
79010
+ const cached = Caching.textureAssetCache.getIfPresent(keyStr);
79011
+ try {
79012
+ const asset = await pending;
79013
+ if (asset) {
79014
+ return await ImageLoader.infoToCanvasData(asset);
79015
+ }
79016
+ return void 0;
79017
+ } catch (err) {
79018
+ if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
79019
+ Caching.textureAssetCache.invalidate(keyStr);
79020
+ }
79021
+ throw err;
79074
79022
  }
79075
- return void 0;
79076
79023
  }
79077
79024
  static async preload(key) {
79078
79025
  const keyStr = key.serialize();
@@ -79798,12 +79745,16 @@ return ${compiler2.callType("value", tagType)}
79798
79745
  static async getBlockEntityModels() {
79799
79746
  const key = AssetKey.parse("models", "minerender:blockEntityModels");
79800
79747
  console.log(key);
79801
- return AssetLoader.get(key, "json" /* JSON */);
79748
+ return Caching.entityModelsCache.get(key.serialize(), () => {
79749
+ return AssetLoader.get(key, "json" /* JSON */);
79750
+ });
79802
79751
  }
79803
79752
  static async getEntityModels() {
79804
79753
  const key = AssetKey.parse("models", "minerender:entityModels");
79805
79754
  console.log(key);
79806
- return AssetLoader.get(key, "json" /* JSON */);
79755
+ return Caching.entityModelsCache.get(key.serialize(), () => {
79756
+ return AssetLoader.get(key, "json" /* JSON */);
79757
+ });
79807
79758
  }
79808
79759
  // BlockEntity names are hardcoded
79809
79760
  static async getBlockList() {
@@ -79849,12 +79800,6 @@ return ${compiler2.callType("value", tagType)}
79849
79800
  };
79850
79801
  }
79851
79802
  };
79852
- __decorateClass([
79853
- Memoize()
79854
- ], Entities, "getBlockEntityModels", 1);
79855
- __decorateClass([
79856
- Memoize()
79857
- ], Entities, "getEntityModels", 1);
79858
79803
  var EntityModels = class {
79859
79804
  };
79860
79805
  var BlockEntityModels = class {
@@ -80367,8 +80312,8 @@ return ${compiler2.callType("value", tagType)}
80367
80312
  dispose() {
80368
80313
  super.dispose();
80369
80314
  }
80370
- async loadTextures() {
80371
- this.imageData = await ModelTextures.get(new AssetKey(
80315
+ get textureKey() {
80316
+ return new AssetKey(
80372
80317
  this.entity.key?.namespace ?? DEFAULT_NAMESPACE,
80373
80318
  this.entity.key.path,
80374
80319
  //TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
@@ -80376,7 +80321,10 @@ return ${compiler2.callType("value", tagType)}
80376
80321
  "entity",
80377
80322
  "assets",
80378
80323
  ".png"
80379
- ));
80324
+ );
80325
+ }
80326
+ async loadTextures() {
80327
+ this.imageData = await ModelTextures.get(this.textureKey);
80380
80328
  }
80381
80329
  //TODO: abstract this, since extracted model data can be used for entities, blocks, players
80382
80330
  createMeshes(force = false) {
@@ -80409,20 +80357,23 @@ return ${compiler2.callType("value", tagType)}
80409
80357
  this.meshesCreated = true;
80410
80358
  }
80411
80359
  async applyTextures() {
80412
- const textureAsset = await ModelTextures.preload(new AssetKey(
80413
- this.entity.key?.namespace ?? DEFAULT_NAMESPACE,
80414
- this.entity.key.path,
80415
- "textures",
80416
- "entity",
80417
- "assets",
80418
- ".png"
80419
- ));
80420
- if (textureAsset) {
80421
- let mat = Materials.getImage({ texture: { src: textureAsset.src } });
80422
- this.iterateAllMeshes((mesh) => {
80423
- mesh.material = mat;
80424
- });
80425
- }
80360
+ const assetKeyStr = this.textureKey.serialize();
80361
+ const keyStr = `entity:${assetKeyStr}`;
80362
+ let mat = Caching.materialCache.getIfPresent(keyStr);
80363
+ if (!mat) {
80364
+ const pending = this.loadTextures();
80365
+ const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
80366
+ await pending;
80367
+ if (!this.imageData) return;
80368
+ const canvas = this.imageData.data.canvas;
80369
+ const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
80370
+ mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
80371
+ this.imageData = void 0;
80372
+ }
80373
+ this.iterateAllMeshes((mesh) => {
80374
+ mesh.material = mat;
80375
+ });
80376
+ this.notifyDirty();
80426
80377
  }
80427
80378
  };
80428
80379
  EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});