mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-23 02:25:52 -04:00
b76df0247d
Don't show the rest in the changelog: This was because the OnceTriggers were shared with the runtime scene. Now each behavior has its set of Once Triggers. This means that Once Triggers "survive" if the behavior is deactivated then activated again. Added integration test for generated behavior Fix #1843
172 lines
5.0 KiB
JavaScript
172 lines
5.0 KiB
JavaScript
const initializeGDevelopJs = require('../../Binaries/embuild/GDevelop.js/libGD.js');
|
|
const { makeMinimalGDJSMock } = require('../TestUtils/GDJSMocks');
|
|
|
|
describe('libGD.js - GDJS Behavior Code Generation integration tests', function () {
|
|
let gd = null;
|
|
beforeAll((done) =>
|
|
initializeGDevelopJs().then((module) => {
|
|
gd = module;
|
|
done();
|
|
})
|
|
);
|
|
|
|
it('generates a working empty behavior', function () {
|
|
// Create an empty behavior
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsBasedBehavior = new gd.EventsBasedBehavior();
|
|
eventsBasedBehavior.setName('MyBehavior');
|
|
eventsBasedBehavior.setFullName('My descriptive name');
|
|
eventsBasedBehavior.setDescription('My description');
|
|
|
|
const makeCompiledRuntimeBehavior = generateCompiledRuntimeBehaviorMaker(
|
|
gd,
|
|
project,
|
|
eventsBasedBehavior
|
|
);
|
|
eventsBasedBehavior.delete();
|
|
project.delete();
|
|
|
|
// Instanciate the behavior
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const CompiledRuntimeBehavior = makeCompiledRuntimeBehavior(gdjs);
|
|
const behaviorData = {};
|
|
const ownerRuntimeObject = {};
|
|
const behavior = new CompiledRuntimeBehavior(
|
|
runtimeScene,
|
|
behaviorData,
|
|
ownerRuntimeObject
|
|
);
|
|
|
|
// Check that doStepPreEvents is always defined
|
|
expect(behavior.doStepPreEvents).not.toBeUndefined();
|
|
});
|
|
|
|
it('generates a working behavior with doStepPreEvents using "Trigger Once" condition', function () {
|
|
// Create a new behavior with events in doStepPreEvents
|
|
const project = new gd.ProjectHelper.createNewGDJSProject();
|
|
const eventsBasedBehavior = new gd.EventsBasedBehavior();
|
|
eventsBasedBehavior.setName('MyBehavior');
|
|
eventsBasedBehavior.setFullName('My descriptive name');
|
|
eventsBasedBehavior.setDescription('My description');
|
|
|
|
const eventsSerializerElement = gd.Serializer.fromJSObject([
|
|
{
|
|
disabled: false,
|
|
folded: false,
|
|
type: 'BuiltinCommonInstructions::Standard',
|
|
conditions: [
|
|
{
|
|
type: {
|
|
inverted: false,
|
|
value: 'BuiltinCommonInstructions::Once',
|
|
},
|
|
parameters: [],
|
|
subInstructions: [],
|
|
},
|
|
],
|
|
actions: [
|
|
{
|
|
type: { inverted: false, value: 'ModVarScene' },
|
|
parameters: ['SuccessVariable', '+', '1'],
|
|
subInstructions: [],
|
|
},
|
|
],
|
|
events: [],
|
|
},
|
|
]);
|
|
eventsBasedBehavior
|
|
.getEventsFunctions()
|
|
.insertNewEventsFunction('doStepPreEvents', 0)
|
|
.getEvents()
|
|
.unserializeFrom(project, eventsSerializerElement);
|
|
|
|
// Instanciate the behavior twice
|
|
const makeCompiledRuntimeBehavior = generateCompiledRuntimeBehaviorMaker(
|
|
gd,
|
|
project,
|
|
eventsBasedBehavior
|
|
);
|
|
eventsBasedBehavior.delete();
|
|
project.delete();
|
|
|
|
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
|
|
const CompiledRuntimeBehavior = makeCompiledRuntimeBehavior(gdjs);
|
|
const behaviorData = {};
|
|
const ownerRuntimeObject = {};
|
|
const behavior = new CompiledRuntimeBehavior(
|
|
runtimeScene,
|
|
behaviorData,
|
|
ownerRuntimeObject
|
|
);
|
|
const behavior2 = new CompiledRuntimeBehavior(
|
|
runtimeScene,
|
|
behaviorData,
|
|
ownerRuntimeObject
|
|
);
|
|
|
|
// Check that Trigger once is working, separately handled by each behavior instance:
|
|
expect(behavior.doStepPreEvents).not.toBeUndefined();
|
|
behavior.doStepPreEvents();
|
|
behavior2.doStepPreEvents();
|
|
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(true);
|
|
expect(
|
|
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
|
|
).toBe(2);
|
|
|
|
behavior.doStepPreEvents();
|
|
behavior2.doStepPreEvents();
|
|
expect(
|
|
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
|
|
).toBe(2);
|
|
});
|
|
});
|
|
|
|
function generateCompiledRuntimeBehaviorMaker(
|
|
gd,
|
|
project,
|
|
eventsBasedBehavior
|
|
) {
|
|
const includeFiles = new gd.SetString();
|
|
|
|
const codeNamespace = 'behaviorNamespace';
|
|
const behaviorCodeGenerator = new gd.BehaviorCodeGenerator(project);
|
|
|
|
// Generate "mangled names" as required by the code generation
|
|
const behaviorMethodMangledNames = new gd.MapStringString();
|
|
for (
|
|
let i = 0;
|
|
i < eventsBasedBehavior.getEventsFunctions().getEventsFunctionsCount();
|
|
i++
|
|
) {
|
|
const eventsFunction = eventsBasedBehavior
|
|
.getEventsFunctions()
|
|
.getEventsFunctionAt(i);
|
|
behaviorMethodMangledNames.set(
|
|
eventsFunction.getName(),
|
|
eventsFunction.getName()
|
|
);
|
|
}
|
|
|
|
const code = behaviorCodeGenerator.generateRuntimeBehaviorCompleteCode(
|
|
'MyExtension',
|
|
eventsBasedBehavior,
|
|
codeNamespace,
|
|
behaviorMethodMangledNames,
|
|
includeFiles,
|
|
true
|
|
);
|
|
|
|
// Create a function with the generated behavior.
|
|
const makeCompiledBehavior = new Function(
|
|
'gdjs',
|
|
`let behaviorNamespace = {};
|
|
let Hashtable = gdjs.Hashtable;
|
|
${code}
|
|
return behaviorNamespace.MyBehavior;`
|
|
);
|
|
|
|
includeFiles.delete();
|
|
|
|
return makeCompiledBehavior;
|
|
}
|