@thi.ng/soa 0.4.87 → 0.4.88
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/CHANGELOG.md +1 -1
- package/aos.js +27 -60
- package/api.js +0 -1
- package/package.json +12 -9
- package/serialize.js +44 -53
- package/soa.js +158 -154
- package/utils.js +7 -4
package/CHANGELOG.md
CHANGED
package/aos.js
CHANGED
|
@@ -2,64 +2,31 @@ import { SIZEOF } from "@thi.ng/api/typedarray";
|
|
|
2
2
|
import { align } from "@thi.ng/binary/align";
|
|
3
3
|
import { SOA } from "./soa.js";
|
|
4
4
|
import { prepareSpec } from "./utils.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* @param num -
|
|
35
|
-
* @param specs -
|
|
36
|
-
* @param buf -
|
|
37
|
-
* @param byteOffset -
|
|
38
|
-
*/
|
|
39
|
-
export const aos = (num, specs, buf, byteOffset = 0) => {
|
|
40
|
-
let total = 0;
|
|
41
|
-
let maxSize = 0;
|
|
42
|
-
const offsets = {};
|
|
43
|
-
const soaSpecs = {};
|
|
44
|
-
for (let id in specs) {
|
|
45
|
-
const spec = prepareSpec(specs[id]);
|
|
46
|
-
const tsize = SIZEOF[spec.type];
|
|
47
|
-
maxSize = Math.max(maxSize, tsize);
|
|
48
|
-
// align field to type size
|
|
49
|
-
total = align(total, tsize);
|
|
50
|
-
offsets[id] = total;
|
|
51
|
-
total += tsize * spec.size;
|
|
52
|
-
soaSpecs[id] = spec;
|
|
53
|
-
}
|
|
54
|
-
// align total struct size to largest type
|
|
55
|
-
total = align(total, maxSize);
|
|
56
|
-
buf = buf || new ArrayBuffer(total * num + byteOffset);
|
|
57
|
-
for (let id in soaSpecs) {
|
|
58
|
-
const spec = soaSpecs[id];
|
|
59
|
-
const tsize = SIZEOF[spec.type];
|
|
60
|
-
spec.stride = total / tsize;
|
|
61
|
-
spec.buf = buf;
|
|
62
|
-
spec.byteOffset = byteOffset + offsets[id];
|
|
63
|
-
}
|
|
64
|
-
return new SOA(num, soaSpecs);
|
|
5
|
+
const aos = (num, specs, buf, byteOffset = 0) => {
|
|
6
|
+
let total = 0;
|
|
7
|
+
let maxSize = 0;
|
|
8
|
+
const offsets = {};
|
|
9
|
+
const soaSpecs = {};
|
|
10
|
+
for (let id in specs) {
|
|
11
|
+
const spec = prepareSpec(specs[id]);
|
|
12
|
+
const tsize = SIZEOF[spec.type];
|
|
13
|
+
maxSize = Math.max(maxSize, tsize);
|
|
14
|
+
total = align(total, tsize);
|
|
15
|
+
offsets[id] = total;
|
|
16
|
+
total += tsize * spec.size;
|
|
17
|
+
soaSpecs[id] = spec;
|
|
18
|
+
}
|
|
19
|
+
total = align(total, maxSize);
|
|
20
|
+
buf = buf || new ArrayBuffer(total * num + byteOffset);
|
|
21
|
+
for (let id in soaSpecs) {
|
|
22
|
+
const spec = soaSpecs[id];
|
|
23
|
+
const tsize = SIZEOF[spec.type];
|
|
24
|
+
spec.stride = total / tsize;
|
|
25
|
+
spec.buf = buf;
|
|
26
|
+
spec.byteOffset = byteOffset + offsets[id];
|
|
27
|
+
}
|
|
28
|
+
return new SOA(num, soaSpecs);
|
|
29
|
+
};
|
|
30
|
+
export {
|
|
31
|
+
aos
|
|
65
32
|
};
|
package/api.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/soa",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.88",
|
|
4
4
|
"description": "SOA & AOS memory mapped structured views with optional & extensible serialization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"author": "Karsten Schmidt (https://thi.ng)",
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "yarn
|
|
27
|
+
"build": "yarn build:esbuild && yarn build:decl",
|
|
28
|
+
"build:decl": "tsc --declaration --emitDeclarationOnly",
|
|
29
|
+
"build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
|
|
28
30
|
"clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
|
|
29
31
|
"doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
|
|
30
32
|
"doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
|
|
@@ -33,15 +35,16 @@
|
|
|
33
35
|
"test": "bun test"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@thi.ng/api": "^8.9.
|
|
37
|
-
"@thi.ng/binary": "^3.
|
|
38
|
-
"@thi.ng/errors": "^2.4.
|
|
39
|
-
"@thi.ng/transducers-binary": "^2.1.
|
|
40
|
-
"@thi.ng/vectors": "^7.8.
|
|
38
|
+
"@thi.ng/api": "^8.9.12",
|
|
39
|
+
"@thi.ng/binary": "^3.4.0",
|
|
40
|
+
"@thi.ng/errors": "^2.4.6",
|
|
41
|
+
"@thi.ng/transducers-binary": "^2.1.82",
|
|
42
|
+
"@thi.ng/vectors": "^7.8.9"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"@microsoft/api-extractor": "^7.38.3",
|
|
44
|
-
"@thi.ng/equiv": "^2.1.
|
|
46
|
+
"@thi.ng/equiv": "^2.1.37",
|
|
47
|
+
"esbuild": "^0.19.8",
|
|
45
48
|
"rimraf": "^5.0.5",
|
|
46
49
|
"tools": "^0.0.1",
|
|
47
50
|
"typedoc": "^0.25.4",
|
|
@@ -103,5 +106,5 @@
|
|
|
103
106
|
"status": "alpha",
|
|
104
107
|
"year": 2019
|
|
105
108
|
},
|
|
106
|
-
"gitHead": "
|
|
109
|
+
"gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n"
|
|
107
110
|
}
|
package/serialize.js
CHANGED
|
@@ -1,61 +1,52 @@
|
|
|
1
1
|
import { identity } from "@thi.ng/api/fn";
|
|
2
2
|
import { assert } from "@thi.ng/errors/assert";
|
|
3
3
|
import { utf8Decode, utf8Encode } from "@thi.ng/transducers-binary/utf8";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export const ident = {
|
|
8
|
-
decode: identity,
|
|
9
|
-
encode: identity,
|
|
4
|
+
const ident = {
|
|
5
|
+
decode: identity,
|
|
6
|
+
encode: identity
|
|
10
7
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export const scalar = {
|
|
15
|
-
decode: (v) => v[0],
|
|
16
|
-
encode: (x) => [x],
|
|
8
|
+
const scalar = {
|
|
9
|
+
decode: (v) => v[0],
|
|
10
|
+
encode: (x) => [x]
|
|
17
11
|
};
|
|
18
12
|
const toUTF8 = utf8Decode();
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
xf(acc, c);
|
|
37
|
-
}
|
|
38
|
-
return acc;
|
|
39
|
-
},
|
|
40
|
-
encode: (v) => {
|
|
41
|
-
const bytes = [...utf8Encode(v), 0];
|
|
42
|
-
assert(bytes.length <= maxLen, `string too large: "${v}"`);
|
|
43
|
-
return bytes;
|
|
44
|
-
},
|
|
13
|
+
const utf8z = (maxLen) => ({
|
|
14
|
+
decode: (v) => {
|
|
15
|
+
let acc = "";
|
|
16
|
+
const xf = toUTF8([null, null, (_, x) => acc += x])[2];
|
|
17
|
+
for (let i = 0, n = v.length; i < n; i++) {
|
|
18
|
+
const c = v[i];
|
|
19
|
+
if (c === 0)
|
|
20
|
+
break;
|
|
21
|
+
xf(acc, c);
|
|
22
|
+
}
|
|
23
|
+
return acc;
|
|
24
|
+
},
|
|
25
|
+
encode: (v) => {
|
|
26
|
+
const bytes = [...utf8Encode(v), 0];
|
|
27
|
+
assert(bytes.length <= maxLen, `string too large: "${v}"`);
|
|
28
|
+
return bytes;
|
|
29
|
+
}
|
|
45
30
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
31
|
+
const serializer = (specs) => ({
|
|
32
|
+
decode(tuple) {
|
|
33
|
+
const res = {};
|
|
34
|
+
for (let id in tuple) {
|
|
35
|
+
res[id] = specs[id].decode(tuple[id]);
|
|
36
|
+
}
|
|
37
|
+
return res;
|
|
38
|
+
},
|
|
39
|
+
encode: (tuple) => {
|
|
40
|
+
const res = {};
|
|
41
|
+
for (let id in tuple) {
|
|
42
|
+
res[id] = specs[id].encode(tuple[id]);
|
|
43
|
+
}
|
|
44
|
+
return res;
|
|
45
|
+
}
|
|
61
46
|
});
|
|
47
|
+
export {
|
|
48
|
+
ident,
|
|
49
|
+
scalar,
|
|
50
|
+
serializer,
|
|
51
|
+
utf8z
|
|
52
|
+
};
|
package/soa.js
CHANGED
|
@@ -2,159 +2,163 @@ import { SIZEOF, typedArray } from "@thi.ng/api/typedarray";
|
|
|
2
2
|
import { assert } from "@thi.ng/errors/assert";
|
|
3
3
|
import { ensureIndex } from "@thi.ng/errors/out-of-bounds";
|
|
4
4
|
import { prepareSpec } from "./utils.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
5
|
+
class SOA {
|
|
6
|
+
length;
|
|
7
|
+
buffers;
|
|
8
|
+
specs;
|
|
9
|
+
constructor(num, specs) {
|
|
10
|
+
this.length = num;
|
|
11
|
+
this.buffers = {};
|
|
12
|
+
this.specs = {};
|
|
13
|
+
this.addSpecs(specs);
|
|
14
|
+
}
|
|
15
|
+
keys() {
|
|
16
|
+
return Object.keys(this.specs);
|
|
17
|
+
}
|
|
18
|
+
*values(from = 0, to = this.length) {
|
|
19
|
+
ensureIndex(from, 0, this.length);
|
|
20
|
+
ensureIndex(to, from, this.length + 1);
|
|
21
|
+
for (; from < to; from++) {
|
|
22
|
+
yield this.indexUnsafe(from);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
attribValues(id, from = 0, to = this.length) {
|
|
26
|
+
this.ensureAttrib(id);
|
|
27
|
+
ensureIndex(from, 0, this.length);
|
|
28
|
+
ensureIndex(to, from, this.length + 1);
|
|
29
|
+
let { size, stride, type } = this.specs[id];
|
|
30
|
+
const buf = this.buffers[id].buffer;
|
|
31
|
+
stride *= SIZEOF[type];
|
|
32
|
+
from *= stride;
|
|
33
|
+
to *= stride;
|
|
34
|
+
const res = [];
|
|
35
|
+
for (; from < to; from += stride) {
|
|
36
|
+
res.push(typedArray(type, buf, from, size));
|
|
37
|
+
}
|
|
38
|
+
return res;
|
|
39
|
+
}
|
|
40
|
+
attribValue(id, i) {
|
|
41
|
+
this.ensureAttrib(id);
|
|
42
|
+
ensureIndex(i, 0, this.length);
|
|
43
|
+
return this.attribValueUnsafe(id, i);
|
|
44
|
+
}
|
|
45
|
+
attribValueUnsafe(id, i) {
|
|
46
|
+
const spec = this.specs[id];
|
|
47
|
+
i *= spec.stride;
|
|
48
|
+
return this.buffers[id].subarray(i, i + spec.size);
|
|
49
|
+
}
|
|
50
|
+
setAttribValue(id, i, val) {
|
|
51
|
+
this.ensureAttrib(id);
|
|
52
|
+
ensureIndex(i, 0, this.length);
|
|
53
|
+
const spec = this.specs[id];
|
|
54
|
+
assert(val.length <= spec.size, `${id} value too large`);
|
|
55
|
+
this.buffers[id].set(val, i * spec.stride);
|
|
56
|
+
}
|
|
57
|
+
setAttribValueUnsafe(id, i, val) {
|
|
58
|
+
this.buffers[id].set(val, i * this.specs[id].stride);
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
setAttribValues(id, vals, from = 0) {
|
|
62
|
+
this.ensureAttrib(id);
|
|
63
|
+
ensureIndex(from, 0, this.length);
|
|
64
|
+
const buf = this.buffers[id];
|
|
65
|
+
const stride = this.specs[id].stride;
|
|
66
|
+
const end = this.length * stride;
|
|
67
|
+
let i = from * stride;
|
|
68
|
+
for (let v of vals) {
|
|
69
|
+
buf.set(v, i);
|
|
70
|
+
i += stride;
|
|
71
|
+
if (i >= end)
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
index(i, ids) {
|
|
77
|
+
ensureIndex(i, 0, this.length);
|
|
78
|
+
return this.indexUnsafe(i, ids);
|
|
79
|
+
}
|
|
80
|
+
indexUnsafe(i, ids) {
|
|
81
|
+
const res = {};
|
|
82
|
+
if (ids) {
|
|
83
|
+
for (let i2 = ids.length; i2-- > 0; ) {
|
|
84
|
+
const id = ids[i2];
|
|
85
|
+
res[id] = this.attribValueUnsafe(id, i2);
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
for (let id in this.specs) {
|
|
89
|
+
res[id] = this.attribValueUnsafe(id, i);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return res;
|
|
93
|
+
}
|
|
94
|
+
setIndex(i, vals) {
|
|
95
|
+
ensureIndex(i, 0, this.length);
|
|
96
|
+
for (let id in vals) {
|
|
97
|
+
this.setAttribValue(id, i, vals[id]);
|
|
98
|
+
}
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
setIndexUnsafe(i, vals) {
|
|
102
|
+
for (let id in vals) {
|
|
103
|
+
this.setAttribValueUnsafe(id, i, vals[id]);
|
|
104
|
+
}
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
107
|
+
setValues(vals, from = 0) {
|
|
108
|
+
for (let id in vals) {
|
|
109
|
+
this.setAttribValues(id, vals[id], from);
|
|
110
|
+
}
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
copyTo(dest, ids, destFrom = 0, srcFrom = 0, srcTo = this.length) {
|
|
114
|
+
ensureIndex(srcFrom, 0, this.length);
|
|
115
|
+
ensureIndex(srcTo, srcFrom, this.length + 1);
|
|
116
|
+
const num = srcTo - srcFrom;
|
|
117
|
+
ensureIndex(destFrom, 0, dest.length);
|
|
118
|
+
ensureIndex(destFrom + num, destFrom, dest.length + 1);
|
|
119
|
+
ids = ids || Object.keys(this.specs);
|
|
120
|
+
for (let k = ids.length; k-- > 0; ) {
|
|
121
|
+
const id = ids[k];
|
|
122
|
+
for (let i = srcFrom, j = destFrom; i < srcTo; i++, j++) {
|
|
123
|
+
dest.setAttribValueUnsafe(id, j, this.attribValueUnsafe(id, i));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return dest;
|
|
127
|
+
}
|
|
128
|
+
addSpecs(specs) {
|
|
129
|
+
const num = this.length;
|
|
130
|
+
for (let id in specs) {
|
|
131
|
+
assert(!this.specs[id], `attrib ${id} already exists`);
|
|
132
|
+
const spec = prepareSpec(specs[id]);
|
|
133
|
+
this.validateSpec(id, spec);
|
|
134
|
+
const { stride, default: defVal } = spec;
|
|
135
|
+
const buffer = spec.buf ? typedArray(spec.type, spec.buf, spec.byteOffset || 0) : typedArray(spec.type, num * stride);
|
|
136
|
+
if (defVal) {
|
|
137
|
+
for (let i = 0; i < num; i++) {
|
|
138
|
+
buffer.set(defVal, i * stride);
|
|
92
139
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return this;
|
|
113
|
-
}
|
|
114
|
-
copyTo(dest, ids, destFrom = 0, srcFrom = 0, srcTo = this.length) {
|
|
115
|
-
ensureIndex(srcFrom, 0, this.length);
|
|
116
|
-
ensureIndex(srcTo, srcFrom, this.length + 1);
|
|
117
|
-
const num = srcTo - srcFrom;
|
|
118
|
-
ensureIndex(destFrom, 0, dest.length);
|
|
119
|
-
ensureIndex(destFrom + num, destFrom, dest.length + 1);
|
|
120
|
-
ids = ids || Object.keys(this.specs);
|
|
121
|
-
for (let k = ids.length; k-- > 0;) {
|
|
122
|
-
const id = ids[k];
|
|
123
|
-
for (let i = srcFrom, j = destFrom; i < srcTo; i++, j++) {
|
|
124
|
-
dest.setAttribValueUnsafe(id, j, this.attribValueUnsafe(id, i));
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return dest;
|
|
128
|
-
}
|
|
129
|
-
addSpecs(specs) {
|
|
130
|
-
const num = this.length;
|
|
131
|
-
for (let id in specs) {
|
|
132
|
-
assert(!this.specs[id], `attrib ${id} already exists`);
|
|
133
|
-
const spec = prepareSpec(specs[id]);
|
|
134
|
-
this.validateSpec(id, spec);
|
|
135
|
-
const { stride, default: defVal } = spec;
|
|
136
|
-
const buffer = spec.buf
|
|
137
|
-
? typedArray(spec.type, spec.buf, spec.byteOffset || 0)
|
|
138
|
-
: typedArray(spec.type, num * stride);
|
|
139
|
-
if (defVal) {
|
|
140
|
-
for (let i = 0; i < num; i++) {
|
|
141
|
-
buffer.set(defVal, i * stride);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
this.specs[id] = spec;
|
|
145
|
-
this.buffers[id] = buffer;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
validateSpec(id, spec) {
|
|
149
|
-
assert(spec.stride >= spec.size, `${id} illegal stride`);
|
|
150
|
-
assert(!spec.buf ||
|
|
151
|
-
spec.buf.byteLength >=
|
|
152
|
-
((this.length - 1) * spec.stride + spec.size) *
|
|
153
|
-
SIZEOF[spec.type], `${id} buffer too small`);
|
|
154
|
-
assert(spec.default === undefined || spec.default.length === spec.size, `illegal default value for ${id}, expected size: ${spec.size}`);
|
|
155
|
-
}
|
|
156
|
-
ensureAttrib(id) {
|
|
157
|
-
assert(!!this.specs[id], `invalid attrib ${id}`);
|
|
158
|
-
}
|
|
140
|
+
}
|
|
141
|
+
this.specs[id] = spec;
|
|
142
|
+
this.buffers[id] = buffer;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
validateSpec(id, spec) {
|
|
146
|
+
assert(spec.stride >= spec.size, `${id} illegal stride`);
|
|
147
|
+
assert(
|
|
148
|
+
!spec.buf || spec.buf.byteLength >= ((this.length - 1) * spec.stride + spec.size) * SIZEOF[spec.type],
|
|
149
|
+
`${id} buffer too small`
|
|
150
|
+
);
|
|
151
|
+
assert(
|
|
152
|
+
spec.default === void 0 || spec.default.length === spec.size,
|
|
153
|
+
`illegal default value for ${id}, expected size: ${spec.size}`
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
ensureAttrib(id) {
|
|
157
|
+
assert(!!this.specs[id], `invalid attrib ${id}`);
|
|
158
|
+
}
|
|
159
159
|
}
|
|
160
|
-
|
|
160
|
+
const soa = (num, specs) => new SOA(num, specs);
|
|
161
|
+
export {
|
|
162
|
+
SOA,
|
|
163
|
+
soa
|
|
164
|
+
};
|
package/utils.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
const prepareSpec = (spec) => {
|
|
2
|
+
spec = { type: "f32", size: 1, ...spec };
|
|
3
|
+
!spec.stride && (spec.stride = spec.size);
|
|
4
|
+
return spec;
|
|
5
|
+
};
|
|
6
|
+
export {
|
|
7
|
+
prepareSpec
|
|
5
8
|
};
|