game-data-gen 2.2.0 → 3.0.0

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 CHANGED
@@ -16,7 +16,7 @@ If you're making a game in Javascript then you might (this was actually me):
16
16
 
17
17
  This library:
18
18
 
19
- - creates data structures based on a very easy syntax (I tried JSON, didn't feel it)
19
+ - creates data structures based on Markdown file (see example below)
20
20
  - each data structure gets associated functions to zero out its memory so it can be reused
21
21
 
22
22
  ## Installation
@@ -31,122 +31,98 @@ npm i -D game-data-gen
31
31
  npx game-data-gen <input-file-path> <optional-output-file-path>
32
32
  ```
33
33
 
34
- ## Format
35
-
36
- ```
37
- name type? length? struct?
38
- fieldName fieldType fieldArrayType? fieldArrayLength?
39
- ```
40
-
41
- `name`
42
-
43
- The name of the data structure.
44
-
45
- `type`
46
-
47
- Supported data structure types:
48
-
49
- - group
50
- - struct
51
- - soa (Structure of Arrays)
52
- - aos (Array of Structures)
53
-
54
- `length` (optional)
55
-
56
- The length of the arrays within the Structure of Arrays data structure.
57
-
58
- If no length is given to the type and no length is given to a field it is considered a dynamic array and zeroing will set the array's length back to zero (emptying it).
59
-
60
- `struct` (optional, required if type=aos)
61
-
62
- The struct to use for this Array of Structures.
63
-
64
- `fieldName`
65
-
66
- The name of one of the fields within the data structure.
67
-
68
- `fieldType`
69
-
70
- Supported field types:
71
-
72
- - string
73
- - number
74
- - boolean
75
- - array
76
- - a struct (see entity struct in example below)
77
-
78
- `fieldArrayType` (required if fieldType=array)
79
-
80
- Supported array field types:
81
-
82
- - string
83
- - boolean
84
- - number
85
-
86
- `fieldArrayLength` (optional)
87
-
88
- The length of the array field, leave empty to use a dynamically sized array instead of a fixed size array.
89
-
90
- In case of a Structure of Arrays data structure (type=soa), setting the length on the type instead is recommended so that all arrays have the same length.
91
-
92
-
93
34
  ## Example
94
35
 
95
- Create a plain text file somewhere in your source code (without a file extension).
36
+ Create a Markdown file somewhere in your source code (without a file extension).
96
37
 
97
- For example `src/data/game`:
38
+ For example `src/data.md`:
98
39
 
99
- ```
100
- game group
101
- activeEntities array number
40
+ ```md
41
+ # game group
42
+ - activeEntities array entity
43
+ - activeEntityIds array number
44
+ - playerId number
102
45
 
103
- vector struct
104
- x number
105
- y number
46
+ # vector struct
47
+ - x number
48
+ - y number
106
49
 
107
- entity struct
108
- position vector
109
- velocity vector
110
- health number
111
- isActive boolean
50
+ # entity struct
51
+ - position vector
52
+ - velocity vector
53
+ <!-- stats -->
54
+ - health number
55
+ <!-- inventory -->
56
+ - items array number
57
+ <!-- flags -->
58
+ - isActive boolean
112
59
 
113
- entities aos 2048 entity
60
+ # entities aos 2048 entity
114
61
 
115
- particle soa 1024
116
- posX array number
117
- posY array number
62
+ # particle soa 10_000
63
+ - type string
64
+ - pos Vector
118
65
  ```
119
66
 
120
67
  Run the package with (consider making this a script in your package.json):
121
68
 
122
69
  ```shell
123
- npx game-data-gen src/data/game
70
+ npx game-data-gen src/data.md
124
71
  ```
125
72
 
126
- This will create or update the `src/data/game.ts` file (see below). The data and functions can then be imported from this file into your code.
73
+ This will create or update the `src/data.ts` file (see below). The data and functions can then be imported from this file into your code.
127
74
 
128
75
  ```typescript
129
76
  /*
130
77
  * --------------------------------------------------
131
- * game (group)
78
+ * game (Group)
132
79
  * --------------------------------------------------
133
80
  */
134
81
 
135
- export const activeEntities = new Array<number>()
82
+ export let activeEntities = new Array<Entity>()
83
+ export let activeEntityIds = new Array<number>()
84
+ export let playerId = 0
85
+
86
+ /** Set the value of the activeEntities field within the game group. */
87
+ export function setActiveEntities(value: Array<Entity>) {
88
+ activeEntities = value
89
+ }
90
+
91
+ /** Set the value of the activeEntityIds field within the game group. */
92
+ export function setActiveEntityIds(value: Array<number>) {
93
+ activeEntityIds = value
94
+ }
95
+
96
+ /** Set the value of the playerId field within the game group. */
97
+ export function setPlayerId(value: number) {
98
+ playerId = value
99
+ }
136
100
 
137
101
  /** Zero the activeEntities field within the game group. */
138
102
  export function zeroActiveEntities() {
139
103
  activeEntities.length = 0
140
104
  }
141
105
 
106
+ /** Zero the activeEntityIds field within the game group. */
107
+ export function zeroActiveEntityIds() {
108
+ activeEntityIds.length = 0
109
+ }
110
+
111
+ /** Zero the playerId field within the game group. */
112
+ export function zeroPlayerId() {
113
+ playerId = 0
114
+ }
115
+
142
116
  /** Zero all fields within the game group. */
143
117
  export function zeroGameData() {
144
118
  activeEntities.length = 0
119
+ activeEntityIds.length = 0
120
+ playerId = 0
145
121
  }
146
122
 
147
123
  /*
148
124
  * --------------------------------------------------
149
- * vector (struct)
125
+ * vector (Struct)
150
126
  * --------------------------------------------------
151
127
  */
152
128
 
@@ -156,13 +132,26 @@ export type Vector = {
156
132
  }
157
133
 
158
134
  /** Create a new Vector object. */
159
- export function createVector(): Vector {
160
- const obj = Object.create(null)
135
+ export function createVector() {
136
+ const obj: Vector = Object.create(null)
161
137
  obj.x = 0
162
138
  obj.y = 0
163
139
  return obj
164
140
  }
165
141
 
142
+ /** Copy the values of Vector object b into Vector object a. */
143
+ export function copyVector(a: Vector, b: Vector) {
144
+ a.x = b.x
145
+ a.y = b.y
146
+ }
147
+
148
+ /** Clone the given Vector object. */
149
+ export function cloneVector(obj: Vector) {
150
+ const clone = createVector()
151
+ copyVector(clone, obj)
152
+ return clone
153
+ }
154
+
166
155
  /** Zero the given Vector object. */
167
156
  export function zeroVector(obj: Vector) {
168
157
  obj.x = 0
@@ -171,7 +160,7 @@ export function zeroVector(obj: Vector) {
171
160
 
172
161
  /*
173
162
  * --------------------------------------------------
174
- * entity (struct)
163
+ * entity (Struct)
175
164
  * --------------------------------------------------
176
165
  */
177
166
 
@@ -179,40 +168,56 @@ export type Entity = {
179
168
  position: Vector
180
169
  velocity: Vector
181
170
  health: number
171
+ items: Array<number>
182
172
  isActive: boolean
183
173
  }
184
174
 
185
175
  /** Create a new Entity object. */
186
- export function createEntity(): Entity {
187
- const obj = Object.create(null)
176
+ export function createEntity() {
177
+ const obj: Entity = Object.create(null)
188
178
  obj.position = createVector()
189
179
  obj.velocity = createVector()
190
180
  obj.health = 0
181
+ obj.items = new Array<number>()
191
182
  obj.isActive = false
192
183
  return obj
193
184
  }
194
185
 
186
+ /** Copy the values of Entity object b into Entity object a. */
187
+ export function copyEntity(a: Entity, b: Entity) {
188
+ a.position = b.position
189
+ a.velocity = b.velocity
190
+ a.health = b.health
191
+ a.items = b.items
192
+ a.isActive = b.isActive
193
+ }
194
+
195
+ /** Clone the given Entity object. */
196
+ export function cloneEntity(obj: Entity) {
197
+ const clone = createEntity()
198
+ copyEntity(clone, obj)
199
+ return clone
200
+ }
201
+
195
202
  /** Zero the given Entity object. */
196
203
  export function zeroEntity(obj: Entity) {
197
204
  zeroVector(obj.position)
198
205
  zeroVector(obj.velocity)
199
206
  obj.health = 0
207
+ obj.items.length = 0
200
208
  obj.isActive = false
201
209
  }
202
210
 
203
211
  /*
204
212
  * --------------------------------------------------
205
- * entities (array of structures)
213
+ * entities (Array Of Structures)
206
214
  * --------------------------------------------------
207
215
  */
208
216
 
209
217
  export const MAX_ENTITIES_COUNT = 2048
210
218
 
211
219
  /** An array of Entity objects (structures). */
212
- export const entities = new Array<Entity>(2048)
213
- for (let i=0; i<2048; i++) {
214
- entities[i] = createEntity()
215
- }
220
+ export const entities = Array.from({ length: 2048 }, createEntity)
216
221
 
217
222
  /** Zero all objects within the entities array of structures. */
218
223
  export function zeroEntities() {
@@ -221,36 +226,41 @@ export function zeroEntities() {
221
226
  }
222
227
  }
223
228
 
229
+ /** Zero an object at a specific index within the entities array of structures. */
230
+ export function zeroEntitiesAt(index: number) {
231
+ zeroEntity(entities[index])
232
+ }
233
+
224
234
  /*
225
235
  * --------------------------------------------------
226
- * particle (structure of arrays)
236
+ * particle (Structure Of Arrays)
227
237
  * --------------------------------------------------
228
238
  */
229
239
 
230
- export const MAX_PARTICLE_COUNT = 1024
240
+ export const MAX_PARTICLE_COUNT = 10_000
231
241
 
232
- export const posX = new Array<number>(1024).fill(0)
233
- export const posY = new Array<number>(1024).fill(0)
242
+ export const type = new Array(10_000).fill("")
243
+ export const pos = Array.from({ length: 10_000 }, createVector)
234
244
 
235
245
  /** Zero an index within the particle structure of arrays. */
236
246
  export function zeroParticle(idx: number) {
237
- posX[idx] = 0
238
- posY[idx] = 0
247
+ type[idx] = ""
248
+ zeroVector(pos[idx])
239
249
  }
240
250
 
241
- /** Zero the posX field within the particle structure of arrays. */
242
- export function zeroPosX() {
243
- posX.fill(0)
251
+ /** Zero the type field within the particle structure of arrays. */
252
+ export function zeroType() {
253
+ type.fill("")
244
254
  }
245
255
 
246
- /** Zero the posY field within the particle structure of arrays. */
247
- export function zeroPosY() {
248
- posY.fill(0)
256
+ /** Zero the pos field within the particle structure of arrays. */
257
+ export function zeroPos() {
258
+ pos.forEach(zeroVector)
249
259
  }
250
260
 
251
261
  /** Zero all fields within the particle structure of arrays. */
252
262
  export function zeroParticleData() {
253
- posX.fill(0)
254
- posY.fill(0)
263
+ type.fill("")
264
+ pos.forEach(zeroVector)
255
265
  }
256
266
  ```
package/dist/consts.js CHANGED
@@ -11,7 +11,6 @@ export var FieldType;
11
11
  FieldType["NUMBER"] = "number";
12
12
  FieldType["BOOLEAN"] = "boolean";
13
13
  FieldType["ARRAY"] = "array";
14
- FieldType["SET"] = "set";
15
14
  })(FieldType || (FieldType = {}));
