@shipload/sdk 1.0.0-next.41 → 1.0.0-next.43

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/src/scan/index.ts CHANGED
@@ -44,6 +44,38 @@ function ex(): any {
44
44
 
45
45
  const hex = (h: string) => Uint8Array.from(h.match(/../g)!.map((b) => parseInt(b, 16)))
46
46
 
47
+ // Shared marshalling for the `*_in_box` exports; grow-and-retry once on overflow (export returns -needed).
48
+ function boxScan<T>(
49
+ exportName: string,
50
+ stride: number,
51
+ gameSeed: string,
52
+ xMin: number,
53
+ yMin: number,
54
+ xMax: number,
55
+ yMax: number,
56
+ decode: (dv: DataView, o: number) => T
57
+ ): T[] {
58
+ const e = ex()
59
+ const mem = e.memory as WebAssembly.Memory
60
+ const g = e.malloc(32)
61
+ new Uint8Array(mem.buffer, g, 32).set(hex(gameSeed))
62
+ let cap = 256
63
+ let out = e.malloc(cap * stride)
64
+ let n = e[exportName](g, xMin, yMin, xMax, yMax, out, cap)
65
+ if (n < 0) {
66
+ e.free(out)
67
+ cap = -n
68
+ out = e.malloc(cap * stride)
69
+ n = e[exportName](g, xMin, yMin, xMax, yMax, out, cap)
70
+ }
71
+ const dv = new DataView(mem.buffer, out, n * stride)
72
+ const res: T[] = []
73
+ for (let i = 0; i < n; i++) res.push(decode(dv, i * stride))
74
+ e.free(g)
75
+ e.free(out)
76
+ return res
77
+ }
78
+
47
79
  export function getLocationType(gameSeed: string, x: number, y: number): number {
48
80
  const e = ex()
49
81
  const mem = e.memory as WebAssembly.Memory
@@ -87,32 +119,55 @@ export function systemsInBox(
87
119
  xMax: number,
88
120
  yMax: number
89
121
  ): SystemCell[] {
90
- const e = ex()
91
- const mem = e.memory as WebAssembly.Memory
92
- const g = e.malloc(32)
93
- new Uint8Array(mem.buffer, g, 32).set(hex(gameSeed))
94
- let cap = 256
95
- let out = e.malloc(cap * 12)
96
- let n = e.systems_in_box(g, xMin, yMin, xMax, yMax, out, cap)
97
- if (n < 0) {
98
- e.free(out)
99
- cap = -n
100
- out = e.malloc(cap * 12)
101
- n = e.systems_in_box(g, xMin, yMin, xMax, yMax, out, cap)
102
- }
103
- const res: SystemCell[] = []
104
- const dv = new DataView(mem.buffer.slice(out, out + n * 12))
105
- for (let i = 0; i < n; i++) {
106
- const o = i * 12
107
- res.push({
108
- x: dv.getInt32(o, true),
109
- y: dv.getInt32(o + 4, true),
110
- locType: dv.getUint32(o + 8, true),
111
- })
112
- }
113
- e.free(g)
114
- e.free(out)
115
- return res
122
+ return boxScan('systems_in_box', 12, gameSeed, xMin, yMin, xMax, yMax, (dv, o) => ({
123
+ x: dv.getInt32(o, true),
124
+ y: dv.getInt32(o + 4, true),
125
+ locType: dv.getUint32(o + 8, true),
126
+ }))
127
+ }
128
+
129
+ export interface LocationCell {
130
+ x: number
131
+ y: number
132
+ locType: number
133
+ subtype: number
134
+ size: number
135
+ }
136
+
137
+ export function locationsInBox(
138
+ gameSeed: string,
139
+ xMin: number,
140
+ yMin: number,
141
+ xMax: number,
142
+ yMax: number
143
+ ): LocationCell[] {
144
+ return boxScan('locations_in_box', 16, gameSeed, xMin, yMin, xMax, yMax, (dv, o) => ({
145
+ x: dv.getInt32(o, true),
146
+ y: dv.getInt32(o + 4, true),
147
+ locType: dv.getUint8(o + 8),
148
+ subtype: dv.getUint8(o + 9),
149
+ size: dv.getUint32(o + 12, true),
150
+ }))
151
+ }
152
+
153
+ export interface WormholeCell {
154
+ x: number
155
+ y: number
156
+ exit: {x: number; y: number}
157
+ }
158
+
159
+ export function wormholesInBox(
160
+ gameSeed: string,
161
+ xMin: number,
162
+ yMin: number,
163
+ xMax: number,
164
+ yMax: number
165
+ ): WormholeCell[] {
166
+ return boxScan('wormholes_in_box', 16, gameSeed, xMin, yMin, xMax, yMax, (dv, o) => ({
167
+ x: dv.getInt32(o, true),
168
+ y: dv.getInt32(o + 4, true),
169
+ exit: {x: dv.getInt32(o + 8, true), y: dv.getInt32(o + 12, true)},
170
+ }))
116
171
  }
117
172
 
118
173
  export async function scanCells(
@@ -121,6 +176,15 @@ export async function scanCells(
121
176
  cells: Coord[]
122
177
  ): Promise<DerivedCell[]> {
123
178
  await scanReady()
179
+ return scanCellsCore(gameSeed, epochSeed, cells)
180
+ }
181
+
182
+ // Sync sibling of scanCells; caller must warm the instance via scanReady() first.
183
+ export function scanCellsSync(gameSeed: string, epochSeed: string, cells: Coord[]): DerivedCell[] {
184
+ return scanCellsCore(gameSeed, epochSeed, cells)
185
+ }
186
+
187
+ function scanCellsCore(gameSeed: string, epochSeed: string, cells: Coord[]): DerivedCell[] {
124
188
  const e = ex()
125
189
  const mem = e.memory as WebAssembly.Memory
126
190
  const write = (b: Uint8Array) => {
@@ -146,9 +210,8 @@ export async function scanCells(
146
210
  depOut = e.malloc(cap * 40)
147
211
  n = e.scan_cells(gp, ep, cp, cells.length, locOut, depOut, cap)
148
212
  }
149
- const locView = new DataView(mem.buffer.slice(locOut, locOut + cells.length * 8))
150
- const depView = new DataView(mem.buffer.slice(depOut, depOut + n * 40))
151
- for (const p of [gp, ep, cp, locOut, depOut]) e.free(p)
213
+ const locView = new DataView(mem.buffer, locOut, cells.length * 8)
214
+ const depView = new DataView(mem.buffer, depOut, n * 40)
152
215
  const out: DerivedCell[] = cells.map((c, i) => ({
153
216
  location: {
154
217
  x: c.x,
@@ -176,5 +239,6 @@ export async function scanCells(
176
239
  ],
177
240
  })
178
241
  }
242
+ for (const p of [gp, ep, cp, locOut, depOut]) e.free(p)
179
243
  return out
180
244
  }