@makefully/platypus 4.1.9 → 4.1.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makefully/platypus",
3
- "version": "4.1.9",
3
+ "version": "4.1.11",
4
4
  "description": "2D tile-based HTML5 game engine with a component-based entity model",
5
5
  "license": "MIT",
6
6
  "contributors": [
@@ -7,6 +7,7 @@
7
7
  /* global platypus, setTimeout */
8
8
  import Data from './Data.js';
9
9
  import DataMap from './DataMap.js';
10
+ import PIXIAnimation from './PIXIAnimation.js';
10
11
  import {Assets} from 'pixi.js';
11
12
  import {arrayCache} from './utils/array.js';
12
13
 
@@ -26,6 +27,9 @@ const
26
27
  'src', path,
27
28
  'data', asset.data ?? null
28
29
  );
30
+ },
31
+ isRegisteredWithPixi = function (alias, src) {
32
+ return Assets.resolver.hasKey(alias) || (src && src !== alias && Assets.resolver.hasKey(src));
29
33
  };
30
34
 
31
35
  export default class AssetManager {
@@ -55,6 +59,7 @@ export default class AssetManager {
55
59
  asset.src = '';
56
60
  }
57
61
  assets.delete(alias);
62
+ PIXIAnimation.invalidateTextureSources(alias);
58
63
  }
59
64
 
60
65
  return !counts[alias];
@@ -71,7 +76,18 @@ export default class AssetManager {
71
76
  * @return {Object} Returns the asset if defined.
72
77
  */
73
78
  get (alias) {
74
- return this.assets.get(alias);
79
+ if (this.assets.has(alias)) {
80
+ return this.assets.get(alias);
81
+ }
82
+
83
+ const
84
+ fileId = this.getFileId(alias);
85
+
86
+ if (fileId !== alias && this.assets.has(fileId)) {
87
+ return this.assets.get(fileId);
88
+ }
89
+
90
+ return undefined;
75
91
  }
76
92
 
77
93
  /**
@@ -131,6 +147,7 @@ export default class AssetManager {
131
147
  const
132
148
  counts = this.counts,
133
149
  needsLoading = arrayCache.setUp(),
150
+ needsRelink = arrayCache.setUp(),
134
151
  adds = Data.setUp();
135
152
 
136
153
  if (platypus.game?.options?.images ?? platypus.game?.options?.audio) {
@@ -154,13 +171,39 @@ export default class AssetManager {
154
171
  adds[alias] += 1;
155
172
  } else {
156
173
  adds[alias] = 1;
174
+ if (isRegisteredWithPixi(alias, item.src)) {
175
+ needsRelink.push(item);
176
+ } else {
177
+ needsLoading.push(item);
178
+ }
179
+ }
180
+ }
181
+
182
+ for (let i = needsRelink.length - 1; i >= 0; i--) {
183
+ const
184
+ item = needsRelink[i],
185
+ alias = item.alias[0],
186
+ asset = Assets.get(alias) ?? Assets.get(item.src);
187
+
188
+ if (asset) {
189
+ this.set(alias, asset, adds[alias]);
190
+ needsRelink.splice(i, 1);
191
+ } else {
157
192
  needsLoading.push(item);
193
+ needsRelink.splice(i, 1);
158
194
  }
159
195
  }
160
196
 
161
197
  if (needsLoading.length) {
162
198
  // Do this first to pass `data` property if needed
163
- needsLoading.forEach((asset) => Assets.add(asset));
199
+ needsLoading.forEach((asset) => {
200
+ const
201
+ alias = asset.alias[0];
202
+
203
+ if (!isRegisteredWithPixi(alias, asset.src)) {
204
+ Assets.add(asset);
205
+ }
206
+ });
164
207
 
165
208
  const
166
209
  aliases = needsLoading.map((asset) => asset.alias[0]),
@@ -188,6 +231,7 @@ export default class AssetManager {
188
231
  }
189
232
 
190
233
  arrayCache.recycle(needsLoading);
234
+ arrayCache.recycle(needsRelink);
191
235
  }
192
236
 
193
237
  /**
@@ -4,15 +4,74 @@ import {arrayCache, greenSlice} from './utils/array.js';
4
4
  import Data from './Data.js';
5
5
 
6
6
  const
7
- MAX_KEY_LENGTH_PER_IMAGE = 128,
8
7
  animationCache = {},
9
8
  textureSourceCache = {},
10
9
  doNothing = function () {},
11
10
  emptyFrame = Texture.EMPTY,
12
- regex = /[\[\]{},-]/g,
11
+ imageBasename = /([\w-\.]+)\.(\w+)$/,
12
+ hashString = function (value) {
13
+ const
14
+ str = typeof value === 'string' ? value : JSON.stringify(value);
15
+ let hash = 5381;
16
+
17
+ for (let i = 0; i < str.length; i++) {
18
+ hash = ((hash << 5) + hash) ^ str.charCodeAt(i);
19
+ }
20
+
21
+ return (hash >>> 0).toString(36);
22
+ },
23
+ getTextureCacheKey = function (path) {
24
+ return platypus.assetCache?.getFileId ? platypus.assetCache.getFileId(path) : path;
25
+ },
26
+ resolveTextureAsset = function (path) {
27
+ const
28
+ assetCache = platypus.assetCache;
29
+
30
+ if (!assetCache) {
31
+ return null;
32
+ }
33
+
34
+ let asset = assetCache.get(path);
35
+
36
+ if (asset) {
37
+ return asset;
38
+ }
39
+
40
+ const
41
+ basename = typeof path === 'string' ? path.match(imageBasename) : null;
42
+
43
+ if (basename) {
44
+ asset = assetCache.get(basename[1]);
45
+
46
+ if (asset) {
47
+ return asset;
48
+ }
49
+ }
50
+
51
+ return null;
52
+ },
53
+ getTextureSourceAliases = function (alias) {
54
+ const
55
+ aliases = arrayCache.setUp(alias),
56
+ basename = typeof alias === 'string' ? alias.match(imageBasename) : null;
57
+
58
+ if (platypus.assetCache?.getFileId) {
59
+ const
60
+ fileId = platypus.assetCache.getFileId(alias);
61
+
62
+ if (fileId !== alias) {
63
+ aliases.push(fileId);
64
+ }
65
+ }
66
+
67
+ if (basename) {
68
+ aliases.push(basename[1]);
69
+ }
70
+
71
+ return aliases;
72
+ },
13
73
  getTextureSources = function (images) {
14
74
  const
15
- assetCache = platypus.assetCache,
16
75
  bts = arrayCache.setUp();
17
76
 
18
77
  for (let i = 0; i < images.length; i++) {
@@ -20,17 +79,21 @@ const
20
79
  path = images[i];
21
80
 
22
81
  if (typeof path === 'string') {
23
- if (!textureSourceCache[path]) {
24
- const
25
- asset = assetCache.get(path);
82
+ const
83
+ cacheKey = getTextureCacheKey(path),
84
+ asset = resolveTextureAsset(path);
26
85
 
27
- if (!asset) {
28
- platypus.debug.warn(`PIXIAnimation: "${path}" is not a loaded asset.`);
29
- break;
30
- }
31
- textureSourceCache[path] = asset.source;
86
+ if (!asset) {
87
+ delete textureSourceCache[cacheKey];
88
+ platypus.debug.warn(`PIXIAnimation: "${path}" is not a loaded asset.`);
89
+ break;
90
+ }
91
+
92
+ if (textureSourceCache[cacheKey] !== asset.source) {
93
+ textureSourceCache[cacheKey] = asset.source;
32
94
  }
33
- bts.push(textureSourceCache[path]);
95
+
96
+ bts.push(textureSourceCache[cacheKey]);
34
97
  } else {
35
98
  bts.push(new TextureSource(path));
36
99
  }
@@ -49,9 +112,7 @@ const
49
112
  }
50
113
  }
51
114
 
52
- spriteSheet.id = JSON.stringify(spriteSheet).replace(regex, '');
53
-
54
- return spriteSheet.id;
115
+ return `ss-${hashString(spriteSheet)}`;
55
116
  },
56
117
  getDefaultAnimation = function (length, textures) {
57
118
  const
@@ -397,6 +458,29 @@ const
397
458
  };
398
459
  }
399
460
 
461
+ /**
462
+ * Removes cached texture sources for an unloaded asset alias.
463
+ *
464
+ * @method platypus.PIXIAnimation.invalidateTextureSources
465
+ * @param {*} alias Asset alias or path used when the texture was cached.
466
+ */
467
+ static invalidateTextureSources (alias) {
468
+ const
469
+ aliases = getTextureSourceAliases(alias),
470
+ cacheKey = getTextureCacheKey(alias);
471
+ let i = aliases.length;
472
+
473
+ if (aliases.indexOf(cacheKey) === -1) {
474
+ aliases.push(cacheKey);
475
+ }
476
+
477
+ while (i--) {
478
+ delete textureSourceCache[aliases[i]];
479
+ }
480
+
481
+ arrayCache.recycle(aliases);
482
+ }
483
+
400
484
  /**
401
485
  * This method formats a provided value into a valid PIXIAnimation Sprite Sheet. This includes accepting the EaselJS spec, strings mapping to Platypus sprite sheets, or arrays of either.
402
486
  *
@@ -406,7 +490,6 @@ const
406
490
  */
407
491
  static formatSpriteSheet (spriteSheet) {
408
492
  const
409
- imageParts = /([\w-\.]+)\.(\w+)$/,
410
493
  addAnimations = function (source = {}, destination, speedRatio, firstFrameIndex, id) {
411
494
  const
412
495
  keys = Object.keys(source),
@@ -458,7 +541,6 @@ const
458
541
  ));
459
542
  }
