squishjs 1.4.2 → 1.4.3

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": "squishjs",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "description": "squish & unsquish stuff",
5
5
  "scripts": {
6
6
  "test": "node testRunner.js"
package/src/Asset.js CHANGED
@@ -165,23 +165,34 @@ class Asset {
165
165
  const fileHash = this.getHash(assetId);
166
166
  const filePath = `${assetPath}/${fileHash}`;
167
167
 
168
- const writeStream = fs.createWriteStream(filePath);
169
168
  const getModule = ASSET_URL.startsWith('https') ? https : http;
170
169
 
171
- writeStream.on('close', () => {
172
- resolve(filePath);
173
- });
174
-
175
170
  getModule.get(`${ASSET_URL}/${assetId}`, (res) => {
176
171
  if (res.statusCode !== 200) {
172
+ res.resume();
177
173
  reject('Bad response when downloading asset');
178
- } else {
179
- writeStream.on('finish', () => {
180
- writeStream.close();
181
- });
182
-
183
- res.pipe(writeStream);
174
+ return;
184
175
  }
176
+
177
+ // Only open the cache file once we know the response is good —
178
+ // otherwise a failed download leaves a zero-byte file behind
179
+ // that reads back as a valid cache hit forever after.
180
+ const writeStream = fs.createWriteStream(filePath);
181
+
182
+ writeStream.on('close', () => {
183
+ resolve(filePath);
184
+ });
185
+
186
+ writeStream.on('error', (error) => {
187
+ fs.unlink(filePath, () => reject(error));
188
+ });
189
+
190
+ res.on('error', (error) => {
191
+ writeStream.destroy();
192
+ fs.unlink(filePath, () => reject(error));
193
+ });
194
+
195
+ res.pipe(writeStream);
185
196
  }).on('error', error => {
186
197
  console.error('Failed to download asset');
187
198
  console.error(error);
package/src/Squisher.js CHANGED
@@ -35,7 +35,9 @@ class Squisher {
35
35
 
36
36
  if (this.game.tick) {
37
37
  const tickRate = this.gameMetadata && this.gameMetadata.tickRate ? this.gameMetadata.tickRate : DEFAULT_TICK_RATE;
38
- setInterval(this.game.tick.bind(this.game), 1000 / tickRate);
38
+ // Keep the handle so consumers can end the tick loop (repeated
39
+ // session create/destroy in one process leaks it otherwise).
40
+ this._tickInterval = setInterval(this.game.tick.bind(this.game), 1000 / tickRate);
39
41
  }
40
42
  }
41
43
 
@@ -28,12 +28,16 @@ const squishCoordinates2d = {
28
28
 
29
29
  if (node.subType == subtypes.SHAPE_2D_CIRCLE) {
30
30
  if (scale) {
31
+ // Math.floor on the integer byte is required, not decorative:
32
+ // a raw float here only decoded correctly because Node's
33
+ // Buffer truncated it on send. Consumers that don't go through
34
+ // Buffer (e.g. the in-browser LocalSession) would round.
31
35
  const shiftedCenterX = clampCoord(squishHelper(scale.x, originalCoords[0]))
32
- squished[0] = shiftedCenterX;
36
+ squished[0] = Math.floor(shiftedCenterX);
33
37
  squished[1] = getFractional(shiftedCenterX);
34
38
 
35
39
  const shiftedCenterY = clampCoord(squishHelper(scale.y, originalCoords[1]))
36
- squished[2] = shiftedCenterY;
40
+ squished[2] = Math.floor(shiftedCenterY);
37
41
  squished[3] = getFractional(shiftedCenterY);
38
42
 
39
43
  let diagonal;
@@ -70,7 +74,7 @@ const squishCoordinates2d = {
70
74
 
71
75
  const shifted = clampCoord(scaled + (removedSpace / 2));
72
76
 
73
- squished[2 * i] = shifted;
77
+ squished[2 * i] = Math.floor(shifted);
74
78
  squished[(2 * i) + 1] = getFractional(shifted);
75
79
 
76
80
  } else {