Fix initialization of local array variables (#6777)

This commit is contained in:
D8H
2024-07-22 11:07:47 +02:00
committed by GitHub
parent 7ac600e92d
commit 45d73df6fb
6 changed files with 100 additions and 9 deletions

View File

@@ -892,22 +892,28 @@ void CommonInstructionsExtension::GenerateLocalVariableInitializationCode(
code += variableCodeName + ".setString(" +
EventsCodeGenerator::ConvertToStringExplicit(variable.GetString()) +
");\n";
} else if (variable.GetType() == gd::Variable::Structure ||
variable.GetType() == gd::Variable::Array) {
} else if (variable.GetType() == gd::Variable::Structure) {
const auto &childrenNames = variable.GetAllChildrenNames();
for (const auto& childName : variable.GetAllChildrenNames()) {
for (const auto &childName : variable.GetAllChildrenNames()) {
auto &child = variable.GetChild(childName);
code += "{\n";
GenerateLocalVariableInitializationCode(child, code, depth + 1);
auto childCodeName = "variable" + gd::String::From(depth + 1);
code += variableCodeName + ".addChild(" +
EventsCodeGenerator::ConvertToStringExplicit(childName) +
", " + childCodeName + ");\n";
EventsCodeGenerator::ConvertToStringExplicit(childName) + ", " +
childCodeName + ");\n";
code += "}\n";
}
if (variable.GetType() == gd::Variable::Array) {
code += variableCodeName + ".castTo('array');\n";
} else if (variable.GetType() == gd::Variable::Array) {
for (std::size_t i = 0; i < variable.GetChildrenCount(); i++) {
auto &child = variable.GetAtIndex(i);
code += "{\n";
GenerateLocalVariableInitializationCode(child, code, depth + 1);
auto childCodeName = "variable" + gd::String::From(depth + 1);
code += variableCodeName + "._pushVariable(" + childCodeName + ");\n";
code += "}\n";
}
}
}

View File

@@ -620,6 +620,16 @@ namespace gdjs {
this._childrenArray.push(variable.clone());
}
/**
* Pushes a variable into the array without duplicating it first.
* This should only be used by generated code.
*/
_pushVariable(variable: gdjs.Variable) {
if (this._type !== 'array') this.castTo('array');
this._childrenArray.push(variable);
}
/**
* Pushes a value into the array.
*/

View File

@@ -521,6 +521,7 @@ namespace gdjs {
return [];
},
pushVariableCopy: () => {},
_pushVariable: () => {},
pushValue: () => {},
removeAtIndex: function () {
return;

View File

@@ -252,6 +252,13 @@ class Variable {
this._childrenArray.push(variable.clone());
return this;
}
/**
* @param {Variable} variable
*/
_pushVariable(variable) {
this._childrenArray.push(variable);
}
/**
*

View File

@@ -420,7 +420,7 @@ describe('libGD.js - GDJS Code Generation integration tests', function () {
).toBe(1);
});
it('can generate a local child-variable condition', function () {
it('can generate a local child-variable condition on a structure', function () {
extension.getSceneVariables().insertNew('SuccessVariable', 0).setValue(0);
const runtimeScene = generateAndRunEventsForFunction([
{
@@ -455,6 +455,41 @@ describe('libGD.js - GDJS Code Generation integration tests', function () {
).toBe(1);
});
it('can generate a local child-variable condition on an array', function () {
extension.getSceneVariables().insertNew('SuccessVariable', 0).setValue(0);
const runtimeScene = generateAndRunEventsForFunction([
{
type: 'BuiltinCommonInstructions::Standard',
variables: [
{
name: 'MyLocalVariable',
type: 'array',
children: [{ name: '0', type: 'number', value: 123 }],
},
],
conditions: [
{
type: { inverted: false, value: 'NumberVariable' },
parameters: ['MyLocalVariable[0]', '=', '123'],
},
],
actions: [
{
type: { value: 'SetNumberVariable' },
parameters: ['SuccessVariable', '=', '1'],
},
],
events: [],
},
]);
expect(
runtimeScene
.getVariablesForExtension('Extension')
.get('SuccessVariable')
.getAsNumber()
).toBe(1);
});
it('can generate a local variable condition giving precedence to the closest local variable', function () {
extension.getSceneVariables().insertNew('SuccessVariable', 0).setValue(0);

View File

@@ -346,7 +346,7 @@ describe('libGD.js - GDJS Code Generation integration tests', function () {
).toBe(1);
});
it('can generate a local child-variable condition', function () {
it('can generate a local child-variable condition on a structure', function () {
scene.getVariables().insertNew('SuccessVariable', 0).setValue(0);
const runtimeScene = generateAndRunEventsForLayout([
{
@@ -378,6 +378,38 @@ describe('libGD.js - GDJS Code Generation integration tests', function () {
).toBe(1);
});
it('can generate a local child-variable condition on an array', function () {
scene.getVariables().insertNew('SuccessVariable', 0).setValue(0);
const runtimeScene = generateAndRunEventsForLayout([
{
type: 'BuiltinCommonInstructions::Standard',
variables: [
{
name: 'MyLocalVariable',
type: 'array',
children: [{ name: '0', type: 'number', value: 123 }],
},
],
conditions: [
{
type: { inverted: false, value: 'NumberVariable' },
parameters: ['MyLocalVariable[0]', '=', '123'],
},
],
actions: [
{
type: { value: 'SetNumberVariable' },
parameters: ['SuccessVariable', '=', '1'],
},
],
events: [],
},
]);
expect(
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
).toBe(1);
});
it('can generate a local variable condition giving precedence to the closest local variable', function () {
scene.getVariables().insertNew('SuccessVariable', 0).setValue(0);