@xtia/grid 0.1.0 → 0.1.1
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/README.md +6 -8
- package/lib/grid.d.ts +1 -7
- package/lib/grid.js +10 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ npm i @xtia/grid
|
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
```ts
|
|
25
|
-
import { Grid } from "@xtia/grid"; // ~4.8kb gzipped
|
|
25
|
+
import { Grid } from "@xtia/grid"; // ~4.8kb gzipped (2.2kb + Pipe2D dep)
|
|
26
26
|
|
|
27
27
|
// initialise a 30x20 Grid<number> of 0's
|
|
28
28
|
const numGrid = Grid.solid(30, 20, 0);
|
|
@@ -32,7 +32,7 @@ numGrid.set(3, 3, 50);
|
|
|
32
32
|
|
|
33
33
|
// initialise a chessboard
|
|
34
34
|
const chessGrid = Grid.init(8, 8, (x, y) =>
|
|
35
|
-
|
|
35
|
+
(x + y) % 2 === 0 ? 'black' : 'white'
|
|
36
36
|
);
|
|
37
37
|
|
|
38
38
|
// read a value
|
|
@@ -106,12 +106,11 @@ const lakeGrid = Grid.from(lakeRegion);
|
|
|
106
106
|
|
|
107
107
|
```ts
|
|
108
108
|
const spriteMap = world.map(
|
|
109
|
-
type => type + ".png",
|
|
110
|
-
sprite => sprite.replace(/\..*/, '')
|
|
109
|
+
type => type + ".png", // add .png on parent-read
|
|
110
|
+
sprite => sprite.replace(/\..*/, '') // remove it on parent-write
|
|
111
111
|
);
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
console.log(spriteMap.get(0, 0)); // read the transformed view: "mountain.png"
|
|
113
|
+
console.log(spriteMap.get(0, 0)); // read the transformed view: "grass.png"
|
|
115
114
|
spriteMap.set(1, 0, "forest.png"); // modify the view
|
|
116
115
|
console.log(world.get(1, 0)); // read the parent: "forest"
|
|
117
116
|
```
|
|
@@ -144,7 +143,6 @@ const minimap = world.pipe
|
|
|
144
143
|
.floorCoordinates()
|
|
145
144
|
.crop(viewX, viewY, vw, vh)
|
|
146
145
|
.stretch(canvas.width, canvas.height);
|
|
147
|
-
|
|
148
146
|
```
|
|
149
147
|
|
|
150
148
|
## Cell interface
|
|
@@ -248,7 +246,7 @@ world.paste(snapshot);
|
|
|
248
246
|
For persistent storage or transmission, Pipe2D can export as array:
|
|
249
247
|
|
|
250
248
|
```ts
|
|
251
|
-
const saved = snapshot.toFlatArrayXY(); // ["
|
|
249
|
+
const saved = snapshot.toFlatArrayXY(); // ["grass", "forest", "grass", ...]
|
|
252
250
|
|
|
253
251
|
const restoredSnapshot = Pipe2D.fromFlatArrayXY(saved);
|
|
254
252
|
```
|
package/lib/grid.d.ts
CHANGED
|
@@ -67,13 +67,8 @@ export declare class Grid<T> {
|
|
|
67
67
|
fill(value: T): void;
|
|
68
68
|
paste(source: Source2D<T>, x?: number, y?: number): void;
|
|
69
69
|
writeMask(mask: Source2D<boolean> | GetXYFunc<boolean>): Grid<T>;
|
|
70
|
-
[Symbol.iterator](): IterableIterator<
|
|
71
|
-
x: number;
|
|
72
|
-
y: number;
|
|
73
|
-
value: T;
|
|
74
|
-
}>;
|
|
70
|
+
[Symbol.iterator](): IterableIterator<T>;
|
|
75
71
|
forEach(callback: (value: T, x: number, y: number) => void): void;
|
|
76
|
-
combine<U, R>(aux: Source2D<U>, cb: (source: T, aux: U) => R): GridBase<R>;
|
|
77
72
|
map<U>(read: (initial: T, x: number, y: number) => U, write: (local: U, x: number, y: number) => T): Grid<U>;
|
|
78
73
|
region(x: number, y: number, width: number, height: number): Grid<T>;
|
|
79
74
|
scroll(xDelta: number, yDelta: number, fill: T): this;
|
|
@@ -90,7 +85,6 @@ export declare class GridBase<T> extends Grid<T> {
|
|
|
90
85
|
batchUpdate(fn: () => void): void;
|
|
91
86
|
constructor(source: Source2D<T>);
|
|
92
87
|
on<K extends keyof EventMap<T>>(eventName: K, handler: (data: EventMap<T>[K]) => void): () => void;
|
|
93
|
-
private xyToIndex;
|
|
94
88
|
private _set;
|
|
95
89
|
private triggerChange;
|
|
96
90
|
}
|
package/lib/grid.js
CHANGED
|
@@ -215,6 +215,9 @@ export class Grid {
|
|
|
215
215
|
this.parentSet = parentSet;
|
|
216
216
|
this.batch = batch;
|
|
217
217
|
this.cells = new Pipe2D(this.width, this.height, (x, y) => {
|
|
218
|
+
if (x < 0 || x >= this.width || y < 0 || y >= this.height || !Number.isInteger(x) || !Number.isInteger(y)) {
|
|
219
|
+
throw new RangeError(`Cell coordinates must be bounded integers; got (${x}, ${y})`);
|
|
220
|
+
}
|
|
218
221
|
return new Cell(x, y, this);
|
|
219
222
|
}).strict().withCache();
|
|
220
223
|
this.pipe = new Pipe2D(this);
|
|
@@ -293,7 +296,7 @@ export class Grid {
|
|
|
293
296
|
*[Symbol.iterator]() {
|
|
294
297
|
for (let y = 0; y < this.height; y++) {
|
|
295
298
|
for (let x = 0; x < this.width; x++) {
|
|
296
|
-
yield
|
|
299
|
+
yield this.get(x, y);
|
|
297
300
|
}
|
|
298
301
|
}
|
|
299
302
|
}
|
|
@@ -304,22 +307,11 @@ export class Grid {
|
|
|
304
307
|
}
|
|
305
308
|
}
|
|
306
309
|
}
|
|
307
|
-
combine(aux, cb) {
|
|
308
|
-
const width = Math.min(this.width, aux.width);
|
|
309
|
-
const height = Math.min(this.height, aux.height);
|
|
310
|
-
return new GridBase({
|
|
311
|
-
width,
|
|
312
|
-
height,
|
|
313
|
-
get: (x, y) => {
|
|
314
|
-
return cb(this.get(x, y), aux.get(x, y));
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
310
|
map(read, write) {
|
|
319
311
|
return new Grid(this.width, this.height, (x, y) => read(this.parentGet(x, y), x, y), (x, y, value) => this.parentSet(x, y, write(value, x, y)), fn => this.batch(fn));
|
|
320
312
|
}
|
|
321
313
|
region(x, y, width, height) {
|
|
322
|
-
if (!Number.isInteger(x) || !Number.isInteger(y)
|
|
314
|
+
if (!Number.isInteger(x) || !Number.isInteger(y)) {
|
|
323
315
|
throw new Error(`Region boundaries must be integer; got (${x}, ${y}), (${width} x ${height})`);
|
|
324
316
|
}
|
|
325
317
|
if (x < 0 || y < 0 || x + width > this.width || y + height > this.height) {
|
|
@@ -387,11 +379,12 @@ export class GridBase extends Grid {
|
|
|
387
379
|
if (this.batchState.level == 0) {
|
|
388
380
|
const changed = this.batchState.changedCells;
|
|
389
381
|
this.batchState = null;
|
|
390
|
-
|
|
382
|
+
if (changed.size > 0)
|
|
383
|
+
this.triggerChange(changed);
|
|
391
384
|
}
|
|
392
385
|
}
|
|
393
386
|
constructor(source) {
|
|
394
|
-
super(source.width, source.height, (x, y) => this.data[this.
|
|
387
|
+
super(source.width, source.height, (x, y) => this.data[y * this.width + x], (x, y, value) => this._set(x, y, value), fn => this.batchUpdate(fn));
|
|
395
388
|
this.eventHandlers = {};
|
|
396
389
|
this.batchState = null;
|
|
397
390
|
const sourcePipe = source instanceof Pipe2D
|
|
@@ -411,20 +404,11 @@ export class GridBase extends Grid {
|
|
|
411
404
|
this.eventHandlers[eventName].splice(idx, 1);
|
|
412
405
|
};
|
|
413
406
|
}
|
|
414
|
-
xyToIndex(x, y) {
|
|
415
|
-
if (x < 0 || x >= this.width || y < 0 || y >= this.height) {
|
|
416
|
-
throw new Error(`Coordinates out of bounds: (${x}, ${y})`);
|
|
417
|
-
}
|
|
418
|
-
if (!Number.isInteger(x) || !Number.isInteger(y)) {
|
|
419
|
-
throw new Error(`Coordinates must be integer; got (${x}, ${y})`);
|
|
420
|
-
}
|
|
421
|
-
return y * this.width + x;
|
|
422
|
-
}
|
|
423
407
|
_set(x, y, value) {
|
|
424
|
-
const idx = this.
|
|
408
|
+
const idx = y * this.width + x;
|
|
425
409
|
if (this.data[idx] === value)
|
|
426
410
|
return;
|
|
427
|
-
this.data[
|
|
411
|
+
this.data[idx] = value;
|
|
428
412
|
if (this.batchState) {
|
|
429
413
|
this.batchState.changedCells.add(this.cells.get(x, y));
|
|
430
414
|
return;
|
package/package.json
CHANGED