gdcore-tools 1.0.4 → 1.0.5

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.
@@ -1,15 +1,5 @@
1
1
  const { mapVector, mapFor } = require("../MapFor");
2
2
  const { caseSensitiveSlug } = require("../CaseSensitiveSlug");
3
- const {
4
- declareInstructionOrExpressionMetadata,
5
- declareBehaviorInstructionOrExpressionMetadata,
6
- declareEventsFunctionParameters,
7
- declareBehaviorMetadata,
8
- declareExtension,
9
- isBehaviorLifecycleEventsFunction,
10
- isExtensionLifecycleEventsFunction,
11
- declareBehaviorPropertiesInstructionAndExpressions,
12
- } = require("./MetadataDeclarationHelpers");
13
3
 
14
4
  const mangleName = (name) => {
15
5
  return caseSensitiveSlug(name, "_", []);
@@ -28,405 +18,434 @@ const getBehaviorFunctionCodeNamespace = (
28
18
  return codeNamespacePrefix + "__" + mangleName(eventsBasedBehavior.getName());
29
19
  };
30
20
 
31
- /**
32
- * Load all events functions of a project in extensions
33
- */
34
- const loadProjectEventsFunctionsExtensions = (
35
- project,
36
- eventsFunctionCodeWriter
37
- ) => {
38
- return Promise.all(
39
- // First pass: generate extensions from the events functions extensions,
40
- // without writing code for the functions. This is useful as events in functions
41
- // could be using other functions, which would not yet be available as
42
- // extensions.
43
- mapFor(0, project.getEventsFunctionsExtensionsCount(), (i) => {
44
- return loadProjectEventsFunctionsExtension(
45
- project,
46
- project.getEventsFunctionsExtensionAt(i),
47
- { skipCodeGeneration: true, eventsFunctionCodeWriter }
48
- );
49
- })
50
- ).then(() =>
51
- Promise.all(
52
- // Second pass: generate extensions, including code.
21
+ module.exports.makeLoader = (gd) => {
22
+ const {
23
+ declareInstructionOrExpressionMetadata,
24
+ declareBehaviorInstructionOrExpressionMetadata,
25
+ declareEventsFunctionParameters,
26
+ declareBehaviorMetadata,
27
+ declareExtension,
28
+ isBehaviorLifecycleEventsFunction,
29
+ isExtensionLifecycleEventsFunction,
30
+ declareBehaviorPropertiesInstructionAndExpressions,
31
+ } = require("./MetadataDeclarationHelpers")(gd);
32
+
33
+ const loader = {};
34
+
35
+ /**
36
+ * Load all events functions of a project in extensions
37
+ */
38
+ const loadProjectEventsFunctionsExtensions = (
39
+ project,
40
+ eventsFunctionCodeWriter
41
+ ) => {
42
+ return Promise.all(
43
+ // First pass: generate extensions from the events functions extensions,
44
+ // without writing code for the functions. This is useful as events in functions
45
+ // could be using other functions, which would not yet be available as
46
+ // extensions.
53
47
  mapFor(0, project.getEventsFunctionsExtensionsCount(), (i) => {
54
48
  return loadProjectEventsFunctionsExtension(
55
49
  project,
56
50
  project.getEventsFunctionsExtensionAt(i),
57
- {
58
- skipCodeGeneration: false,
59
- eventsFunctionCodeWriter,
60
- }
51
+ { skipCodeGeneration: true, eventsFunctionCodeWriter }
61
52
  );
62
53
  })
63
- )
64
- );
65
- };
66
- module.exports.loadProjectEventsFunctionsExtensions = loadProjectEventsFunctionsExtensions;
54
+ ).then(() =>
55
+ Promise.all(
56
+ // Second pass: generate extensions, including code.
57
+ mapFor(0, project.getEventsFunctionsExtensionsCount(), (i) => {
58
+ return loadProjectEventsFunctionsExtension(
59
+ project,
60
+ project.getEventsFunctionsExtensionAt(i),
61
+ {
62
+ skipCodeGeneration: false,
63
+ eventsFunctionCodeWriter,
64
+ }
65
+ );
66
+ })
67
+ )
68
+ );
69
+ };
70
+ loader.loadProjectEventsFunctionsExtensions =
71
+ loadProjectEventsFunctionsExtensions;
67
72
 
68
- const loadProjectEventsFunctionsExtension = (
69
- project,
70
- eventsFunctionsExtension,
71
- options
72
- ) => {
73
- return generateEventsFunctionExtension(
73
+ const loadProjectEventsFunctionsExtension = (
74
74
  project,
75
75
  eventsFunctionsExtension,
76
76
  options
77
- ).then((extension) => {
78
- _GD.JsPlatform.get().addNewExtension(extension);
79
- extension.delete();
80
- });
81
- };
82
-
83
- /**
84
- * Get the list of mandatory include files when using the
85
- * extension.
86
- */
87
- const getExtensionIncludeFiles = (
88
- project,
89
- eventsFunctionsExtension,
90
- options,
91
- codeNamespacePrefix
92
- ) => {
93
- return mapFor(0, eventsFunctionsExtension.getEventsFunctionsCount(), (i) => {
94
- const eventsFunction = eventsFunctionsExtension.getEventsFunctionAt(i);
95
-
96
- if (isExtensionLifecycleEventsFunction(eventsFunction.getName())) {
97
- const codeNamespace = getFreeFunctionCodeNamespace(
98
- eventsFunction,
99
- codeNamespacePrefix
100
- );
101
- const functionName = codeNamespace + ".func"; // TODO
102
-
103
- return options.eventsFunctionCodeWriter.getIncludeFileFor(functionName);
104
- }
105
-
106
- return null;
107
- }).filter(Boolean);
108
- };
109
-
110
- /**
111
- * Generate the code for the events based extension
112
- */
113
- const generateEventsFunctionExtension = (
114
- project,
115
- eventsFunctionsExtension,
116
- options
117
- ) => {
118
- const extension = new _GD.PlatformExtension();
119
- declareExtension(extension, eventsFunctionsExtension);
120
-
121
- const codeNamespacePrefix =
122
- "gdjs.evtsExt__" + mangleName(eventsFunctionsExtension.getName());
77
+ ) => {
78
+ return generateEventsFunctionExtension(
79
+ project,
80
+ eventsFunctionsExtension,
81
+ options
82
+ ).then((extension) => {
83
+ gd.JsPlatform.get().addNewExtension(extension);
84
+ extension.delete();
85
+ });
86
+ };
123
87
 
124
- const extensionIncludeFiles = getExtensionIncludeFiles(
88
+ /**
89
+ * Get the list of mandatory include files when using the
90
+ * extension.
91
+ */
92
+ const getExtensionIncludeFiles = (
125
93
  project,
126
94
  eventsFunctionsExtension,
127
95
  options,
128
96
  codeNamespacePrefix
129
- );
130
- const codeGenerationContext = {
131
- codeNamespacePrefix,
132
- extensionIncludeFiles,
133
- };
97
+ ) => {
98
+ return mapFor(
99
+ 0,
100
+ eventsFunctionsExtension.getEventsFunctionsCount(),
101
+ (i) => {
102
+ const eventsFunction = eventsFunctionsExtension.getEventsFunctionAt(i);
103
+
104
+ if (isExtensionLifecycleEventsFunction(eventsFunction.getName())) {
105
+ const codeNamespace = getFreeFunctionCodeNamespace(
106
+ eventsFunction,
107
+ codeNamespacePrefix
108
+ );
109
+ const functionName = codeNamespace + ".func"; // TODO
134
110
 
135
- return Promise.all(
136
- // Generate all behaviors and their functions
137
- mapVector(
138
- eventsFunctionsExtension.getEventsBasedBehaviors(),
139
- (eventsBasedBehavior) => {
140
- return generateBehavior(
141
- project,
142
- extension,
143
- eventsFunctionsExtension,
144
- eventsBasedBehavior,
145
- options,
146
- codeGenerationContext
147
- );
148
- }
149
- )
150
- )
151
- .then(() =>
152
- // Generate all free functions
153
- Promise.all(
154
- mapFor(0, eventsFunctionsExtension.getEventsFunctionsCount(), (i) => {
155
- const eventsFunction = eventsFunctionsExtension.getEventsFunctionAt(
156
- i
111
+ return options.eventsFunctionCodeWriter.getIncludeFileFor(
112
+ functionName
157
113
  );
158
- return generateFreeFunction(
114
+ }
115
+
116
+ return null;
117
+ }
118
+ ).filter(Boolean);
119
+ };
120
+
121
+ /**
122
+ * Generate the code for the events based extension
123
+ */
124
+ const generateEventsFunctionExtension = (
125
+ project,
126
+ eventsFunctionsExtension,
127
+ options
128
+ ) => {
129
+ const extension = new gd.PlatformExtension();
130
+ declareExtension(extension, eventsFunctionsExtension);
131
+
132
+ const codeNamespacePrefix =
133
+ "gdjs.evtsExt__" + mangleName(eventsFunctionsExtension.getName());
134
+
135
+ const extensionIncludeFiles = getExtensionIncludeFiles(
136
+ project,
137
+ eventsFunctionsExtension,
138
+ options,
139
+ codeNamespacePrefix
140
+ );
141
+ const codeGenerationContext = {
142
+ codeNamespacePrefix,
143
+ extensionIncludeFiles,
144
+ };
145
+
146
+ return Promise.all(
147
+ // Generate all behaviors and their functions
148
+ mapVector(
149
+ eventsFunctionsExtension.getEventsBasedBehaviors(),
150
+ (eventsBasedBehavior) => {
151
+ return generateBehavior(
159
152
  project,
160
153
  extension,
161
154
  eventsFunctionsExtension,
162
- eventsFunction,
155
+ eventsBasedBehavior,
163
156
  options,
164
157
  codeGenerationContext
165
158
  );
166
- })
159
+ }
167
160
  )
168
161
  )
169
- .then(() => extension);
170
- };
162
+ .then(() =>
163
+ // Generate all free functions
164
+ Promise.all(
165
+ mapFor(0, eventsFunctionsExtension.getEventsFunctionsCount(), (i) => {
166
+ const eventsFunction =
167
+ eventsFunctionsExtension.getEventsFunctionAt(i);
168
+ return generateFreeFunction(
169
+ project,
170
+ extension,
171
+ eventsFunctionsExtension,
172
+ eventsFunction,
173
+ options,
174
+ codeGenerationContext
175
+ );
176
+ })
177
+ )
178
+ )
179
+ .then(() => extension);
180
+ };
171
181
 
172
- const generateFreeFunction = (
173
- project,
174
- extension,
175
- eventsFunctionsExtension,
176
- eventsFunction,
177
- options,
178
- codeGenerationContext
179
- ) => {
180
- const instructionOrExpression = declareInstructionOrExpressionMetadata(
182
+ const generateFreeFunction = (
183
+ project,
181
184
  extension,
182
185
  eventsFunctionsExtension,
183
- eventsFunction
184
- );
185
- // By convention, first parameter is always the Runtime Scene.
186
- instructionOrExpression.addCodeOnlyParameter("currentScene", "");
187
- declareEventsFunctionParameters(eventsFunction, instructionOrExpression);
188
-
189
- // Hide "lifecycle" functions as they are called automatically by
190
- // the game engine.
191
- if (isExtensionLifecycleEventsFunction(eventsFunction.getName())) {
192
- instructionOrExpression.setHidden();
193
- }
194
-
195
- const codeNamespace = getFreeFunctionCodeNamespace(
196
186
  eventsFunction,
197
- codeGenerationContext.codeNamespacePrefix
198
- );
199
- const functionName = codeNamespace + ".func";
200
-
201
- const codeExtraInformation = instructionOrExpression.getCodeExtraInformation();
202
- codeExtraInformation
203
- .setIncludeFile(
204
- options.eventsFunctionCodeWriter.getIncludeFileFor(functionName)
205
- )
206
- .setFunctionName(functionName);
207
-
208
- // Always include the extension include files when using a free function.
209
- codeGenerationContext.extensionIncludeFiles.forEach((includeFile) => {
210
- codeExtraInformation.addIncludeFile(includeFile);
211
- });
212
-
213
- if (!options.skipCodeGeneration) {
214
- const includeFiles = new _GD.SetString();
215
- const eventsFunctionsExtensionCodeGenerator = new _GD.EventsFunctionsExtensionCodeGenerator(
216
- project
217
- );
218
- const code = eventsFunctionsExtensionCodeGenerator.generateFreeEventsFunctionCompleteCode(
219
- eventsFunction,
220
- codeNamespace,
221
- includeFiles,
222
- // For now, always generate functions for runtime (this disables
223
- // generation of profiling for groups (see EventsCodeGenerator))
224
- // as extensions generated can be used either for preview or export.
225
- true
226
- );
227
-
228
- // Add any include file required by the function to the list
229
- // of include files for this function (so that when used, the "dependencies"
230
- // are transitively included).
231
- includeFiles
232
- .toNewVectorString()
233
- .toJSArray()
234
- .forEach((includeFile) => {
235
- codeExtraInformation.addIncludeFile(includeFile);
236
- });
237
-
238
- includeFiles.delete();
239
-
240
- return options.eventsFunctionCodeWriter.writeFunctionCode(
241
- functionName,
242
- code
187
+ options,
188
+ codeGenerationContext
189
+ ) => {
190
+ const instructionOrExpression = declareInstructionOrExpressionMetadata(
191
+ extension,
192
+ eventsFunctionsExtension,
193
+ eventsFunction
243
194
  );
244
- } else {
245
- // Skip code generation if no events function writer is provided.
246
- // This is the case during the "first pass", where all events functions extensions
247
- // are loaded as extensions but not code generated, as events in functions could
248
- // themselves be using functions that are not yet available in extensions.
249
- return Promise.resolve();
250
- }
251
- };
195
+ // By convention, first parameter is always the Runtime Scene.
196
+ instructionOrExpression.addCodeOnlyParameter("currentScene", "");
197
+ declareEventsFunctionParameters(eventsFunction, instructionOrExpression);
252
198
 
253
- function generateBehavior(
254
- project,
255
- extension,
256
- eventsFunctionsExtension,
257
- eventsBasedBehavior,
258
- options,
259
- codeGenerationContext
260
- ) {
261
- const behaviorMetadata = declareBehaviorMetadata(
262
- extension,
263
- eventsBasedBehavior
264
- );
265
-
266
- const eventsFunctionsContainer = eventsBasedBehavior.getEventsFunctions();
267
- const codeNamespace = getBehaviorFunctionCodeNamespace(
268
- eventsBasedBehavior,
269
- codeGenerationContext.codeNamespacePrefix
270
- );
271
- const includeFile = options.eventsFunctionCodeWriter.getIncludeFileFor(
272
- codeNamespace
273
- );
274
-
275
- behaviorMetadata.setIncludeFile(includeFile);
276
-
277
- // Always include the extension include files when using a behavior.
278
- codeGenerationContext.extensionIncludeFiles.forEach((includeFile) => {
279
- behaviorMetadata.addIncludeFile(includeFile);
280
- });
281
-
282
- return Promise.resolve().then(() => {
283
- const behaviorMethodMangledNames = new _GD.MapStringString();
199
+ // Hide "lifecycle" functions as they are called automatically by
200
+ // the game engine.
201
+ if (isExtensionLifecycleEventsFunction(eventsFunction.getName())) {
202
+ instructionOrExpression.setHidden();
203
+ }
284
204
 
285
- // Declare the instructions/expressions for properties
286
- declareBehaviorPropertiesInstructionAndExpressions(
287
- behaviorMetadata,
288
- eventsBasedBehavior
205
+ const codeNamespace = getFreeFunctionCodeNamespace(
206
+ eventsFunction,
207
+ codeGenerationContext.codeNamespacePrefix
289
208
  );
209
+ const functionName = codeNamespace + ".func";
290
210
 
291
- // Declare all the behavior functions
292
- mapFor(0, eventsFunctionsContainer.getEventsFunctionsCount(), (i) => {
293
- const eventsFunction = eventsFunctionsContainer.getEventsFunctionAt(i);
294
-
295
- const eventsFunctionMangledName = mangleName(eventsFunction.getName());
296
- behaviorMethodMangledNames.set(
297
- eventsFunction.getName(),
298
- eventsFunctionMangledName
299
- );
300
-
301
- const instructionOrExpression = declareBehaviorInstructionOrExpressionMetadata(
302
- behaviorMetadata,
303
- eventsBasedBehavior,
304
- eventsFunction
305
- );
306
- declareEventsFunctionParameters(eventsFunction, instructionOrExpression);
307
-
308
- // Hide "lifecycle" methods as they are called automatically by
309
- // the game engine.
310
- if (isBehaviorLifecycleEventsFunction(eventsFunction.getName())) {
311
- instructionOrExpression.setHidden();
312
- }
211
+ const codeExtraInformation =
212
+ instructionOrExpression.getCodeExtraInformation();
213
+ codeExtraInformation
214
+ .setIncludeFile(
215
+ options.eventsFunctionCodeWriter.getIncludeFileFor(functionName)
216
+ )
217
+ .setFunctionName(functionName);
313
218
 
314
- const codeExtraInformation = instructionOrExpression.getCodeExtraInformation();
315
- codeExtraInformation
316
- .setIncludeFile(includeFile)
317
- .setFunctionName(eventsFunctionMangledName);
219
+ // Always include the extension include files when using a free function.
220
+ codeGenerationContext.extensionIncludeFiles.forEach((includeFile) => {
221
+ codeExtraInformation.addIncludeFile(includeFile);
318
222
  });
319
223
 
320
- // Generate code for the behavior and its methods
321
224
  if (!options.skipCodeGeneration) {
322
- const includeFiles = new _GD.SetString();
323
- const behaviorCodeGenerator = new _GD.BehaviorCodeGenerator(project);
324
- const code = behaviorCodeGenerator.generateRuntimeBehaviorCompleteCode(
325
- eventsFunctionsExtension.getName(),
326
- eventsBasedBehavior,
327
- codeNamespace,
328
- behaviorMethodMangledNames,
329
- includeFiles,
330
-
331
- // For now, always generate functions for runtime (this disables
332
- // generation of profiling for groups (see EventsCodeGenerator))
333
- // as extensions generated can be used either for preview or export.
334
- true
335
- );
336
- behaviorCodeGenerator.delete();
337
- behaviorMethodMangledNames.delete();
225
+ const includeFiles = new gd.SetString();
226
+ const eventsFunctionsExtensionCodeGenerator =
227
+ new gd.EventsFunctionsExtensionCodeGenerator(project);
228
+ const code =
229
+ eventsFunctionsExtensionCodeGenerator.generateFreeEventsFunctionCompleteCode(
230
+ eventsFunction,
231
+ codeNamespace,
232
+ includeFiles,
233
+ // For now, always generate functions for runtime (this disables
234
+ // generation of profiling for groups (see EventsCodeGenerator))
235
+ // as extensions generated can be used either for preview or export.
236
+ true
237
+ );
338
238
 
339
- // Add any include file required by the functions to the list
340
- // of include files for this behavior (so that when used, the "dependencies"
239
+ // Add any include file required by the function to the list
240
+ // of include files for this function (so that when used, the "dependencies"
341
241
  // are transitively included).
342
242
  includeFiles
343
243
  .toNewVectorString()
344
244
  .toJSArray()
345
245
  .forEach((includeFile) => {
346
- behaviorMetadata.addIncludeFile(includeFile);
246
+ codeExtraInformation.addIncludeFile(includeFile);
347
247
  });
348
248
 
349
249
  includeFiles.delete();
350
250
 
351
- return options.eventsFunctionCodeWriter.writeBehaviorCode(
352
- codeNamespace,
251
+ return options.eventsFunctionCodeWriter.writeFunctionCode(
252
+ functionName,
353
253
  code
354
254
  );
355
255
  } else {
356
- // Skip code generation
357
- behaviorMethodMangledNames.delete();
256
+ // Skip code generation if no events function writer is provided.
257
+ // This is the case during the "first pass", where all events functions extensions
258
+ // are loaded as extensions but not code generated, as events in functions could
259
+ // themselves be using functions that are not yet available in extensions.
358
260
  return Promise.resolve();
359
261
  }
360
- });
361
- }
362
-
363
- /**
364
- * Unload all extensions providing events functions of a project
365
- */
366
- const unloadProjectEventsFunctionsExtensions = (project) => {
367
- return Promise.all(
368
- mapFor(0, project.getEventsFunctionsExtensionsCount(), (i) => {
369
- _GD.JsPlatform.get().removeExtension(
370
- project.getEventsFunctionsExtensionAt(i).getName()
262
+ };
263
+
264
+ function generateBehavior(
265
+ project,
266
+ extension,
267
+ eventsFunctionsExtension,
268
+ eventsBasedBehavior,
269
+ options,
270
+ codeGenerationContext
271
+ ) {
272
+ const behaviorMetadata = declareBehaviorMetadata(
273
+ extension,
274
+ eventsBasedBehavior
275
+ );
276
+
277
+ const eventsFunctionsContainer = eventsBasedBehavior.getEventsFunctions();
278
+ const codeNamespace = getBehaviorFunctionCodeNamespace(
279
+ eventsBasedBehavior,
280
+ codeGenerationContext.codeNamespacePrefix
281
+ );
282
+ const includeFile =
283
+ options.eventsFunctionCodeWriter.getIncludeFileFor(codeNamespace);
284
+
285
+ behaviorMetadata.setIncludeFile(includeFile);
286
+
287
+ // Always include the extension include files when using a behavior.
288
+ codeGenerationContext.extensionIncludeFiles.forEach((includeFile) => {
289
+ behaviorMetadata.addIncludeFile(includeFile);
290
+ });
291
+
292
+ return Promise.resolve().then(() => {
293
+ const behaviorMethodMangledNames = new gd.MapStringString();
294
+
295
+ // Declare the instructions/expressions for properties
296
+ declareBehaviorPropertiesInstructionAndExpressions(
297
+ behaviorMetadata,
298
+ eventsBasedBehavior
371
299
  );
372
- })
373
- );
374
- };
375
- module.exports.unloadProjectEventsFunctionsExtensions = unloadProjectEventsFunctionsExtensions;
376
-
377
- /**
378
- * Given metadata about an instruction or an expression, tells if this was created
379
- * from an event function.
380
- */
381
- const isAnEventFunctionMetadata = (instructionOrExpression) => {
382
- const parametersCount = instructionOrExpression.getParametersCount();
383
- if (parametersCount <= 0) return false;
384
-
385
- return (
386
- instructionOrExpression.getParameter(parametersCount - 1).getType() ===
387
- "eventsFunctionContext"
388
- );
389
- };
390
- module.exports.isAnEventFunctionMetadata = isAnEventFunctionMetadata;
391
-
392
- /**
393
- * Get back the name a function from its type.
394
- * See also getFreeEventsFunctionType for the reverse operation.
395
- */
396
- const getFunctionNameFromType = (type) => {
397
- const parts = type.split("::");
398
- if (!parts.length)
300
+
301
+ // Declare all the behavior functions
302
+ mapFor(0, eventsFunctionsContainer.getEventsFunctionsCount(), (i) => {
303
+ const eventsFunction = eventsFunctionsContainer.getEventsFunctionAt(i);
304
+
305
+ const eventsFunctionMangledName = mangleName(eventsFunction.getName());
306
+ behaviorMethodMangledNames.set(
307
+ eventsFunction.getName(),
308
+ eventsFunctionMangledName
309
+ );
310
+
311
+ const instructionOrExpression =
312
+ declareBehaviorInstructionOrExpressionMetadata(
313
+ behaviorMetadata,
314
+ eventsBasedBehavior,
315
+ eventsFunction
316
+ );
317
+ declareEventsFunctionParameters(
318
+ eventsFunction,
319
+ instructionOrExpression
320
+ );
321
+
322
+ // Hide "lifecycle" methods as they are called automatically by
323
+ // the game engine.
324
+ if (isBehaviorLifecycleEventsFunction(eventsFunction.getName())) {
325
+ instructionOrExpression.setHidden();
326
+ }
327
+
328
+ const codeExtraInformation =
329
+ instructionOrExpression.getCodeExtraInformation();
330
+ codeExtraInformation
331
+ .setIncludeFile(includeFile)
332
+ .setFunctionName(eventsFunctionMangledName);
333
+ });
334
+
335
+ // Generate code for the behavior and its methods
336
+ if (!options.skipCodeGeneration) {
337
+ const includeFiles = new gd.SetString();
338
+ const behaviorCodeGenerator = new gd.BehaviorCodeGenerator(project);
339
+ const code = behaviorCodeGenerator.generateRuntimeBehaviorCompleteCode(
340
+ eventsFunctionsExtension.getName(),
341
+ eventsBasedBehavior,
342
+ codeNamespace,
343
+ behaviorMethodMangledNames,
344
+ includeFiles,
345
+
346
+ // For now, always generate functions for runtime (this disables
347
+ // generation of profiling for groups (see EventsCodeGenerator))
348
+ // as extensions generated can be used either for preview or export.
349
+ true
350
+ );
351
+ behaviorCodeGenerator.delete();
352
+ behaviorMethodMangledNames.delete();
353
+
354
+ // Add any include file required by the functions to the list
355
+ // of include files for this behavior (so that when used, the "dependencies"
356
+ // are transitively included).
357
+ includeFiles
358
+ .toNewVectorString()
359
+ .toJSArray()
360
+ .forEach((includeFile) => {
361
+ behaviorMetadata.addIncludeFile(includeFile);
362
+ });
363
+
364
+ includeFiles.delete();
365
+
366
+ return options.eventsFunctionCodeWriter.writeBehaviorCode(
367
+ codeNamespace,
368
+ code
369
+ );
370
+ } else {
371
+ // Skip code generation
372
+ behaviorMethodMangledNames.delete();
373
+ return Promise.resolve();
374
+ }
375
+ });
376
+ }
377
+
378
+ /**
379
+ * Unload all extensions providing events functions of a project
380
+ */
381
+ const unloadProjectEventsFunctionsExtensions = (project) => {
382
+ return Promise.all(
383
+ mapFor(0, project.getEventsFunctionsExtensionsCount(), (i) => {
384
+ gd.JsPlatform.get().removeExtension(
385
+ project.getEventsFunctionsExtensionAt(i).getName()
386
+ );
387
+ })
388
+ );
389
+ };
390
+ loader.unloadProjectEventsFunctionsExtensions =
391
+ unloadProjectEventsFunctionsExtensions;
392
+
393
+ /**
394
+ * Given metadata about an instruction or an expression, tells if this was created
395
+ * from an event function.
396
+ */
397
+ const isAnEventFunctionMetadata = (instructionOrExpression) => {
398
+ const parametersCount = instructionOrExpression.getParametersCount();
399
+ if (parametersCount <= 0) return false;
400
+
401
+ return (
402
+ instructionOrExpression.getParameter(parametersCount - 1).getType() ===
403
+ "eventsFunctionContext"
404
+ );
405
+ };
406
+ loader.isAnEventFunctionMetadata = isAnEventFunctionMetadata;
407
+
408
+ /**
409
+ * Get back the name a function from its type.
410
+ * See also getFreeEventsFunctionType for the reverse operation.
411
+ */
412
+ const getFunctionNameFromType = (type) => {
413
+ const parts = type.split("::");
414
+ if (!parts.length)
415
+ return {
416
+ name: "",
417
+ behaviorName: "",
418
+ extensionName: "",
419
+ };
420
+
399
421
  return {
400
- name: "",
401
- behaviorName: "",
402
- extensionName: "",
422
+ name: parts[parts.length - 1],
423
+ behaviorName: parts.length > 2 ? parts[1] : undefined,
424
+ extensionName: parts[0],
403
425
  };
404
-
405
- return {
406
- name: parts[parts.length - 1],
407
- behaviorName: parts.length > 2 ? parts[1] : undefined,
408
- extensionName: parts[0],
409
426
  };
427
+ loader.getFunctionNameFromType = getFunctionNameFromType;
428
+
429
+ /**
430
+ * Get the type of a Events Function.
431
+ * See also getFunctionNameFromType for the reverse operation.
432
+ */
433
+ const getFreeEventsFunctionType = (extensionName, eventsFunction) => {
434
+ return extensionName + "::" + eventsFunction.getName();
435
+ };
436
+ loader.getFreeEventsFunctionType = getFreeEventsFunctionType;
437
+
438
+ /**
439
+ * Return the index of the first parameter to be shown to the user:
440
+ * * 0 for a behavior "method",
441
+ * * 1 for a free function (as the first parameter is by convention the runtimeScene).
442
+ */
443
+ const getParametersIndexOffset = (isEventsBasedBehaviorMethod) => {
444
+ return isEventsBasedBehaviorMethod
445
+ ? 0 /*In the case of a behavior events function, the first two parameters are by convention the "Object" and "Behavior" */
446
+ : 1; /*In the case of a free events function (i.e: not tied to a behavior), the first parameter is by convention the current scene and is not shown.*/
447
+ };
448
+ loader.getParametersIndexOffset = getParametersIndexOffset;
449
+
450
+ return loader;
410
451
  };
411
- module.exports.getFunctionNameFromType = getFunctionNameFromType;
412
-
413
- /**
414
- * Get the type of a Events Function.
415
- * See also getFunctionNameFromType for the reverse operation.
416
- */
417
- const getFreeEventsFunctionType = (extensionName, eventsFunction) => {
418
- return extensionName + "::" + eventsFunction.getName();
419
- };
420
- module.exports.getFreeEventsFunctionType = getFreeEventsFunctionType;
421
-
422
- /**
423
- * Return the index of the first parameter to be shown to the user:
424
- * * 0 for a behavior "method",
425
- * * 1 for a free function (as the first parameter is by convention the runtimeScene).
426
- */
427
- const getParametersIndexOffset = (isEventsBasedBehaviorMethod) => {
428
- return isEventsBasedBehaviorMethod
429
- ? 0 /*In the case of a behavior events function, the first two parameters are by convention the "Object" and "Behavior" */
430
- : 1; /*In the case of a free events function (i.e: not tied to a behavior), the first parameter is by convention the current scene and is not shown.*/
431
- };
432
- module.exports.getParametersIndexOffset = getParametersIndexOffset;