Add action to set function return value and expressions to get arguments

Also fix unselection of an event function in IDE
This commit is contained in:
Florian Rival
2018-10-06 16:28:01 +01:00
parent a790be3c37
commit 53a5dc1742
8 changed files with 307 additions and 13 deletions

View File

@@ -643,6 +643,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
argOutput += (parameter == "yes" || parameter == "oui") ? GenerateTrue()
: GenerateFalse();
} else if (metadata.type == "trueorfalse") {
// This is duplicated in AdvancedExtension.cpp for GDJS
argOutput += (parameter == "True" || parameter == "Vrai") ? GenerateTrue()
: GenerateFalse();
}

View File

@@ -32,6 +32,62 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"res/conditions/toujours.png")
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced();
extension
.AddAction(
"SetReturnNumber",
_("Set number return value"),
_("Set the return value of the events function to the specified "
"number (to be used with \"Expression\" functions)."),
_("Set return value to number _PARAM0_"),
_("Advanced/Functions"),
"res/function24.png",
"res/function16.png")
.AddParameter("expression", "The number to be returned")
.MarkAsAdvanced();
extension
.AddAction(
"SetReturnString",
_("Set text return value"),
_("Set the return value of the events function to the specified text "
"(to be used with \"String Expression\" functions)."),
_("Set return value to text _PARAM0_"),
_("Advanced/Functions"),
"res/function24.png",
"res/function16.png")
.AddParameter("expression", "The text to be returned")
.MarkAsAdvanced();
extension
.AddAction("SetReturnBoolean",
_("Set condition return value"),
_("Set the return value of the Condition events function to "
"either true (condition will pass) or false."),
_("Set return value of the condition to _PARAM0_"),
_("Advanced/Functions"),
"res/function24.png",
"res/function16.png")
.AddParameter("trueorfalse", "Should the condition be true or false?")
.MarkAsAdvanced();
extension
.AddExpression(
"GetArgumentAsNumber",
_("Get function parameter value"),
_("Get function parameter (also called \"argument\") value"),
_("Functions"),
"res/function16.png")
.AddParameter("string", "Parameter name");
extension
.AddStrExpression(
"GetArgumentAsString",
_("Get function parameter text"),
_("Get function parameter (also called \"argument\") text "),
_("Functions"),
"res/function16.png")
.AddParameter("string", "Parameter name");
#endif
}

View File