16
15
  export var ArrayType;
17
16
  (function (ArrayType) {
package/dist/lib/aos.js CHANGED
@@ -1,32 +1,33 @@
1
- import { addFieldMaxLengthConstant } from "./fields.js";
2
- import { capitalize, getName } from "./utils.js";
1
+ import { addHeader, capitalize } from "./utils.js";
3
2
  export function addArrayOfStructures(header, output) {
4
- const [name, , length, struct] = header.split(" ");
3
+ const [name, , length, type] = header.split(" ");
4
+ addHeader(`${name} (Array Of Structures)`, output);
5
5
  addFieldMaxLengthConstant(name, length, output);
6
- addArrayOfStructuresDefinition(name, struct, length, output);
7
- addArrayOfStructuresZeroFunction(name, struct, length, output);
8
- addArrayOfStructuresZeroAtIndexFunction(name, struct, output);
6
+ addArrayOfStructuresDefinition(name, type, length, output);
7
+ addArrayOfStructuresZeroFunction(name, type, length, output);
8
+ addArrayOfStructuresZeroAtIndexFunction(name, type, output);
9
9
  }
10
- function addArrayOfStructuresDefinition(name, struct, length, output) {
11
- output.push(`/** An array of ${capitalize(struct)} objects (structures). */`);
12
- output.push(`export const ${name} = new Array<${getName(struct)}>(${length})`);
13
- output.push(`for (let i=0; i<${length}; i++) {`);
14
- output.push(` ${name}[i] = create${capitalize(struct)}()`);
15
- output.push("}");
10
+ function addFieldMaxLengthConstant(name, length, output) {
11
+ output.push(`export const MAX_${name.toUpperCase()}_COUNT = ${length}`);
12
+ output.push("");
13
+ }
14
+ function addArrayOfStructuresDefinition(name, type, length, output) {
15
+ output.push(`/** An array of ${capitalize(type)} objects (structures). */`);
16
+ output.push(`export const ${name} = Array.from({ length: ${length} }, create${capitalize(type)})`);
16
17
  }
17
- function addArrayOfStructuresZeroFunction(name, struct, length, output) {
18
+ function addArrayOfStructuresZeroFunction(name, type, length, output) {
18
19
  output.push("");
19
20
  output.push(`/** Zero all objects within the ${name} array of structures. */`);
20
21
  output.push(`export function zero${capitalize(name)}() {`);
21
22
  output.push(` for (let i=0; i<${length}; i++) {`);
22
- output.push(` zero${capitalize(struct)}(${name}[i])`);
23
+ output.push(` zero${capitalize(type)}(${name}[i])`);
23
24
  output.push(" }");
24
25
  output.push("}");
25
26
  }
26
- function addArrayOfStructuresZeroAtIndexFunction(name, struct, output) {
27
+ function addArrayOfStructuresZeroAtIndexFunction(name, type, output) {
27
28
  output.push("");
28
29
  output.push(`/** Zero an object at a specific index within the ${name} array of structures. */`);
29
- output.push(`export function zero${capitalize(struct)}At(index: number) {`);
30
- output.push(` zero${capitalize(struct)}(${name}[index])`);
30
+ output.push(`export function zero${capitalize(name)}At(i: number) {`);
31
+ output.push(` zero${capitalize(type)}(${name}[i])`);
31
32
  output.push("}");
32
33
  }
@@ -101,6 +101,6 @@ function zeroField(name, type, arrayType, length, output) {
101
101
  }
102
102
  }
103
103
  export function addFieldMaxLengthConstant(name, length, output) {
104
- output.push(`export const MAX_${name.toUpperCase()}_COUNT = ${length}`);
104
+ output.push(`export const MAX_${name.toUpperCase()} = ${length}`);
105
105
  output.push("");
106
106
  }
package/dist/lib/group.js CHANGED
@@ -1,14 +1,79 @@
1
- import { addFieldDefinition, addFieldSetFunction, addFieldZeroFunction, addZeroFunction } from "./fields.js";
1
+ import { FieldType } from "../consts.js";
2
+ import { addHeader, capitalize, getTypeName } from "./utils.js";
2
3
  export function addGroup(header, fields, output) {
3
- const [name, type, baseLength] = header.split(" ");
4
+ const [name] = header.split(" ");
5
+ addHeader(`${name} (Group)`, output);
4
6
  for (const field of fields) {
5
- addFieldDefinition(field, baseLength, output);
7
+ addFieldDefinition(field, output);
6
8
  }
7
9
  for (const field of fields) {
8
- addFieldSetFunction(name, type, field, output);
10
+ addFieldSetFunction(name, field, output);
9
11
  }
10
12
  for (const field of fields) {
11
- addFieldZeroFunction(name, type, field, baseLength, output);
13
+ addFieldZeroFunction(name, field, output);
14
+ }
15
+ addZeroFunction(name, fields, output);
16
+ }
17
+ function addFieldDefinition(field, output) {
18
+ const [fieldName, fieldType, fieldArrayType] = field.split(" ");
19
+ switch (fieldType) {
20
+ case FieldType.STRING:
21
+ output.push(`export let ${fieldName} = ""`);
22
+ break;
23
+ case FieldType.NUMBER:
24
+ output.push(`export let ${fieldName} = 0`);
25
+ break;
26
+ case FieldType.BOOLEAN:
27
+ output.push(`export let ${fieldName} = false`);
28
+ break;
29
+ case FieldType.ARRAY:
30
+ output.push(`export let ${fieldName} = new Array<${getTypeName(fieldArrayType)}>()`);
31
+ break;
32
+ default:
33
+ output.push(`export let ${fieldName} = create${capitalize(fieldType)}()`);
34
+ }
35
+ }
36
+ function addFieldSetFunction(name, field, output) {
37
+ const [fieldName, fieldType, fieldArrayType] = field.split(" ");
38
+ output.push("");
39
+ output.push(`/** Set the value of the ${fieldName} field within the ${name} group. */`);
40
+ output.push(`export function set${capitalize(fieldName)}(v: ${getTypeName(fieldType, fieldArrayType)}) {`);
41
+ output.push(` ${fieldName} = v`);
42
+ output.push("}");
43
+ }
44
+ function addFieldZeroFunction(name, field, output) {
45
+ const [fieldName, fieldType] = field.split(" ");
46
+ output.push("");
47
+ output.push(`/** Zero the ${fieldName} field within the ${name} group. */`);
48
+ output.push(`export function zero${capitalize(fieldName)}() {`);
49
+ zeroField(fieldName, fieldType, output);
50
+ output.push("}");
51
+ }
52
+ function addZeroFunction(name, fields, output) {
53
+ output.push("");
54
+ output.push(`/** Zero all fields within the ${name} group. */`);
55
+ output.push(`export function zero${capitalize(name)}Data() {`);
56
+ for (const field of fields) {
57
+ const [fieldName, fieldType] = field.split(" ");
58
+ zeroField(fieldName, fieldType, output);
59
+ }
60
+ output.push("}");
61
+ }
62
+ function zeroField(name, type, output) {
63
+ switch (type) {
64
+ case FieldType.STRING:
65
+ output.push(` ${name} = ""`);
66
+ break;
67
+ case FieldType.NUMBER:
68
+ output.push(` ${name} = 0`);
69
+ break;
70
+ case FieldType.BOOLEAN:
71
+ output.push(` ${name} = false`);
72
+ break;
73
+ case FieldType.ARRAY:
74
+ output.push(` ${name}.length = 0`);
75
+ break;
76
+ default:
77
+ output.push(` zero${capitalize(type)}(${name})`);
12
78
  }
13
- addZeroFunction(name, type, fields, baseLength, output);
14
79
  }
package/dist/lib/soa.js CHANGED
@@ -1,37 +1,89 @@
1
1
  import { ArrayType } from "../consts.js";
2
- import { addFieldDefinition, addFieldMaxLengthConstant, addFieldSetFunction, addFieldZeroFunction, addZeroFunction } from "./fields.js";
3
- import { capitalize, getName } from "./utils.js";
2
+ import { addHeader, capitalize } from "./utils.js";
4
3
  export function addStructureOfArrays(header, fields, output) {
5
- const [name, type, baseLength] = header.split(" ");
6
- addFieldMaxLengthConstant(name, baseLength, output);
4
+ const [name, _, length] = header.split(" ");
5
+ addHeader(`${name} (Structure Of Arrays)`, output);
6
+ addFieldMaxLengthConstant(name, length, output);
7
7
  for (const field of fields) {
8
- addFieldDefinition(field, baseLength, output);
8
+ addFieldDefinition(field, length, output);
9
9
  }
10
+ addFieldZeroAtIndexFunction(name, fields, output);
10
11
  for (const field of fields) {
11
- addFieldSetFunction(name, type, field, output);
12
+ addFieldZeroFunction(name, field, output);
12
13
  }
13
- addFieldZeroAtIndexFunction(name, type, fields, output);
14
+ addZeroFunction(name, fields, output);
15
+ }
16
+ function addFieldMaxLengthConstant(name, length, output) {
17
+ output.push(`export const MAX_${name.toUpperCase()}_COUNT = ${length}`);
18
+ output.push("");
19
+ }
20
+ function addFieldDefinition(field, length, output) {
21
+ const [fieldName, fieldType] = field.split(" ");
22
+ switch (fieldType) {
23
+ case ArrayType.STRING:
24
+ output.push(`export const ${fieldName} = new Array(${length}).fill("")`);
25
+ break;
26
+ case ArrayType.NUMBER:
27
+ output.push(`export const ${fieldName} = new Array(${length}).fill(0)`);
28
+ break;
29
+ case ArrayType.BOOLEAN:
30
+ output.push(`export const ${fieldName} = new Array(${length}).fill(false)`);
31
+ break;
32
+ default:
33
+ output.push(`export const ${fieldName} = Array.from({ length: ${length} }, create${capitalize(fieldType)})`);
34
+ }
35
+ }
36
+ function addFieldZeroFunction(name, field, output) {
37
+ const [fieldName, fieldType] = field.split(" ");
38
+ output.push("");
39
+ output.push(`/** Zero the ${fieldName} field within the ${name} structure of arrays. */`);
40
+ output.push(`export function zero${capitalize(fieldName)}() {`);
41
+ zeroField(fieldName, fieldType, output);
42
+ output.push("}");
43
+ }
44
+ function addZeroFunction(name, fields, output) {
45
+ output.push("");
46
+ output.push(`/** Zero all fields within the ${name} structure of arrays. */`);
47
+ output.push(`export function zero${capitalize(name)}Data() {`);
14
48
  for (const field of fields) {
15
- addFieldZeroFunction(name, type, field, baseLength, output);
49
+ const [fieldName, fieldType] = field.split(" ");
50
+ zeroField(fieldName, fieldType, output);
51
+ }
52
+ output.push("}");
53
+ }
54
+ function zeroField(name, type, output) {
55
+ switch (type) {
56
+ case ArrayType.STRING:
57
+ output.push(` ${name}.fill("")`);
58
+ break;
59
+ case ArrayType.NUMBER:
60
+ output.push(` ${name}.fill(0)`);
61
+ break;
62
+ case ArrayType.BOOLEAN:
63
+ output.push(` ${name}.fill(false)`);
64
+ break;
65
+ default:
66
+ output.push(` ${name}.forEach(zero${capitalize(type)})`);
16
67
  }
17
- addZeroFunction(name, type, fields, baseLength, output);
18
68
  }
19
- function addFieldZeroAtIndexFunction(name, type, fields, output) {
69
+ function addFieldZeroAtIndexFunction(name, fields, output) {
20
70
  output.push("");
21
- output.push(`/** Zero an index within the ${name} ${getName(type)}. */`);
22
- output.push(`export function zero${capitalize(name)}(idx: number) {`);
71
+ output.push(`/** Zero an index within the ${name} structure of arrays. */`);
72
+ output.push(`export function zero${capitalize(name)}(i: number) {`);
23
73
  for (const field of fields) {
24
- const [fieldName, _, fieldArrayType] = field.split(" ");
25
- switch (fieldArrayType) {
74
+ const [fieldName, fieldType] = field.split(" ");
75
+ switch (fieldType) {
26
76
  case ArrayType.STRING:
27
- output.push(` ${fieldName}[idx] = ""`);
77
+ output.push(` ${fieldName}[i] = ""`);
28
78
  break;
29
79
  case ArrayType.NUMBER:
30
- output.push(` ${fieldName}[idx] = 0`);
80
+ output.push(` ${fieldName}[i] = 0`);
31
81
  break;
32
82
  case ArrayType.BOOLEAN:
33
- output.push(` ${fieldName}[idx] = false`);
83
+ output.push(` ${fieldName}[i] = false`);
34
84
  break;
85
+ default:
86
+ output.push(` zero${capitalize(fieldType)}(${fieldName}[i])`);
35
87
  }
36
88
  }
37
89
  output.push("}");
@@ -1,26 +1,29 @@
1
- import { ArrayType, FieldType } from "../consts.js";
2
- import { capitalize, getName } from "./utils.js";
1
+ import { FieldType } from "../consts.js";
2
+ import { addHeader, capitalize, getTypeName } from "./utils.js";
3
3
  export function addStruct(header, fields, output) {
4
4
  const [name] = header.split(" ");
5
+ addHeader(`${name} (Struct)`, output);
5
6
  addStructTypeDefinition(name, fields, output);
6
7
  addStructCreateFunction(name, fields, output);
8
+ addStructCopyFunction(name, fields, output);
9
+ addStructCloneFunction(name, output);
7
10
  addStructZeroFunction(name, fields, output);
8
11
  }
9
12
  function addStructTypeDefinition(name, fields, output) {
10
13
  output.push(`export type ${capitalize(name)} = {`);
11
14
  for (const field of fields) {
12
15
  const [fieldName, fieldType, fieldArrayType] = field.split(" ");
13
- output.push(` ${fieldName}: ${getName(fieldType, fieldArrayType)}`);
16
+ output.push(` ${fieldName}: ${getTypeName(fieldType, fieldArrayType)}`);
14
17
  }
15
18
  output.push("}");
16
19
  }
17
20
  function addStructCreateFunction(name, fields, output) {
18
21
  output.push("");
19
22
  output.push(`/** Create a new ${capitalize(name)} object. */`);
20
- output.push(`export function create${capitalize(name)}(): ${capitalize(name)} {`);
21
- output.push(` const obj = Object.create(null)`);
23
+ output.push(`export function create${capitalize(name)}() {`);
24
+ output.push(` const obj: ${getTypeName(name)} = Object.create(null)`);
22
25
  for (const field of fields) {
23
- const [fieldName, fieldType, fieldArrayType, fieldArrayLength = ""] = field.split(" ");
26
+ const [fieldName, fieldType, fieldArrayType] = field.split(" ");
24
27
  switch (fieldType) {
25
28
  case FieldType.STRING:
26
29
  output.push(` obj.${fieldName} = ""`);
@@ -32,24 +35,7 @@ function addStructCreateFunction(name, fields, output) {
32
35
  output.push(` obj.${fieldName} = false`);
33
36
  break;
34
37
  case FieldType.ARRAY:
35
- {
36
- switch (fieldArrayType) {
37
- case ArrayType.STRING:
38
- output.push(` obj.${fieldName} = new Array<string>(${fieldArrayLength})${fieldArrayLength ? '.fill("")' : ""}`);
39
- break;
40
- case ArrayType.NUMBER:
41
- output.push(` obj.${fieldName} = new Array<number>(${fieldArrayLength})${fieldArrayLength ? ".fill(0)" : ""}`);
42
- break;
43
- case ArrayType.BOOLEAN:
44
- output.push(` obj.${fieldName} = new Array<boolean>(${fieldArrayLength})${fieldArrayLength ? ".fill(false)" : ""}`);
45
- break;
46
- default:
47
- output.push(` obj.${fieldName} = new Array<${getName(fieldArrayType)}>()`);
48
- }
49
- }
50
- break;
51
- case FieldType.SET:
52
- output.push(` obj.${fieldName} = new Set<${getName(fieldArrayType)}>()`);
38
+ output.push(` obj.${fieldName} = new Array<${getTypeName(fieldArrayType)}>()`);
53
39
  break;
54
40
  default: {
55
41
  output.push(` obj.${fieldName} = create${capitalize(fieldType)}()`);
@@ -59,12 +45,31 @@ function addStructCreateFunction(name, fields, output) {
59
45
  output.push(" return obj");
60
46
  output.push("}");
61
47
  }
48
+ function addStructCopyFunction(name, fields, output) {
49
+ output.push("");
50
+ output.push(`/** Copy the values of ${capitalize(name)} object b into ${capitalize(name)} object a. */`);
51
+ output.push(`export function copy${capitalize(name)}(a: ${getTypeName(name)}, b: ${getTypeName(name)}) {`);
52
+ for (const field of fields) {
53
+ const [fieldName] = field.split(" ");
54
+ output.push(` a.${fieldName} = b.${fieldName}`);
55
+ }
56
+ output.push("}");
57
+ }
58
+ function addStructCloneFunction(name, output) {
59
+ output.push("");
60
+ output.push(`/** Clone the given ${capitalize(name)} object. */`);
61
+ output.push(`export function clone${capitalize(name)}(obj: ${getTypeName(name)}) {`);
62
+ output.push(` const clone = create${capitalize(name)}()`);
63
+ output.push(` copy${capitalize(name)}(clone, obj)`);
64
+ output.push(" return clone");
65
+ output.push("}");
66
+ }
62
67
  function addStructZeroFunction(name, fields, output) {
63
68
  output.push("");
64
69
  output.push(`/** Zero the given ${capitalize(name)} object. */`);
65
- output.push(`export function zero${capitalize(name)}(obj: ${capitalize(name)}) {`);
70
+ output.push(`export function zero${capitalize(name)}(obj: ${getTypeName(name)}) {`);
66
71
  for (const field of fields) {
67
- const [fieldName, fieldType, fieldArrayType, fieldArrayLength] = field.split(" ");
72
+ const [fieldName, fieldType] = field.split(" ");
68
73
  switch (fieldType) {
69
74
  case FieldType.STRING:
70
75
  output.push(` obj.${fieldName} = ""`);
@@ -76,24 +81,7 @@ function addStructZeroFunction(name, fields, output) {
76
81
  output.push(` obj.${fieldName} = false`);
77
82
  break;
78
83
  case FieldType.ARRAY:
79
- {
80
- switch (fieldArrayType) {
81
- case ArrayType.STRING:
82
- output.push(` obj.${fieldName}.${fieldArrayLength ? 'fill("")' : "length = 0"}`);
83
- break;
84
- case ArrayType.NUMBER:
85
- output.push(` obj.${fieldName}.${fieldArrayLength ? "fill(0)" : "length = 0"}`);
86
- break;
87
- case ArrayType.BOOLEAN:
88
- output.push(` obj.${fieldName}.${fieldArrayLength ? "fill(false)" : "length = 0"}`);
89
- break;
90
- default:
91
- output.push(` obj.${fieldName}.length = 0`);
92
- }
93
- }
94
- break;
95
- case FieldType.SET:
96
- output.push(` obj.${fieldName}.clear()`);
84
+ output.push(` obj.${fieldName}.length = 0`);
97
85
  break;
98
86
  default:
99
87
  output.push(` zero${capitalize(fieldType)}(obj.${fieldName})`);
package/dist/lib/utils.js CHANGED
@@ -1,8 +1,17 @@
1
1
  import { FieldType, Type } from "../consts.js";
2
+ export function addHeader(name, output) {
3
+ output.push("");
4
+ output.push("/*");
5
+ output.push(` * ${"-".repeat(50)}`);
6
+ output.push(` * ${name}`);
7
+ output.push(` * ${"-".repeat(50)}`);
8
+ output.push(" */");
9
+ output.push("");
10
+ }
2
11
  /**
3
12
  * Get the name based on the type of the data structure.
4
13
  */
5
- export function getName(type, arrayType = "") {
14
+ export function getTypeName(type, arrayType = "") {
6
15
  switch (type) {
7
16
  case Type.SOA:
8
17
  return "structure of arrays";
@@ -19,9 +28,7 @@ export function getName(type, arrayType = "") {
19
28
  case FieldType.BOOLEAN:
20
29
  return "boolean";
21
30
  case FieldType.ARRAY:
22
- return `Array<${getName(arrayType)}>`;
23
- case FieldType.SET:
24
- return `Set<${getName(arrayType)}>`;
31
+ return `Array<${getTypeName(arrayType)}>`;
25
32
  default:
26
33
  return capitalize(type);
27
34
  }
package/dist/main.js CHANGED
@@ -1,32 +1,31 @@
1
1
  #!/usr/bin/env node
2
+ var _a;
2
3
  import fs from "node:fs";
3
4
  import { Type } from "./consts.js";
4
5
  import { addArrayOfStructures } from "./lib/aos.js";
5
6
  import { addGroup } from "./lib/group.js";
6
7
  import { addStructureOfArrays } from "./lib/soa.js";
7
8
  import { addStruct } from "./lib/struct.js";
8
- import { getName } from "./lib/utils.js";
9
9
  const inputFile = process.argv[2];
10
- const outputFile = process.argv[3] || `${inputFile}.ts`;
10
+ const outputFile = process.argv[3] || `${inputFile.replace(/\.md$/, "")}.ts`;
11
11
  const input = fs.readFileSync(inputFile, "utf-8");
12
12
  const output = [];
13
13
  output.push("/*");
14
14
  output.push(` * Generated with game-data-gen on ${new Date().toLocaleString()}. DO NOT MODIFY THIS FILE!`);
15
15
  output.push(" */");
16
- const blocks = input.trim().split("\n\n");
16
+ const blocks = input
17
+ .split("\n")
18
+ .filter((line) => !line.startsWith("<!--"))
19
+ .join("\n")
20
+ .trim()
21
+ .split("\n\n");
17
22
  for (const block of blocks) {
18
- const fields = block.split("\n");
19
- const header = fields.shift();
23
+ const lines = block.split("\n");
24
+ const header = (_a = lines.shift()) === null || _a === void 0 ? void 0 : _a.replace(/^#\s*/, "");
20
25
  if (!header)
21
26
  continue;
22
- const [name, type] = header.split(" ");
23
- output.push("");
24
- output.push("/*");
25
- output.push(` * ${"-".repeat(50)}`);
26
- output.push(` * ${name} (${getName(type)})`);
27
- output.push(` * ${"-".repeat(50)}`);
28
- output.push(" */");
29
- output.push("");
27
+ const fields = lines.map((line) => line.replace(/^-\s*/, ""));
28
+ const [_, type] = header.split(" ");
30
29
  switch (type) {
31
30
  case Type.STRUCT:
32
31
  addStruct(header, fields, output);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "game-data-gen",
3
- "version": "2.2.0",
3
+ "version": "3.0.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -9,7 +9,7 @@
9
9
  "game-data-gen": "dist/main.js"
10
10
  },
11
11
  "scripts": {
12
- "start": "tsc && node dist/main.js tests/data",
12
+ "start": "tsc && node dist/main.js tests/data.md",
13
13
  "build": "biome check && tsc"
14
14
  },
15
15
  "repository": {