mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-21 01:25:32 -04:00
3646 lines
123 KiB
JavaScript
3646 lines
123 KiB
JavaScript
const initializeGDevelopJs = require('../../Binaries/embuild/GDevelop.js/libGD.js');
|
|
const {
|
|
generateCompiledEventsForEventsFunction,
|
|
generateCompiledEventsFromSerializedEvents,
|
|
generateCompiledEventsForSerializedEventsBasedExtension,
|
|
} = require('../TestUtils/CodeGenerationHelpers.js');
|
|
const { makeMinimalGDJSMock } = require('../TestUtils/GDJSMocks');
|
|
const { makeTestExtensions } = require('../TestUtils/TestExtensions');
|
|
|
|
describe('libGD.js - GDJS Async Code Generation integration tests', function () {
|
|
let gd = null;
|
|
beforeAll(async () => {
|
|
gd = await initializeGDevelopJs();
|
|
makeTestExtensions(gd);
|
|
});
|
|
|
|
describe('Basics', () => {
|
|
it('generates a working function with asynchronous actions', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['SuccessVariable', '+', '1'],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const runCompiledEvents = generateCompiledEventsFromSerializedEvents(
|
|
gd,
|
|
eventsSerializerElement
|
|
);
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
runCompiledEvents(gdjs, runtimeScene, []);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Process the tasks (but the task is not finished yet).
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(
|
|
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
|
|
).toBe(1);
|
|
});
|
|
|
|
it('generates a working function with an optionally asynchronous action, that is not set as async', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value: 'FakeOptionallyAsyncAction::DoOptionallyAsyncAction',
|
|
},
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['SuccessVariable', '+', '1'],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const runCompiledEvents = generateCompiledEventsFromSerializedEvents(
|
|
gd,
|
|
eventsSerializerElement
|
|
);
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
runCompiledEvents(gdjs, runtimeScene, []);
|
|
|
|
// Nothing is async, the actions are all executed.
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(true);
|
|
});
|
|
|
|
it('generates a working function with an optionally asynchronous action, that is set as async', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value: 'FakeOptionallyAsyncAction::DoOptionallyAsyncAction',
|
|
await: true,
|
|
},
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['SuccessVariable', '+', '1'],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const runCompiledEvents = generateCompiledEventsFromSerializedEvents(
|
|
gd,
|
|
eventsSerializerElement
|
|
);
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
runCompiledEvents(gdjs, runtimeScene, []);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Process the tasks (but the task is not finished yet).
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(
|
|
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
|
|
).toBe(1);
|
|
});
|
|
|
|
it('generates a working function with two asynchronous actions', function () {
|
|
// Create events using the Trigger Once condition.
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['SuccessVariable', '+', '1'],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['SuccessVariable', '+', '2'],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const runCompiledEvents = generateCompiledEventsFromSerializedEvents(
|
|
gd,
|
|
eventsSerializerElement
|
|
);
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
runCompiledEvents(gdjs, runtimeScene, []);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Process the tasks (but the task is not finished yet).
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(
|
|
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
|
|
).toBe(1);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(
|
|
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
|
|
).toBe(3);
|
|
});
|
|
|
|
it('generates a working function with asynchronous actions referring to the function arguments', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: [
|
|
'SuccessVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
runCompiledEvents(gdjs, runtimeScene, [5]);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Process the tasks (but the task is not finished yet).
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(
|
|
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
|
|
).toBe(5);
|
|
});
|
|
});
|
|
|
|
describe('With objects', () => {
|
|
test('one asynchronous action', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const runCompiledEvents = generateCompiledEventsFromSerializedEvents(
|
|
gd,
|
|
eventsSerializerElement,
|
|
{
|
|
parameterTypes: { IncreaseValue: 'number', MyParamObject: 'object' },
|
|
}
|
|
);
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA = runtimeScene.createObject('MyObjectA');
|
|
const myObjectALists = gdjs.Hashtable.newFrom({ MyObjectA: [myObjectA] });
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectALists]);
|
|
expect(myObjectA.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
|
|
// Process the tasks (but the task is not finished yet).
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(myObjectA.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(myObjectA.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
});
|
|
|
|
test('two asynchronous actions and a condition before the async actions filtering objects', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'TestVariable', '=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
],
|
|
events: [
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value: 'Wait',
|
|
},
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectALists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2],
|
|
});
|
|
myObjectA2.getVariables().get('TestVariable').setNumber(1);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectALists]);
|
|
|
|
// Initial state is unchanged because the first wait task is not done.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Initial state is still unchanged because the condition ran but the second wait task
|
|
// is not done.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Only the "myObjectA2" instance was modified by the action.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
6
|
|
);
|
|
});
|
|
|
|
test('two asynchronous actions and a condition in between filtering objects', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
],
|
|
events: [
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'TestVariable', '=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value: 'Wait',
|
|
},
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectALists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2],
|
|
});
|
|
myObjectA2.getVariables().get('TestVariable').setNumber(1);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectALists]);
|
|
|
|
// Initial state is unchanged because the first wait task is not done.
|
|
expect(myObjectA1.getVariables().has('TestVariable')).toBe(false);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Initial state is still unchanged because the condition ran but the second wait task
|
|
// is not done.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Only the "myObjectA2" instance was modified by the action.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
6
|
|
);
|
|
});
|
|
|
|
test('two asynchronous actions and conditions filtering objects in sub events after a filtering outside the async context', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
// Do a first filtering.
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'TestVariable', '>=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
],
|
|
events: [
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
// Filter with the more precise condition first.
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'TestVariable', '>=', '3'],
|
|
},
|
|
],
|
|
actions: [],
|
|
events: [
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
// Filter with a less precise condition then.
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'>=',
|
|
'2',
|
|
],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value: 'Wait',
|
|
},
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA4 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectALists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3, myObjectA4],
|
|
});
|
|
myObjectA2.getVariables().get('TestVariable').setNumber(1);
|
|
myObjectA3.getVariables().get('TestVariable').setNumber(2);
|
|
myObjectA4.getVariables().get('TestVariable').setNumber(3);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectALists]);
|
|
|
|
// Initial state is unchanged because the first wait task is not done.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
2
|
|
);
|
|
expect(myObjectA4.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Initial state is still unchanged because the conditions ran but the second wait task
|
|
// is not done.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
2
|
|
);
|
|
expect(myObjectA4.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Only the "myObjectA3" instance was modified by the action.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
2
|
|
);
|
|
expect(myObjectA4.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3 + 5
|
|
);
|
|
});
|
|
|
|
test('two asynchronous actions and conditions filtering objects in sub events after a filtering outside the async context, with a third condition having its result discarded', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
// Do a first filtering.
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'TestVariable', '>=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
],
|
|
events: [
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
// Filter with the more precise condition first.
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'TestVariable', '>=', '3'],
|
|
},
|
|
],
|
|
actions: [],
|
|
events: [
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
// Filter with a less precise condition then.
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'>=',
|
|
'2',
|
|
],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value: 'Wait',
|
|
},
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
// Add an event to prevent optimisation (reuse of the same objects list)
|
|
// in the previous event.
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'>=',
|
|
'0',
|
|
],
|
|
},
|
|
],
|
|
actions: [],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA4 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectALists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3, myObjectA4],
|
|
});
|
|
myObjectA2.getVariables().get('TestVariable').setNumber(1);
|
|
myObjectA3.getVariables().get('TestVariable').setNumber(2);
|
|
myObjectA4.getVariables().get('TestVariable').setNumber(3);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectALists]);
|
|
|
|
// Initial state is unchanged because the first wait task is not done.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
2
|
|
);
|
|
expect(myObjectA4.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Initial state is still unchanged because the conditions ran but the second wait task
|
|
// is not done.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
2
|
|
);
|
|
expect(myObjectA4.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Only the "myObjectA3" instance was modified by the action.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
2
|
|
);
|
|
expect(myObjectA4.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3 + 5
|
|
);
|
|
});
|
|
|
|
test('two asynchronous actions and two conditions in different sub-events in between filtering objects, with a third condition having its result discarded', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
],
|
|
events: [
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'TestVariable', '>=', '2'],
|
|
},
|
|
],
|
|
actions: [],
|
|
events: [
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'>=',
|
|
'1',
|
|
],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value: 'Wait',
|
|
},
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
// Add an event to prevent optimisation (reuse of the same objects list)
|
|
// in the previous event.
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'>=',
|
|
'0',
|
|
],
|
|
},
|
|
],
|
|
actions: [],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectALists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
});
|
|
myObjectA2.getVariables().get('TestVariable').setNumber(1);
|
|
myObjectA3.getVariables().get('TestVariable').setNumber(2);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectALists]);
|
|
|
|
// Initial state is unchanged because the first wait task is not done.
|
|
expect(myObjectA1.getVariables().has('TestVariable')).toBe(false);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
2
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Initial state is still unchanged because the conditions ran but the second wait task
|
|
// is not done.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
2
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Only the "myObjectA3" instance was modified by the action.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().has('TestVariable')).toBe(true);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
2 + 5
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('With objects, object groups and deleted/created objects', () => {
|
|
test('asynchronous actions and deleted objects', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
|
|
// Delete an object while the task is running.
|
|
myObjectA1.deleteFromScene();
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
|
|
// Delete other objects while the task is running.
|
|
myObjectA3.deleteFromScene();
|
|
myObjectB1.deleteFromScene();
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check only non deleted objects are updated by the final action.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
15
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
15
|
|
);
|
|
});
|
|
|
|
test('two asynchronous actions immediately following each other, and deleted objects', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
|
|
// Delete an object while the task is running.
|
|
myObjectA1.deleteFromScene();
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Nothing is changed (no action run).
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
|
|
// Delete other objects while the task is running.
|
|
myObjectA3.deleteFromScene();
|
|
myObjectB1.deleteFromScene();
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check only non deleted objects are updated by the final action.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
});
|
|
|
|
test('asynchronous actions and object groups', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyGroup', 'TestVariable', '=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject1',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject2',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyGroup',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.addNewParameter('IncreaseValue')
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.addNewParameter('MyParamObject1')
|
|
.setType('object');
|
|
eventsFunction
|
|
.getParameters()
|
|
.addNewParameter('MyParamObject2')
|
|
.setType('object');
|
|
|
|
// Create a group that refers to both objects passed as parameters.
|
|
const myGroup = eventsFunction.getObjectGroups().insertNew('MyGroup', 0);
|
|
myGroup.addObject('MyParamObject1');
|
|
myGroup.addObject('MyParamObject2');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectALists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
});
|
|
const myObjectBLists = gdjs.Hashtable.newFrom({
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
|
|
myObjectA2.getVariables().get('TestVariable').setNumber(1);
|
|
myObjectB2.getVariables().get('TestVariable').setNumber(1);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [
|
|
5,
|
|
myObjectALists,
|
|
myObjectBLists,
|
|
]);
|
|
|
|
// Only objects passed to the "MyParamObject1" parameter have their variable increased.
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1
|
|
);
|
|
|
|
// Object filtered in the initial condition are not updated.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Now, only objects passed to the "MyParamObject2" parameter have their variable increased.
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
|
|
// Object filtered in the initial condition are not updated.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// All the remaining objects, referred by "MyGroup" in the function, should have their variable increased.
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5 + 5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5 + 5
|
|
);
|
|
|
|
// Object filtered in the initial condition are not updated.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
});
|
|
|
|
test('asynchronous actions and deleted objects in object groups', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject1',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject2',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyGroup',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.addNewParameter('IncreaseValue')
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.addNewParameter('MyParamObject1')
|
|
.setType('object');
|
|
eventsFunction
|
|
.getParameters()
|
|
.addNewParameter('MyParamObject2')
|
|
.setType('object');
|
|
|
|
// Create a group that refers to both objects passed as parameters.
|
|
const myGroup = eventsFunction.getObjectGroups().insertNew('MyGroup', 0);
|
|
myGroup.addObject('MyParamObject1');
|
|
myGroup.addObject('MyParamObject2');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectALists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
});
|
|
const myObjectBLists = gdjs.Hashtable.newFrom({
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [
|
|
5,
|
|
myObjectALists,
|
|
myObjectBLists,
|
|
]);
|
|
|
|
// Only objects passed to the "MyParamObject1" parameter have their variable increased.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Delete an object while the task is running.
|
|
myObjectA1.deleteFromScene();
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Now, only objects passed to the "MyParamObject2" parameter have their variable increased.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
|
|
// Delete other objects while the task is running.
|
|
myObjectA3.deleteFromScene();
|
|
myObjectB1.deleteFromScene();
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// All the remaining objects, referred by "MyGroup" in the function, should have their variable increased.
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
10
|
|
);
|
|
|
|
// Objects deleted, even if they are in "MyGroup", don't have their variable increased.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
});
|
|
|
|
test('asynchronous actions and multiple created objects (that were not used before)', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [],
|
|
});
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check an object was created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(2);
|
|
const myObjectA2 = runtimeScene.getObjects('MyObjectA')[1];
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check an object was created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(3);
|
|
const myObjectA3 = runtimeScene.getObjects('MyObjectA')[2];
|
|
|
|
// Check that both objects that have been created are updated by
|
|
// the last action (like if there was no wait action).
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
});
|
|
|
|
test('asynchronous actions and multiple created objects (that were not used before, with a usage after the first is created)', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [],
|
|
});
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check an object was created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(2);
|
|
const myObjectA2 = runtimeScene.getObjects('MyObjectA')[1];
|
|
|
|
// Check that the instance just created is updated by
|
|
// the action (like if there was no wait action).
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check an object was created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(3);
|
|
const myObjectA3 = runtimeScene.getObjects('MyObjectA')[2];
|
|
|
|
// Check that both objects that have been created are updated by
|
|
// the last action (like if there was no wait action).
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
});
|
|
|
|
test('asynchronous actions and multiple created objects (that were not used before, with a usage after an async action after the first is created)', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [],
|
|
});
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check an object was created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(2);
|
|
const myObjectA2 = runtimeScene.getObjects('MyObjectA')[1];
|
|
|
|
// Check that the instance just created is updated by
|
|
// the action (like if there was no wait action).
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check an object was created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(3);
|
|
const myObjectA3 = runtimeScene.getObjects('MyObjectA')[2];
|
|
|
|
// Check that both objects that have been created are updated by
|
|
// the last action (like if there was no wait action).
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
});
|
|
|
|
test('asynchronous actions and created and deleted objects, using object groups', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'TestVariable', '>=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
myObjectA1.getVariables().get('TestVariable').setNumber(1);
|
|
myObjectA2.getVariables().get('TestVariable').setNumber(1);
|
|
myObjectB1.getVariables().get('TestVariable').setNumber(1);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
|
|
// Only objects filtered by the first condition should have been impacted.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
|
|
// Other objects, not picked by the first condition, are not impacted.
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check an object was created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(4);
|
|
const newMyObjectA = runtimeScene.getObjects('MyObjectA')[3];
|
|
|
|
// Delete some objects while the second Wait task is running.
|
|
myObjectA1.deleteFromScene();
|
|
myObjectB1.deleteFromScene();
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check the newly created object was updated by the last action
|
|
expect(
|
|
newMyObjectA.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
|
|
// Check the object picked by the condition (and not deleted) is updated
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5 + 5
|
|
);
|
|
|
|
// Check the deleted objects and objects not picked are not updated
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
});
|
|
|
|
test('created and then immediately deleted objects', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'TestVariable', '>=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
myObjectA1.getVariables().get('TestVariable').setNumber(1);
|
|
myObjectA2.getVariables().get('TestVariable').setNumber(1);
|
|
myObjectB1.getVariables().get('TestVariable').setNumber(1);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
|
|
// Only objects filtered by the first condition should have been impacted.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
|
|
// Other objects, not picked by the first condition, are not impacted.
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that two objects were created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(5);
|
|
const newMyObjectA1 = runtimeScene.getObjects('MyObjectA')[3];
|
|
const newMyObjectA2 = runtimeScene.getObjects('MyObjectA')[4];
|
|
|
|
// Delete some objects while the second Wait task is running.
|
|
myObjectA1.deleteFromScene();
|
|
myObjectB1.deleteFromScene();
|
|
newMyObjectA1.deleteFromScene();
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check the newly created and then deleted object was not updated by the last action
|
|
expect(
|
|
newMyObjectA1.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(0);
|
|
|
|
// Check the newly created object was updated by the last action
|
|
expect(
|
|
newMyObjectA2.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
|
|
// Check the object picked by the condition (and not deleted) is updated
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5 + 5
|
|
);
|
|
|
|
// Check the deleted objects and objects not picked are not updated
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
1 + 5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
});
|
|
|
|
describe('async object actions, waiting for all objects to be finished', () => {
|
|
const expectProgressivelyResolvedTasksForObjects = (
|
|
runCompiledEvents
|
|
) => {
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Process the tasks again (but none is finished).
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Mark some tasks as done.
|
|
myObjectA1.markFakeAsyncActionAsFinished();
|
|
myObjectA2.markFakeAsyncActionAsFinished();
|
|
myObjectB1.markFakeAsyncActionAsFinished();
|
|
|
|
// Process the tasks again (but not everything is finished).
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Mark the rest of tasks as done.
|
|
myObjectA3.markFakeAsyncActionAsFinished();
|
|
myObjectB2.markFakeAsyncActionAsFinished();
|
|
|
|
// Process the tasks again (everything is finished this time).
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(true);
|
|
expect(
|
|
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
|
|
).toBe(1);
|
|
|
|
expect(
|
|
myObjectA1.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
expect(
|
|
myObjectA2.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
expect(
|
|
myObjectA3.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
expect(
|
|
myObjectB1.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
expect(
|
|
myObjectB2.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
};
|
|
|
|
test('async object actions, waiting for all objects to be finished', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value:
|
|
'FakeObjectWithAsyncAction::FakeObjectWithAsyncAction::DoAsyncAction',
|
|
},
|
|
parameters: ['MyParamObject'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['SuccessVariable', '+', '1'],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object')
|
|
.setExtraInfo('FakeObjectWithAsyncAction::FakeObjectWithAsyncAction');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
expectProgressivelyResolvedTasksForObjects(runCompiledEvents);
|
|
});
|
|
|
|
test('optionally async object action, set as async', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value:
|
|
'FakeObjectWithAsyncAction::FakeObjectWithAsyncAction::DoOptionallyAsyncAction',
|
|
await: true,
|
|
},
|
|
parameters: ['MyParamObject'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['SuccessVariable', '+', '1'],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object')
|
|
.setExtraInfo('FakeObjectWithAsyncAction::FakeObjectWithAsyncAction');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
expectProgressivelyResolvedTasksForObjects(runCompiledEvents);
|
|
});
|
|
|
|
test('optionally async object action, not set as async', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value:
|
|
'FakeObjectWithAsyncAction::FakeObjectWithAsyncAction::DoOptionallyAsyncAction',
|
|
await: false,
|
|
},
|
|
parameters: ['MyParamObject'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['SuccessVariable', '+', '1'],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object')
|
|
.setExtraInfo('FakeObjectWithAsyncAction::FakeObjectWithAsyncAction');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
|
|
// Nothing is async, everything is done in a single run.
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(true);
|
|
expect(
|
|
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
|
|
).toBe(1);
|
|
|
|
expect(
|
|
myObjectA1.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
expect(
|
|
myObjectA2.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
expect(
|
|
myObjectA3.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
expect(
|
|
myObjectB1.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
expect(
|
|
myObjectB2.getVariables().get('TestVariable').getAsNumber()
|
|
).toBe(5);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('With objects, and advanced conditions', () => {
|
|
test('with "Or" conditions', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: {
|
|
value: 'BuiltinCommonInstructions::Or',
|
|
},
|
|
parameters: [],
|
|
subInstructions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'PleaseCountMe', '=', '1'],
|
|
},
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'PleaseCountMeToo', '=', '1'],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: {
|
|
value:
|
|
'FakeObjectWithAsyncAction::FakeObjectWithAsyncAction::DoAsyncAction',
|
|
},
|
|
parameters: ['MyParamObject'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
events: [
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: {
|
|
value: 'BuiltinCommonInstructions::Or',
|
|
},
|
|
parameters: [],
|
|
subInstructions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'PleaseCountMeASecondTime',
|
|
'=',
|
|
'1',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'PleaseCountMeASecondTimeToo',
|
|
'=',
|
|
'1',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object')
|
|
.setExtraInfo('FakeObjectWithAsyncAction::FakeObjectWithAsyncAction');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB3 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2, myObjectB3],
|
|
});
|
|
myObjectA1.getVariables().get('PleaseCountMe').setNumber(1);
|
|
myObjectA1.getVariables().get('PleaseCountMeASecondTime').setNumber(1);
|
|
myObjectA2.getVariables().get('PleaseCountMeToo').setNumber(1);
|
|
myObjectB1.getVariables().get('PleaseCountMe').setNumber(1);
|
|
myObjectB1.getVariables().get('PleaseCountMeASecondTimeToo').setNumber(1);
|
|
myObjectB2.getVariables().get('PleaseCountMeToo').setNumber(1);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(false);
|
|
|
|
// Mark tasks as done.
|
|
myObjectA1.markFakeAsyncActionAsFinished();
|
|
myObjectA2.markFakeAsyncActionAsFinished();
|
|
myObjectA3.markFakeAsyncActionAsFinished();
|
|
myObjectB1.markFakeAsyncActionAsFinished();
|
|
myObjectB2.markFakeAsyncActionAsFinished();
|
|
myObjectB3.markFakeAsyncActionAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that only objects passing the "Or" sub-conditions have been
|
|
// updated.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5 // Pass both "Or" conditions.
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 // Pass the first "Or" conditions.
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0 // Pass no conditions.
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5 // Pass both "Or" conditions.
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 // Pass the first "Or" conditions.
|
|
);
|
|
expect(myObjectB3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0 // Pass no conditions.
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('With non standard events', () => {
|
|
test('a While event', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSObject([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['Counter', '=', '0'],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
infiniteLoopWarning: true,
|
|
type: 'BuiltinCommonInstructions::While',
|
|
whileConditions: [
|
|
{
|
|
type: { value: 'VarScene' },
|
|
parameters: ['Counter', '<', '4'],
|
|
},
|
|
],
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'PleasePickMe', '=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['Counter', '+', '1'],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
myObjectA1.getVariables().get('PleasePickMe').setNumber(1);
|
|
myObjectA2.getVariables().get('PleasePickMe').setNumber(1);
|
|
myObjectB1.getVariables().get('PleasePickMe').setNumber(1);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
|
|
// Check that the loop is done.
|
|
expect(runtimeScene.getVariables().has('Counter')).toBe(true);
|
|
expect(runtimeScene.getVariables().get('Counter').getAsNumber()).toBe(4);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that all the tasks are done
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 * 4
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 * 4
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 * 4
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
});
|
|
|
|
test('a While event, with sub-events', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSObject([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['Counter', '=', '0'],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
infiniteLoopWarning: true,
|
|
type: 'BuiltinCommonInstructions::While',
|
|
whileConditions: [
|
|
{
|
|
type: { value: 'VarScene' },
|
|
parameters: ['Counter', '<', '4'],
|
|
},
|
|
],
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'PleasePickMe', '=', '1'],
|
|
},
|
|
],
|
|
actions: [],
|
|
events: [
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
// (Same condition as before)
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'PleasePickMe', '=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['Counter', '+', '1'],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
myObjectA1.getVariables().get('PleasePickMe').setNumber(1);
|
|
myObjectA2.getVariables().get('PleasePickMe').setNumber(1);
|
|
myObjectB1.getVariables().get('PleasePickMe').setNumber(1);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
|
|
// Check that the loop is done.
|
|
expect(runtimeScene.getVariables().has('Counter')).toBe(true);
|
|
expect(runtimeScene.getVariables().get('Counter').getAsNumber()).toBe(4);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that all the tasks are done
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 * 4
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 * 4
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 * 4
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
});
|
|
|
|
test('a Repeat event', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSObject([
|
|
{
|
|
infiniteLoopWarning: true,
|
|
type: 'BuiltinCommonInstructions::Repeat',
|
|
repeatExpression: '3',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'PleasePickMe', '=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['Counter', '+', '1'],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
myObjectA1.getVariables().get('PleasePickMe').setNumber(1);
|
|
myObjectA2.getVariables().get('PleasePickMe').setNumber(1);
|
|
myObjectB1.getVariables().get('PleasePickMe').setNumber(1);
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [5, myObjectsLists]);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that all the tasks are done
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 * 3
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 * 3
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 * 3
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
});
|
|
|
|
test('a ForEach event', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSObject([
|
|
{
|
|
infiniteLoopWarning: true,
|
|
type: 'BuiltinCommonInstructions::ForEach',
|
|
object: 'MyParamObject',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'PleasePickMe', '=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { value: 'ModVarScene' },
|
|
parameters: ['Counter', '+', '1'],
|
|
},
|
|
// Add a wait action to check that 3 different waits will be done
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
// Add another wait action to check that 3 different waits will be done
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: ['MyOtherParamObject', 'TestVariable', '+', '4'],
|
|
},
|
|
// Add an async object action that can be resolved at different time by each object.
|
|
{
|
|
type: {
|
|
value:
|
|
'FakeObjectWithAsyncAction::FakeObjectWithAsyncAction::DoAsyncAction',
|
|
},
|
|
parameters: ['MyParamObject'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: ['MyOtherParamObject', 'TestVariable', '+', '4'],
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object')
|
|
.setExtraInfo('FakeObjectWithAsyncAction::FakeObjectWithAsyncAction');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyOtherParamObject', 2)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA2 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectA3 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectB1 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectB2 = runtimeScene.createObject('MyObjectB');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [myObjectA1, myObjectA2, myObjectA3],
|
|
MyObjectB: [myObjectB1, myObjectB2],
|
|
});
|
|
|
|
myObjectA1.getVariables().get('PleasePickMe').setNumber(1);
|
|
myObjectA2.getVariables().get('PleasePickMe').setNumber(1);
|
|
myObjectB1.getVariables().get('PleasePickMe').setNumber(1);
|
|
const myObjectC1 = runtimeScene.createObject('MyObjectC');
|
|
const myObjectC2 = runtimeScene.createObject('MyObjectC');
|
|
const myOtherObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectC: [myObjectC1, myObjectC2],
|
|
});
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [
|
|
5,
|
|
myObjectsLists,
|
|
myOtherObjectsLists,
|
|
]);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that each object A and B got its variable updated.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that each object A and B got its variable updated.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Check that the objects C are also updated: the two of them are updated
|
|
// 3 times (once for each object of the ForEach)
|
|
// (4 is added each time to the variable).
|
|
expect(myObjectC1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3 * 4
|
|
);
|
|
expect(myObjectC2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3 * 4
|
|
);
|
|
|
|
// Process some object (myObjectA1, myObjectB1) async tasks:
|
|
myObjectA1.markFakeAsyncActionAsFinished();
|
|
myObjectB1.markFakeAsyncActionAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that each object A and B got its variable updated.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5 + 5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5 // This was not updated
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5 + 5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Check that the objects C are also updated: the two of them are updated
|
|
// 2 times (once for each object that finished its task)
|
|
// (4 is added each time to the variable).
|
|
expect(myObjectC1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3 * 4 + 2 * 4
|
|
);
|
|
expect(myObjectC2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3 * 4 + 2 * 4
|
|
);
|
|
|
|
// Process the last object (myObjectA2) async tasks:
|
|
myObjectA2.markFakeAsyncActionAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that each object A and B got its variable updated.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5 + 5
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5 + 5 // This was just updated.
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectB1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 + 5 + 5
|
|
);
|
|
expect(myObjectB2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Check that the objects C are also updated: the two of them are updated
|
|
// 1 more time (once the last object) (4 is added each time to the variable).
|
|
expect(myObjectC1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3 * 4 + 2 * 4 + 1 * 4
|
|
);
|
|
expect(myObjectC2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
3 * 4 + 2 * 4 + 1 * 4
|
|
);
|
|
});
|
|
|
|
test('a ForEach on created objects', function () {
|
|
const eventsSerializerElement = gd.Serializer.fromJSON(
|
|
JSON.stringify([
|
|
{
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [],
|
|
actions: [
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
// Set a variable for the last two created instances:
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: ['MyParamObject', 'PleasePickMe', '=', '1'],
|
|
},
|
|
{
|
|
type: { value: 'Wait' },
|
|
parameters: ['1.5'],
|
|
},
|
|
// Create an additional object but without a variable, so
|
|
// that it's discarded in the for each
|
|
{
|
|
type: { value: 'Create' },
|
|
parameters: ['', 'MyParamObject', '0', '0', ''],
|
|
},
|
|
],
|
|
events: [
|
|
{
|
|
infiniteLoopWarning: true,
|
|
type: 'BuiltinCommonInstructions::ForEach',
|
|
object: 'MyParamObject',
|
|
conditions: [
|
|
{
|
|
type: { value: 'VarObjet' },
|
|
parameters: ['MyParamObject', 'PleasePickMe', '=', '1'],
|
|
},
|
|
],
|
|
actions: [
|
|
// Add an async object action that can be resolved at different time by each object.
|
|
{
|
|
type: {
|
|
value:
|
|
'FakeObjectWithAsyncAction::FakeObjectWithAsyncAction::DoAsyncAction',
|
|
},
|
|
parameters: ['MyParamObject'],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'GetArgumentAsNumber("IncreaseValue")',
|
|
],
|
|
},
|
|
{
|
|
type: { value: 'ModVarObjet' },
|
|
parameters: [
|
|
'MyOtherParamObject',
|
|
'TestVariable',
|
|
'+',
|
|
'4',
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
);
|
|
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsFunction = new gd.EventsFunction();
|
|
|
|
eventsFunction
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('IncreaseValue', 0)
|
|
.setType('number');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyParamObject', 1)
|
|
.setType('object')
|
|
.setExtraInfo('FakeObjectWithAsyncAction::FakeObjectWithAsyncAction');
|
|
eventsFunction
|
|
.getParameters()
|
|
.insertNewParameter('MyOtherParamObject', 2)
|
|
.setType('object');
|
|
|
|
const runCompiledEvents = generateCompiledEventsForEventsFunction(
|
|
gd,
|
|
project,
|
|
eventsFunction
|
|
);
|
|
|
|
eventsFunction.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const myObjectA1 = runtimeScene.createObject('MyObjectA');
|
|
const myObjectC1 = runtimeScene.createObject('MyObjectC');
|
|
const myObjectC2 = runtimeScene.createObject('MyObjectC');
|
|
const myObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectA: [],
|
|
});
|
|
const myOtherObjectsLists = gdjs.Hashtable.newFrom({
|
|
MyObjectC: [myObjectC1, myObjectC2],
|
|
});
|
|
|
|
runCompiledEvents(gdjs, runtimeScene, [
|
|
5,
|
|
myObjectsLists,
|
|
myOtherObjectsLists,
|
|
]);
|
|
|
|
// Process the tasks (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check an object was created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(2);
|
|
const myObjectA2 = runtimeScene.getObjects('MyObjectA')[1];
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check an object was created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(3);
|
|
const myObjectA3 = runtimeScene.getObjects('MyObjectA')[2];
|
|
|
|
// Process the tasks again (after faking it's finished).
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check an object was created.
|
|
expect(runtimeScene.getObjects('MyObjectA').length).toBe(4);
|
|
const myObjectA4 = runtimeScene.getObjects('MyObjectA')[3];
|
|
|
|
// Process some object async tasks:
|
|
myObjectA2.markFakeAsyncActionAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that object A got its variable updated.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 // This was just updated.
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA4.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Check that the objects C are also updated: the two of them are updated
|
|
// once (4 is added each time to the variable).
|
|
expect(myObjectC1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
4
|
|
);
|
|
expect(myObjectC2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
4
|
|
);
|
|
|
|
// Process the remaining object async tasks:
|
|
myObjectA3.markFakeAsyncActionAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks(runtimeScene);
|
|
|
|
// Check that object A got its variable updated.
|
|
expect(myObjectA1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
expect(myObjectA2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5
|
|
);
|
|
expect(myObjectA3.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
5 // This was just updated.
|
|
);
|
|
expect(myObjectA4.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
0
|
|
);
|
|
|
|
// Check that the objects C are also updated: the two of them are updated
|
|
// once more.
|
|
expect(myObjectC1.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
4 + 4
|
|
);
|
|
expect(myObjectC2.getVariables().get('TestVariable').getAsNumber()).toBe(
|
|
4 + 4
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('Events based asynchronous functions', () => {
|
|
it('Resolves after awaiting an async action', () => {
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const extensionModule =
|
|
generateCompiledEventsForSerializedEventsBasedExtension(
|
|
gd,
|
|
require('./extensions/EBAsyncAction.json'),
|
|
gdjs,
|
|
runtimeScene
|
|
);
|
|
|
|
const {
|
|
freeFunctions: { wait },
|
|
behaviors: { Behavior },
|
|
objects: { Object },
|
|
} = extensionModule;
|
|
|
|
const freeFunctionExtensionTask = wait();
|
|
expect(freeFunctionExtensionTask.update()).toBe(false);
|
|
expect(runtimeScene.getAsyncTasksManager().tasks.size).toBe(1);
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks();
|
|
expect(freeFunctionExtensionTask.update()).toBe(true);
|
|
|
|
const object = new Object(runtimeScene, {});
|
|
const objectExtensionTask = object.wait();
|
|
expect(objectExtensionTask.update()).toBe(false);
|
|
expect(runtimeScene.getAsyncTasksManager().tasks.size).toBe(1);
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks();
|
|
expect(objectExtensionTask.update()).toBe(true);
|
|
|
|
const behavior = new Behavior(runtimeScene, {});
|
|
const behaviorExtensionTask = behavior.wait();
|
|
expect(behaviorExtensionTask.update()).toBe(false);
|
|
expect(runtimeScene.getAsyncTasksManager().tasks.size).toBe(1);
|
|
runtimeScene.getAsyncTasksManager().markAllFakeAsyncTasksAsFinished();
|
|
runtimeScene.getAsyncTasksManager().processTasks();
|
|
expect(behaviorExtensionTask.update()).toBe(true);
|
|
});
|
|
|
|
it('Resolves without awaiting an async action', () => {
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const extensionModule =
|
|
generateCompiledEventsForSerializedEventsBasedExtension(
|
|
gd,
|
|
require('./extensions/EBAsyncAction.json'),
|
|
gdjs,
|
|
runtimeScene
|
|
);
|
|
|
|
const {
|
|
freeFunctions: { noWait },
|
|
behaviors: { Behavior },
|
|
objects: { Object },
|
|
} = extensionModule;
|
|
|
|
const extensionTask = noWait();
|
|
expect(extensionTask.update()).toBe(true);
|
|
expect(runtimeScene.getAsyncTasksManager().tasks.size).toBe(0);
|
|
|
|
const obj = new Object(runtimeScene, {});
|
|
const objectExtensionTask = obj.noWait();
|
|
expect(objectExtensionTask.update()).toBe(true);
|
|
expect(runtimeScene.getAsyncTasksManager().tasks.size).toBe(0);
|
|
|
|
const behavior = new Behavior(runtimeScene, {});
|
|
const behaviorExtensionTask = behavior.noWait();
|
|
expect(behaviorExtensionTask.update()).toBe(true);
|
|
expect(runtimeScene.getAsyncTasksManager().tasks.size).toBe(0);
|
|
});
|
|
});
|
|
});
|