460
543
  },
461
- createId = (images) => images.map((image) => (image.src ?? image).substring(0, MAX_KEY_LENGTH_PER_IMAGE)).join(','),
462
544
  format = function (source, destination) {
463
545
  const
464
546
  {
@@ -479,11 +561,8 @@ const
479
561
  firstImageIndex = dImages.length,
480
562
  firstFrameIndex = dFrames.length;
481
563
 
482
- // Set up id
483
- if (dID) {
484
- destination.id = `${dID};${sID ?? createId(sImages)}`;
485
- } else {
486
- destination.id = sID ?? createId(sImages);
564
+ if (sID) {
565
+ destination.id = dID ? `${dID};${sID}` : sID;
487
566
  }
488
567
 
489
568
  // Set up images array
@@ -546,7 +625,7 @@ const
546
625
  formatImages = function (name) {
547
626
  if (typeof name === 'string') {
548
627
  const
549
- match = name.match(imageParts);
628
+ match = name.match(imageBasename);
550
629
 
551
630
  if (match) {
552
631
  return match[1];
package/src/VOPlayer.js CHANGED
@@ -662,7 +662,7 @@ class VOPlayer extends Messenger {
662
662
  * @public
663
663
  */
664
664
  unloadSound (sound) {
665
- this.assetCache.delete(sound);
665
+ this.assetCache.delete(this.assetCache.getFileId(sound));
666
666
  }
667
667
 
668
668
  /**