@@ -145,7 +145,7 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionCode(
eventsFunction.GetParameters()) +
"\n" + globalObjectListsReset + "\n" +
codeGenerator.GetCustomCodeInMain() + wholeEventsCode + "\n" +
"return;\n" + "}\n";
codeGenerator.GenerateEventsFunctionReturn(eventsFunction) + "\n" + "}\n";
includeFiles.insert(codeGenerator.GetIncludeFiles().begin(),
codeGenerator.GetIncludeFiles().end());
@@ -189,6 +189,21 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionContext(
" return \"\";" + " }\n" + "};\n";
}
gd::String EventsCodeGenerator::GenerateEventsFunctionReturn(
const gd::EventsFunction& eventsFunction) {
if (eventsFunction.GetFunctionType() == gd::EventsFunction::Condition) {
return "return !!eventsFunctionContext.returnValue;";
} else if (eventsFunction.GetFunctionType() ==
gd::EventsFunction::Expression) {
return "return Number(eventsFunctionContext.returnValue) || 0;";
} else if (eventsFunction.GetFunctionType() ==
gd::EventsFunction::StringExpression) {
return "return \"\" + eventsFunctionContext.returnValue;";
}
return "return;";
}
std::pair<gd::String, gd::String>
EventsCodeGenerator::GenerateAllObjectsDeclarationsAndResets(
unsigned int maxDepthLevelReached) {

View File

@@ -258,6 +258,8 @@ class EventsCodeGenerator : public gd::EventsCodeGenerator {
const std::vector<gd::ParameterMetadata>& parameters);
gd::String GenerateEventsFunctionContext(
const std::vector<gd::ParameterMetadata>& parameters);
gd::String GenerateEventsFunctionReturn(
const gd::EventsFunction & eventFunction);
/**
* \brief Construct a code generator for the specified project and layout.

View File

@@ -5,7 +5,9 @@
*/
#include "AdvancedExtension.h"
#include "GDCore/CommonTools.h"
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
#include "GDCore/Tools/Localization.h"
@@ -16,6 +18,113 @@ AdvancedExtension::AdvancedExtension() {
GetAllConditions()["Toujours"].SetFunctionName(
"gdjs.evtTools.common.logicalNegation");
GetAllActions()["SetReturnNumber"]
.GetCodeExtraInformation()
.SetCustomCodeGenerator([](gd::Instruction& instruction,
gd::EventsCodeGenerator& codeGenerator,
gd::EventsCodeGenerationContext& context) {
gd::String expressionCode;
{
gd::CallbacksForGeneratingExpressionCode callbacks(
expressionCode, codeGenerator, context);
gd::ExpressionParser parser(
instruction.GetParameter(0).GetPlainString());
if (!parser.ParseMathExpression(
codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
callbacks) ||
expressionCode.empty())
expressionCode = "0";
}
return "eventsFunctionContext.returnValue = " + expressionCode + ";";
});
GetAllActions()["SetReturnString"]
.GetCodeExtraInformation()
.SetCustomCodeGenerator([](gd::Instruction& instruction,
gd::EventsCodeGenerator& codeGenerator,
gd::EventsCodeGenerationContext& context) {
gd::String expressionCode;
{
gd::CallbacksForGeneratingExpressionCode callbacks(
expressionCode, codeGenerator, context);
gd::ExpressionParser parser(
instruction.GetParameter(0).GetPlainString());
if (!parser.ParseStringExpression(
codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
callbacks) ||
expressionCode.empty())
expressionCode = "\"\"";
}
return "eventsFunctionContext.returnValue = " + expressionCode + ";";
});
GetAllActions()["SetReturnBoolean"]
.GetCodeExtraInformation()
.SetCustomCodeGenerator([](gd::Instruction& instruction,
gd::EventsCodeGenerator& codeGenerator,
gd::EventsCodeGenerationContext& context) {
// This is duplicated from EventsCodeGenerator::GenerateParameterCodes
gd::String parameter = instruction.GetParameter(0).GetPlainString();
gd::String booleanCode =
(parameter == "True" || parameter == "Vrai") ? "true" : "false";
return "eventsFunctionContext.returnValue = " + booleanCode + ";";
});
auto generateParameterNameCode =
[](const std::vector<gd::Expression>& parameters,
gd::EventsCodeGenerator& codeGenerator,
gd::EventsCodeGenerationContext& context) {
gd::String parameterNameCode;
{
gd::CallbacksForGeneratingExpressionCode callbacks(
parameterNameCode, codeGenerator, context);
gd::ExpressionParser parser(
!parameters.empty() ? parameters[0].GetPlainString() : "");
if (!parser.ParseStringExpression(
codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
callbacks) ||
parameterNameCode.empty())
parameterNameCode = "\"\"";
}
return parameterNameCode;
};
GetAllExpressions()["GetArgumentAsNumber"]
.GetCodeExtraInformation()
.SetCustomCodeGenerator([&generateParameterNameCode](
const std::vector<gd::Expression>& parameters,
gd::EventsCodeGenerator& codeGenerator,
gd::EventsCodeGenerationContext& context) {
gd::String parameterNameCode =
generateParameterNameCode(parameters, codeGenerator, context);
return "(Number(eventsFunctionContext.getArgument(" +
parameterNameCode + ")) || 0)";
});
GetAllExpressions()["GetArgumentAsString"]
.GetCodeExtraInformation()
.SetCustomCodeGenerator([&generateParameterNameCode](
const std::vector<gd::Expression>& parameters,
gd::EventsCodeGenerator& codeGenerator,
gd::EventsCodeGenerationContext& context) {
gd::String parameterNameCode =
generateParameterNameCode(parameters, codeGenerator, context);
return "(\"\" + eventsFunctionContext.getArgument(" +
parameterNameCode + "))";
});
}
} // namespace gdjs

View File

