From 5d67c8ac35196102d17b77255281da8506514e05 Mon Sep 17 00:00:00 2001 From: Arthur Pacaud Date: Wed, 21 Jun 2023 17:43:04 +0200 Subject: [PATCH 1/3] Add trigger once per instance --- .vscode/settings.json | 9 +- .../Builtin/CommonInstructionsExtension.cpp | 11 ++ .../Builtin/CommonInstructionsExtension.cpp | 132 +++++++++++++----- .../CustomRuntimeObjectInstanceContainer.ts | 1 + GDJS/Runtime/RuntimeInstanceContainer.ts | 1 + GDJS/Runtime/runtimeobject.ts | 9 ++ 6 files changed, 130 insertions(+), 33 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index e1c51b815bb3..b59bb929d220 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ // Place your settings in this file to overwrite default and user settings. { "files.associations": { + "*.ldtk": "json", "*.idl": "java", "Fastfile": "ruby", "iosfwd": "cpp", @@ -110,7 +111,13 @@ "xlocbuf": "cpp", "xlocmes": "cpp", "xmemory0": "cpp", - "memory_resource": "cpp" + "memory_resource": "cpp", + "charconv": "cpp", + "format": "cpp", + "ranges": "cpp", + "span": "cpp", + "stop_token": "cpp", + "thread": "cpp" }, "files.exclude": { "Binaries/*build*": true, diff --git a/Core/GDCore/Extensions/Builtin/CommonInstructionsExtension.cpp b/Core/GDCore/Extensions/Builtin/CommonInstructionsExtension.cpp index 696dff8d81fe..bd4b4739cc49 100644 --- a/Core/GDCore/Extensions/Builtin/CommonInstructionsExtension.cpp +++ b/Core/GDCore/Extensions/Builtin/CommonInstructionsExtension.cpp @@ -98,6 +98,17 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension( "res/conditions/once24.png", "res/conditions/once.png"); + extension + .AddCondition("OncePerObject", + _("Trigger once while true for an object"), + _("Run actions only once per instance of an object every " + "time the previous conditions start matching."), + _("Trigger once per instance of _PARAM0_"), + "", + "res/conditions/once24.png", + "res/conditions/once.png") + .AddParameter("object", _("The objects that should trigger once")); + extension .AddCondition("CompareNumbers", _("Compare two numbers"), diff --git a/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp b/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp index 9e38a9f5314a..e0b2ae7b8f6b 100644 --- a/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp +++ b/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp @@ -68,7 +68,8 @@ CommonInstructionsExtension::CommonInstructionsExtension() { instruction.GetParameter(2).GetPlainString()); gd::String resultingBoolean = - codeGenerator.GenerateUpperScopeBooleanFullName("isConditionTrue", context); + codeGenerator.GenerateUpperScopeBooleanFullName("isConditionTrue", + context); return resultingBoolean + " = (" + value1Code + " " + operatorCode + " " + value2Code + ");\n"; @@ -98,7 +99,8 @@ CommonInstructionsExtension::CommonInstructionsExtension() { instruction.GetParameter(2).GetPlainString()); gd::String resultingBoolean = - codeGenerator.GenerateUpperScopeBooleanFullName("isConditionTrue", context); + codeGenerator.GenerateUpperScopeBooleanFullName("isConditionTrue", + context); return resultingBoolean + " = (" + value1Code + " " + operatorCode + " " + value2Code + ");\n"; @@ -133,12 +135,10 @@ CommonInstructionsExtension::CommonInstructionsExtension() { gd::String conditionsCode = codeGenerator.GenerateConditionsListCode( event.GetConditions(), context); - gd::String ifPredicate = - event.GetConditions().empty() - ? "" - : codeGenerator.GenerateBooleanFullName( - "isConditionTrue", - context); + gd::String ifPredicate = event.GetConditions().empty() + ? "" + : codeGenerator.GenerateBooleanFullName( + "isConditionTrue", context); gd::EventsCodeGenerationContext actionsContext; actionsContext.Reuse(context); @@ -187,8 +187,8 @@ CommonInstructionsExtension::CommonInstructionsExtension() { // The Or "return" true by setting the upper boolean to true. // So, it needs to be initialized to false. conditionsCode += codeGenerator.GenerateUpperScopeBooleanFullName( - "isConditionTrue", parentContext) + - " = false;\n"; + "isConditionTrue", parentContext) + + " = false;\n"; //"OR" condition must declare objects list, but without picking the // objects from the scene. Lists are either empty or come from a // parent event. @@ -199,12 +199,11 @@ CommonInstructionsExtension::CommonInstructionsExtension() { // "MyObject" will both have to declare a "MyObject" object list. gd::EventsCodeGenerationContext context; context.InheritsFrom(parentContext); - context.ForbidReuse(); // TODO: This may not be necessary (to be investigated/heavily tested). + context.ForbidReuse(); // TODO: This may not be necessary (to be + // investigated/heavily tested). gd::String conditionCode = codeGenerator.GenerateConditionCode( - conditions[cId], - "isConditionTrue", - context); + conditions[cId], "isConditionTrue", context); conditionsCode += "{\n"; @@ -216,11 +215,10 @@ CommonInstructionsExtension::CommonInstructionsExtension() { // If the condition is true : merge all objects picked in the // final object lists. - conditionsCode += - "if(" + - codeGenerator.GenerateBooleanFullName( - "isConditionTrue", context) + - ") {\n"; + conditionsCode += "if(" + + codeGenerator.GenerateBooleanFullName( + "isConditionTrue", context) + + ") {\n"; conditionsCode += " " + codeGenerator.GenerateUpperScopeBooleanFullName( "isConditionTrue", context) + @@ -328,9 +326,9 @@ CommonInstructionsExtension::CommonInstructionsExtension() { GetAllConditions()["BuiltinCommonInstructions::Not"] .codeExtraInformation.SetCustomCodeGenerator( - [](gd::Instruction &instruction, - gd::EventsCodeGenerator &codeGenerator, - gd::EventsCodeGenerationContext &parentContext) { + [](gd::Instruction& instruction, + gd::EventsCodeGenerator& codeGenerator, + gd::EventsCodeGenerationContext& parentContext) { gd::String outputCode; outputCode += codeGenerator.GenerateConditionsListCode( @@ -354,9 +352,10 @@ CommonInstructionsExtension::CommonInstructionsExtension() { gd::EventsCodeGenerationContext& context) { size_t uniqueId = codeGenerator.GenerateSingleUsageUniqueIdFor( instruction.GetOriginalInstruction().lock().get()); - gd::String outputCode = codeGenerator.GenerateUpperScopeBooleanFullName( - "isConditionTrue", context) + - " = "; + gd::String outputCode = + codeGenerator.GenerateUpperScopeBooleanFullName( + "isConditionTrue", context) + + " = "; gd::String contextObjectName = codeGenerator.HasProjectAndLayout() ? "runtimeScene" : "eventsFunctionContext"; @@ -366,6 +365,73 @@ CommonInstructionsExtension::CommonInstructionsExtension() { return outputCode; }); + GetAllConditions()["BuiltinCommonInstructions::OncePerObject"] + .codeExtraInformation + .SetCustomCodeGenerator([](gd::Instruction& instruction, + gd::EventsCodeGenerator& codeGenerator, + gd::EventsCodeGenerationContext& context) + -> gd::String { + gd::String objectName = instruction.GetParameter(0).GetPlainString(); + + if (!codeGenerator.GetObjectsAndGroups().HasObjectNamed(objectName) && + !codeGenerator.GetGlobalObjectsAndGroups().HasObjectNamed( + objectName) && + !codeGenerator.GetObjectsAndGroups().GetObjectGroups().Has( + objectName) && + !codeGenerator.GetGlobalObjectsAndGroups().GetObjectGroups().Has( + objectName)) { + return "/* Unknown object - skipped. */"; + } + + size_t uniqueId = codeGenerator.GenerateSingleUsageUniqueIdFor( + instruction.GetOriginalInstruction().lock().get()); + + gd::String conditionCode = ""; + std::vector realObjects = + codeGenerator.ExpandObjectsName(objectName, context); + for (std::size_t i = 0; i < realObjects.size(); ++i) { + // Set up the context + gd::String objectType = + gd::GetTypeOfObject(codeGenerator.GetGlobalObjectsAndGroups(), + codeGenerator.GetObjectsAndGroups(), + realObjects[i]); + + context.SetCurrentObject(realObjects[i]); + context.ObjectsListNeeded(realObjects[i]); + + conditionCode += + "for (var i = 0, k = 0, l = " + + codeGenerator.GetObjectListName(objectName, context) + + ".length;i Date: Sat, 12 Aug 2023 19:08:22 +0200 Subject: [PATCH 2/3] Rename to OncePerInstance --- Core/GDCore/Extensions/Builtin/CommonInstructionsExtension.cpp | 2 +- GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/GDCore/Extensions/Builtin/CommonInstructionsExtension.cpp b/Core/GDCore/Extensions/Builtin/CommonInstructionsExtension.cpp index bd4b4739cc49..2beb07b94842 100644 --- a/Core/GDCore/Extensions/Builtin/CommonInstructionsExtension.cpp +++ b/Core/GDCore/Extensions/Builtin/CommonInstructionsExtension.cpp @@ -99,7 +99,7 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension( "res/conditions/once.png"); extension - .AddCondition("OncePerObject", + .AddCondition("OncePerInstance", _("Trigger once while true for an object"), _("Run actions only once per instance of an object every " "time the previous conditions start matching."), diff --git a/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp b/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp index e0b2ae7b8f6b..7c8067607118 100644 --- a/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp +++ b/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp @@ -365,7 +365,7 @@ CommonInstructionsExtension::CommonInstructionsExtension() { return outputCode; }); - GetAllConditions()["BuiltinCommonInstructions::OncePerObject"] + GetAllConditions()["BuiltinCommonInstructions::OncePerInstance"] .codeExtraInformation .SetCustomCodeGenerator([](gd::Instruction& instruction, gd::EventsCodeGenerator& codeGenerator, From 620433263f22a7a942bf503239fb66f30c4677ad Mon Sep 17 00:00:00 2001 From: Arthur Pacaud Date: Sat, 12 Aug 2023 19:12:19 +0200 Subject: [PATCH 3/3] Remove the (obsolete?) `.codeExtraInformation` accessor --- GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp b/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp index 4a1fe46d98c8..fefc905bc0f4 100644 --- a/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp +++ b/GDJS/GDJS/Extensions/Builtin/CommonInstructionsExtension.cpp @@ -366,7 +366,6 @@ CommonInstructionsExtension::CommonInstructionsExtension() { }); GetAllConditions()["BuiltinCommonInstructions::OncePerInstance"] - .codeExtraInformation .SetCustomCodeGenerator([](gd::Instruction& instruction, gd::EventsCodeGenerator& codeGenerator, gd::EventsCodeGenerationContext& context)