@@ -12,7 +12,7 @@
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.platformer",
"projectFile": "/Users/florianrival/GDevelop projects/My project952/platformer.json",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/events-function (and events-functions-extensions)/platformer with events functions.json",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
@@ -3638,7 +3638,18 @@
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"conditions": [
{
"type": {
"inverted": false,
"value": "RotaterExtension::AlwaysTrue"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
@@ -3661,7 +3672,8 @@
},
"parameters": [
"",
"Platform"
"Platform",
"35"
],
"subInstructions": []
}
@@ -5208,7 +5220,7 @@
"fullName": "t",
"functionType": "Action",
"name": "RotatePlease",
"sentence": "Rotate the _PARAM1_",
"sentence": "Rotate the _PARAM1_ at speed _PARAM2_deg/sec",
"events": [
{
"disabled": false,
@@ -5223,7 +5235,7 @@
},
"parameters": [
"Hello",
"15",
"GetArgumentAsNumber(\"Speed\")",
""
],
"subInstructions": []
@@ -5250,6 +5262,93 @@
"optional": false,
"supplementaryInformation": "",
"type": "objectList"
},
{
"codeOnly": false,
"defaultValue": "",
"description": "Rotation speed",
"name": "Speed",
"optional": false,
"supplementaryInformation": "",
"type": "expression"
}
]
},
{
"description": "Always true",
"fullName": "Always true",
"functionType": "Condition",
"name": "AlwaysTrue",
"sentence": "Always true",
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "SetReturnBoolean"
},
"parameters": [
"True"
],
"subInstructions": []
}
],
"events": []
}
],
"parameters": [
{
"codeOnly": true,
"defaultValue": "",
"description": "",
"name": "runtimeScene",
"optional": false,
"supplementaryInformation": "",
"type": "currentScene"
}
]
},
{
"description": "Return a speed of rotation",
"fullName": "Speed of rotation",
"functionType": "Expression",
"name": "GetSpeed",
"sentence": "",
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "SetReturnNumber"
},
"parameters": [
"25"
],
"subInstructions": []
}
],
"events": []
}
],
"parameters": [
{
"codeOnly": true,
"defaultValue": "",
"description": "",
"name": "runtimeScene",
"optional": false,
"supplementaryInformation": "",
"type": "currentScene"
}
]
}

View File

@@ -56,10 +56,22 @@ export default class EventsFunctionsExtensionEditor extends React.Component<
};
updateToolbar() {
if (this.editor) this.editor.updateToolbar();
if (this.editor) {
this.editor.updateToolbar();
} else {
this.props.setToolbar(<div />);
}
}
_selectEventsFunction = (selectedEventsFunction: gdEventsFunction) => {
_selectEventsFunction = (selectedEventsFunction: ?gdEventsFunction) => {
if (!selectedEventsFunction) {
this.setState({
selectedEventsFunction: null,
},
() => this.updateToolbar())
return;
}
this._loadEventsFunctionFrom(this.props.project, selectedEventsFunction);
this.setState(
{

View File

@@ -28,10 +28,10 @@ type Props = {|
project: gdProject,
eventsFunctions: gdVectorEventsFunction,
selectedEventsFunction: ?gdEventsFunction,
onSelectEventsFunction: (resource: gdEventsFunction) => void,
onDeleteEventsFunction: (resource: gdEventsFunction) => void,
onSelectEventsFunction: (eventsFunction: ?gdEventsFunction) => void,
onDeleteEventsFunction: (eventsFunction: gdEventsFunction) => void,
onRenameEventsFunction: (
resource: gdEventsFunction,
eventsFunction: gdEventsFunction,
newName: string,
cb: (boolean) => void
) => void,
@@ -40,10 +40,10 @@ type Props = {|
export default class EventsFunctionsList extends React.Component<Props, State> {
static defaultProps = {
onDeleteEventsFunction: (resource: gdEventsFunction, cb: boolean => void) =>
onDeleteEventsFunction: (eventsFunction: gdEventsFunction, cb: boolean => void) =>
cb(true),
onRenameEventsFunction: (
resource: gdEventsFunction,
eventsFunction: gdEventsFunction,
newName: string,
cb: boolean => void
) => cb(true),