GDevelop Core
Core library for developing platforms and tools compatible with GDevelop.
EventsCodeGenerator.h
1 /*
2  * GDevelop Core
3  * Copyright 2008-present Florian Rival ([email protected]). All rights
4  * reserved. This project is released under the MIT License.
5  */
6 #pragma once
7 
8 #include <set>
9 #include <utility>
10 #include <vector>
11 
12 #include "GDCore/Events/CodeGeneration/DiagnosticReport.h"
13 #include "GDCore/Events/Event.h"
14 #include "GDCore/Events/Instruction.h"
15 #include "GDCore/Project/ProjectScopedContainers.h"
16 #include "GDCore/String.h"
17 
18 namespace gd {
19 class EventsList;
20 class Expression;
21 class Project;
22 class Layout;
23 class ObjectsContainer;
24 class ObjectsContainersList;
25 class ExternalEvents;
26 class ParameterMetadata;
27 class ObjectMetadata;
28 class BehaviorMetadata;
29 class InstructionMetadata;
30 class EventsCodeGenerationContext;
31 class ExpressionCodeGenerationInformation;
32 class InstructionMetadata;
33 class Platform;
34 } // namespace gd
35 
36 namespace gd {
37 
41 class GD_CORE_API EventsCodeGenerator {
42  friend class ExpressionCodeGenerator;
43 
44  public:
48  static void DeleteUselessEvents(gd::EventsList& events);
49 
54  EventsCodeGenerator(const gd::Project& project_,
55  const gd::Layout& layout,
56  const gd::Platform& platform_);
57 
63  const gd::Platform& platform,
64  const gd::ProjectScopedContainers& projectScopedContainers_);
65  virtual ~EventsCodeGenerator() {};
66 
73  void PreprocessEventList(gd::EventsList& listEvent);
74 
82  virtual gd::String GenerateEventsListCode(
84 
98  virtual gd::String GenerateConditionsListCode(
100 
112  virtual gd::String GenerateActionsListCode(
114 
129  std::vector<gd::String> GenerateParametersCodes(
130  const std::vector<gd::Expression>& parameters,
131  const ParameterMetadataContainer& parametersInfo,
133  std::vector<std::pair<gd::String, gd::String> >*
134  supplementaryParametersTypes = 0);
135 
146  gd::String GenerateConditionCode(gd::Instruction& condition,
147  gd::String returnBoolean,
148  EventsCodeGenerationContext& context);
149 
160  gd::String GenerateActionCode(
161  gd::Instruction& action,
163  const gd::String& optionalAsyncCallbackName = "",
164  const gd::String& optionalAsyncCallbackId = "");
165 
167  CallbackDescriptor(const gd::String functionName_,
168  const gd::String argumentsList_,
169  const std::set<gd::String> requiredObjects_)
170  : functionName(functionName_),
171  argumentsList(argumentsList_),
172  requiredObjects(requiredObjects_) {};
185  const std::set<gd::String> requiredObjects;
186  };
187 
198  virtual const CallbackDescriptor GenerateCallback(
199  const gd::String& callbackFunctionName,
200  gd::EventsCodeGenerationContext& parentContext,
201  gd::InstructionsList& actions,
202  gd::EventsList* subEvents = nullptr);
203 
207  const gd::String GenerateEventsParameters(
208  const gd::EventsCodeGenerationContext& context);
209 
217  virtual gd::String GenerateObjectsDeclarationCode(
218  EventsCodeGenerationContext& context);
219 
235  static gd::String ConvertToString(gd::String plainString);
236 
253  static gd::String ConvertToStringExplicit(gd::String plainString);
254 
264  if (!file.empty()) includeFiles.insert(file);
265  };
266 
271  void AddIncludeFiles(std::vector<gd::String> files) {
272  for (std::size_t i = 0; i < files.size(); ++i) AddIncludeFile(files[i]);
273  };
274 
278  void AddGlobalDeclaration(gd::String declaration) {
279  customGlobalDeclarations.insert(declaration);
280  };
281 
286  customCodeOutsideMain += code;
287  };
288 
291  const std::set<gd::String>& GetIncludeFiles() const { return includeFiles; }
292 
296  return customCodeOutsideMain;
297  }
298 
301  const std::set<gd::String>& GetCustomGlobalDeclaration() const {
302  return customGlobalDeclarations;
303  }
304 
308  bool GenerateCodeForRuntime() { return compilationForRuntime; }
309 
314  void SetGenerateCodeForRuntime(bool compilationForRuntime_) {
315  compilationForRuntime = compilationForRuntime_;
316  }
317 
322  void ReportError();
323 
331  bool ErrorOccurred() const { return errorOccurred; };
332 
333  const gd::ObjectsContainersList& GetObjectsContainersList() const {
334  return projectScopedContainers.GetObjectsContainersList();
335  };
336 
337  const gd::ProjectScopedContainers& GetProjectScopedContainers() const {
338  return projectScopedContainers;
339  }
340 
348  return projectScopedContainers;
349  }
350 
355  bool HasProjectAndLayout() const { return hasProjectAndLayout; }
356 
361  const gd::Project& GetProject() const { return *project; }
362 
367  const gd::Layout& GetLayout() const { return *scene; }
368 
372  const gd::Platform& GetPlatform() const { return platform; }
373 
379  return maxCustomConditionsDepth;
380  }
381 
385  size_t GetMaxConditionsListsSize() const { return maxConditionsListsSize; }
386 
387  void SetDiagnosticReport(gd::DiagnosticReport* diagnosticReport_) {
388  diagnosticReport = diagnosticReport_;
389  }
390 
391  gd::DiagnosticReport* GetDiagnosticReport() { return diagnosticReport; }
392 
400  const gd::String& boolName,
401  const gd::EventsCodeGenerationContext& context) {
402  return boolName;
403  }
404 
412  const gd::String& boolName,
413  const gd::EventsCodeGenerationContext& context) {
414  return boolName;
415  }
416 
423  const gd::String& boolName,
424  const gd::EventsCodeGenerationContext& context) {
425  return "bool " + boolName + " = false;\n";
426  }
427 
434  virtual gd::String GetObjectListName(
435  const gd::String& name, const gd::EventsCodeGenerationContext& context);
436 
442  return "";
443  };
444 
449  return "";
450  };
451 
459  virtual gd::String GetCodeNamespaceAccessor() { return ""; };
460 
467  virtual gd::String GetCodeNamespace() { return ""; };
468 
469  enum VariableScope {
470  LAYOUT_VARIABLE = 0,
471  PROJECT_VARIABLE,
472  OBJECT_VARIABLE,
473  ANY_VARIABLE,
474  VARIABLE_OR_PROPERTY,
475  VARIABLE_OR_PROPERTY_OR_PARAMETER
476  };
477 
490  size_t GenerateSingleUsageUniqueIdFor(const gd::Instruction* instruction);
491 
499  size_t GenerateSingleUsageUniqueIdForEventsList();
500 
501  virtual gd::String GenerateRelationalOperation(
502  const gd::String& relationalOperator,
503  const gd::String& lhs,
504  const gd::String& rhs);
505 
509  virtual gd::String GenerateLocalVariablesStackAccessor();
510 
515  gd::String GenerateAnyOrSceneVariableGetter(
516  const gd::Expression& variableExpression,
517  EventsCodeGenerationContext& context);
518 
519  virtual gd::String GeneratePropertySetterWithoutCasting(
520  const gd::PropertiesContainer& propertiesContainer,
521  const gd::NamedPropertyDescriptor& property,
522  const gd::String& operandCode);
523 
524  protected:
525  virtual const gd::String GenerateRelationalOperatorCodes(
526  const gd::String& operatorString);
527 
564  virtual gd::String GenerateParameterCodes(
565  const gd::Expression& parameter,
566  const gd::ParameterMetadata& metadata,
568  const gd::String& lastObjectName,
569  std::vector<std::pair<gd::String, gd::String> >*
570  supplementaryParametersTypes);
571 
576  const gd::String& variableName,
577  const VariableScope& scope,
579  const gd::String& objectName,
580  bool hasChild) {
581  // This code is only used as a mock.
582  // See the real implementation in GDJS.
583  if (scope == LAYOUT_VARIABLE) {
584  return "getLayoutVariable(" + variableName + ")";
585 
586  } else if (scope == PROJECT_VARIABLE) {
587  return "getProjectVariable(" + variableName + ")";
588  } else if (scope == ANY_VARIABLE || scope == VARIABLE_OR_PROPERTY ||
589  scope == VARIABLE_OR_PROPERTY_OR_PARAMETER) {
590  // TODO Split the 3 cases to make tests stronger.
591  return "getAnyVariable(" + variableName + ")";
592  }
593 
594  return "getVariableForObject(" + objectName + ", " + variableName + ")";
595  }
596 
601  return ".getChild(" + ConvertToStringExplicit(childName) + ")";
602  };
603 
604  virtual gd::String GenerateVariableValueAs(const gd::String& type) {
605  return type == "number|string" ? ".getAsNumberOrString()"
606  : type == "string" ? ".getAsString()"
607  : ".getAsNumber()";
608  }
609 
615  gd::String expressionCode) {
616  return ".getChild(" + expressionCode + ")";
617  };
618 
623  virtual gd::String GenerateBadVariable() { return "fakeBadVariable"; }
624 
632  virtual gd::String GenerateObject(const gd::String& objectName,
633  const gd::String& type,
635  return "fakeObjectListOf_" + objectName;
636  }
637 
638  virtual gd::String GeneratePropertyGetter(
639  const gd::PropertiesContainer& propertiesContainer,
640  const gd::NamedPropertyDescriptor& property,
641  const gd::String& type,
643 
644  virtual gd::String GeneratePropertyGetterWithoutCasting(
645  const gd::PropertiesContainer& propertiesContainer,
646  const gd::NamedPropertyDescriptor& property);
647 
648  virtual gd::String GenerateParameterGetter(
649  const gd::ParameterMetadata& parameter,
650  const gd::String& type,
652 
653  virtual gd::String GenerateParameterGetterWithoutCasting(
654  const gd::ParameterMetadata& parameter);
655 
660  virtual gd::String GenerateBadObject() { return "fakeNullObject"; }
661 
674  virtual gd::String GenerateObjectFunctionCall(
675  gd::String objectListName,
676  const ObjectMetadata& objMetadata,
678  gd::String parametersStr,
679  gd::String defaultOutput,
681 
695  virtual gd::String GenerateObjectBehaviorFunctionCall(
696  gd::String objectListName,
697  gd::String behaviorName,
698  const gd::BehaviorMetadata& autoInfo,
700  gd::String parametersStr,
701  gd::String defaultOutput,
703 
713  const gd::String& extraVariable = "") {
714  return "{\n";
715  };
716 
725  const gd::String& extraVariable = "") {
726  return "}\n";
727  };
728 
736  const gd::String& predicate) const {
737  return "!(" + predicate + ")";
738  };
739 
740  virtual gd::String GenerateFreeCondition(
741  const std::vector<gd::String>& arguments,
742  const gd::InstructionMetadata& instrInfos,
743  const gd::String& returnBoolean,
744  bool conditionInverted,
746 
747  virtual gd::String GenerateObjectCondition(
748  const gd::String& objectName,
749  const gd::ObjectMetadata& objInfo,
750  const std::vector<gd::String>& arguments,
751  const gd::InstructionMetadata& instrInfos,
752  const gd::String& returnBoolean,
753  bool conditionInverted,
755 
756  virtual gd::String GenerateBehaviorCondition(
757  const gd::String& objectName,
758  const gd::String& behaviorName,
759  const gd::BehaviorMetadata& autoInfo,
760  const std::vector<gd::String>& arguments,
761  const gd::InstructionMetadata& instrInfos,
762  const gd::String& returnBoolean,
763  bool conditionInverted,
765 
766  virtual gd::String GenerateFreeAction(
767  const gd::String& functionCallName,
768  const std::vector<gd::String>& arguments,
769  const gd::InstructionMetadata& instrInfos,
771  const gd::String& optionalAsyncCallbackName = "",
772  const gd::String& optionalAsyncCallbackId = "");
773 
774  virtual gd::String GenerateObjectAction(
775  const gd::String& objectName,
776  const gd::ObjectMetadata& objInfo,
777  const gd::String& functionCallName,
778  const std::vector<gd::String>& arguments,
779  const gd::InstructionMetadata& instrInfos,
781  const gd::String& optionalAsyncCallbackName = "",
782  const gd::String& optionalAsyncCallbackId = "");
783 
784  virtual gd::String GenerateBehaviorAction(
785  const gd::String& objectName,
786  const gd::String& behaviorName,
787  const gd::BehaviorMetadata& autoInfo,
788  const gd::String& functionCallName,
789  const std::vector<gd::String>& arguments,
790  const gd::InstructionMetadata& instrInfos,
792  const gd::String& optionalAsyncCallbackName = "",
793  const gd::String& optionalAsyncCallbackId = "");
794 
795  gd::String GenerateRelationalOperatorCall(
796  const gd::InstructionMetadata& instrInfos,
797  const std::vector<gd::String>& arguments,
798  const gd::String& callStartString,
799  std::size_t startFromArgument = 0);
800 
801  gd::String GenerateOperatorCall(const gd::InstructionMetadata& instrInfos,
802  const std::vector<gd::String>& arguments,
803  const gd::String& callStartString,
804  const gd::String& getterStartString,
805  std::size_t startFromArgument = 0);
806  gd::String GenerateCompoundOperatorCall(
807  const gd::InstructionMetadata& instrInfos,
808  const std::vector<gd::String>& arguments,
809  const gd::String& callStartString,
810  std::size_t startFromArgument = 0);
811  gd::String GenerateMutatorCall(const gd::InstructionMetadata& instrInfos,
812  const std::vector<gd::String>& arguments,
813  const gd::String& callStartString,
814  std::size_t startFromArgument = 0);
815 
819  gd::String GenerateTrue() const { return "true"; };
820 
824  gd::String GenerateFalse() const { return "false"; };
825 
833  virtual gd::String GenerateArgumentsList(
834  const std::vector<gd::String>& arguments, size_t startFrom = 0);
835 
839  virtual gd::String GenerateGetBehaviorNameCode(
840  const gd::String& behaviorName);
841 
842  bool CheckBehaviorParameters(const gd::Instruction& instruction,
843  const gd::InstructionMetadata& instrInfos);
844 
846 
847  gd::ProjectScopedContainers projectScopedContainers;
848 
852  const gd::Layout* scene;
853 
857 
858  std::set<gd::String>
864  std::set<gd::String>
870 
871  std::set<size_t>
875 
876  gd::DiagnosticReport* diagnosticReport;
877 };
878 
879 } // namespace gd
Contains user-friendly information about a behavior type.
Definition: BehaviorMetadata.h:32
Definition: DiagnosticReport.h:57
Used to manage the context when generating code for events.
Definition: EventsCodeGenerationContext.h:27
Internal class used to generate code from events.
Definition: EventsCodeGenerator.h:41
virtual gd::String GenerateNegatedPredicate(const gd::String &predicate) const
Must negate a predicate.
Definition: EventsCodeGenerator.h:735
size_t GetMaxConditionsListsSize() const
Get the maximum size of a list of conditions.
Definition: EventsCodeGenerator.h:385
const gd::Project * project
The project being used.
Definition: EventsCodeGenerator.h:851
void AddIncludeFiles(std::vector< gd::String > files)
Declare a list of include files to be added.
Definition: EventsCodeGenerator.h:271
virtual gd::String GetCodeNamespace()
Get the namespace to be used to store code generated objects/values/functions.
Definition: EventsCodeGenerator.h:467
const gd::Platform & GetPlatform() const
Get the platform the code is being generated for.
Definition: EventsCodeGenerator.h:372
virtual gd::String GenerateUpperScopeBooleanFullName(const gd::String &boolName, const gd::EventsCodeGenerationContext &context)
Generate the full name for accessing to a boolean variable used for conditions.
Definition: EventsCodeGenerator.h:411
void AddGlobalDeclaration(gd::String declaration)
Add a declaration which will be inserted after includes.
Definition: EventsCodeGenerator.h:278
virtual gd::String GenerateVariableBracketAccessor(gd::String expressionCode)
Generate the code to get the child of a variable, using generated the expression.
Definition: EventsCodeGenerator.h:614
const std::set< gd::String > & GetIncludeFiles() const
Get the set containing the include files.
Definition: EventsCodeGenerator.h:291
void SetGenerateCodeForRuntime(bool compilationForRuntime_)
Set if the code generated is meant to be used for runtime only and not in the IDE.
Definition: EventsCodeGenerator.h:314
size_t maxCustomConditionsDepth
Definition: EventsCodeGenerator.h:867
virtual gd::String GenerateScopeBegin(gd::EventsCodeGenerationContext &context, const gd::String &extraVariable="")
Called when a new scope must be entered.
Definition: EventsCodeGenerator.h:711
bool compilationForRuntime
Definition: EventsCodeGenerator.h:855
const gd::Platform & platform
The platform being used.
Definition: EventsCodeGenerator.h:845
virtual gd::String GenerateProfilerSectionBegin(const gd::String &section)
Generate the code to notify the profiler of the beginning of a section.
Definition: EventsCodeGenerator.h:441
const gd::Layout * scene
The scene being generated.
Definition: EventsCodeGenerator.h:852
virtual gd::String GenerateBadVariable()
Generate the code to reference a variable which is in an empty/null state.
Definition: EventsCodeGenerator.h:623
virtual gd::String GenerateBooleanInitializationToFalse(const gd::String &boolName, const gd::EventsCodeGenerationContext &context)
Must create a boolean. Its value must be false.
Definition: EventsCodeGenerator.h:422
bool GenerateCodeForRuntime()
Return true if code generation is made for runtime only.
Definition: EventsCodeGenerator.h:308
virtual gd::String GenerateBadObject()
Generate the code to reference an object which is in an empty/null state.
Definition: EventsCodeGenerator.h:660
virtual gd::String GenerateGetVariable(const gd::String &variableName, const VariableScope &scope, gd::EventsCodeGenerationContext &context, const gd::String &objectName, bool hasChild)
Generate the code to get a variable.
Definition: EventsCodeGenerator.h:575
bool hasProjectAndLayout
Definition: EventsCodeGenerator.h:849
gd::String GenerateTrue() const
Return the "true" keyword in the target language.
Definition: EventsCodeGenerator.h:819
size_t GetMaxCustomConditionsDepth() const
Get the maximum depth of custom conditions reached during code generation.
Definition: EventsCodeGenerator.h:378
gd::String GenerateFalse() const
Return the "false" keyword in the target language.
Definition: EventsCodeGenerator.h:824
gd::String customCodeOutsideMain
Definition: EventsCodeGenerator.h:862
size_t maxConditionsListsSize
The maximum size of a list of conditions.
Definition: EventsCodeGenerator.h:869
gd::ProjectScopedContainers & GetProjectScopedContainers()
Give access to the project scoped containers as code generation might push and pop variable container...
Definition: EventsCodeGenerator.h:347
size_t eventsListNextUniqueId
Definition: EventsCodeGenerator.h:873
std::set< gd::String > customGlobalDeclarations
Definition: EventsCodeGenerator.h:865
const std::set< gd::String > & GetCustomGlobalDeclaration() const
Get the custom declaration to be inserted after includes.
Definition: EventsCodeGenerator.h:301
virtual gd::String GenerateObject(const gd::String &objectName, const gd::String &type, gd::EventsCodeGenerationContext &context)
Generate the code to reference an object.
Definition: EventsCodeGenerator.h:632
bool HasProjectAndLayout() const
Return true if the code generation is done for a given project and layout. If not,...
Definition: EventsCodeGenerator.h:355
virtual gd::String GenerateBooleanFullName(const gd::String &boolName, const gd::EventsCodeGenerationContext &context)
Generate the full name for accessing to a boolean variable used for conditions.
Definition: EventsCodeGenerator.h:399
virtual gd::String GenerateProfilerSectionEnd(const gd::String &section)
Generate the code to notify the profiler of the end of a section.
Definition: EventsCodeGenerator.h:448
const gd::String & GetCustomCodeOutsideMain() const
Get the custom code to be inserted outside main.
Definition: EventsCodeGenerator.h:295
const gd::Project & GetProject() const
Get the project the code is being generated for.
Definition: EventsCodeGenerator.h:361
void AddCustomCodeOutsideMain(gd::String code)
Add some code before events outside the main function.
Definition: EventsCodeGenerator.h:285
std::set< gd::String > includeFiles
Definition: EventsCodeGenerator.h:859
void AddIncludeFile(gd::String file)
Declare an include file to be added.
Definition: EventsCodeGenerator.h:263
virtual gd::String GenerateVariableAccessor(gd::String childName)
Generate the code to get the child of a variable.
Definition: EventsCodeGenerator.h:600
bool errorOccurred
Must be set to true if an error occurred.
Definition: EventsCodeGenerator.h:854
virtual gd::String GetCodeNamespaceAccessor()
Get the namespace to be used to store code generated objects/values/functions, with the extra "dot" a...
Definition: EventsCodeGenerator.h:459
bool ErrorOccurred() const
Return true if an error has occurred during code generation (in this case, generated code is not usab...
Definition: EventsCodeGenerator.h:331
std::set< size_t > instructionUniqueIds
The unique ids generated for instructions.
Definition: EventsCodeGenerator.h:872
const gd::Layout & GetLayout() const
Get the layout the code is being generated for.
Definition: EventsCodeGenerator.h:367
virtual gd::String GenerateScopeEnd(gd::EventsCodeGenerationContext &context, const gd::String &extraVariable="")
Called when a new must be ended.
Definition: EventsCodeGenerator.h:724
A list of events.
Definition: EventsList.h:32
Information about how generate code for an expression.
Definition: ExpressionMetadata.h:24
Generate code for a parsed expression.
Definition: ExpressionCodeGenerator.h:35
Class representing an expression used as a parameter of a gd::Instruction. This class is nothing more...
Definition: Expression.h:30
An instruction is a member of an event: It can be a condition or an action.
Definition: Instruction.h:30
Describe user-friendly information about an instruction (action or condition), its parameters and the...
Definition: InstructionMetadata.h:39
Definition: InstructionsList.h:25
Represent a layout ( also called a scene ) of a project.
Definition: Layout.h:40
Used to describe a property shown in a property grid.
Definition: NamedPropertyDescriptor.h:21
Contains user-friendly information about an object type, and a function to create a new gd::Object of...
Definition: ObjectMetadata.h:37
A list of objects containers, useful for accessing objects in a scoped way, along with methods to acc...
Definition: ObjectsContainersList.h:29
Used as a base class for classes that will own events-backed functions.
Definition: ParameterMetadataContainer.h:26
Describe a parameter of an instruction (action, condition) or of an expression: type,...
Definition: ParameterMetadata.h:27
Base class for implementing a platform.
Definition: Platform.h:42
Base class representing a project (game), including all resources, scenes, objects,...
Definition: Project.h:50
Holds references to variables, objects, properties and other containers.
Definition: ProjectScopedContainers.h:34
A container of properties, used for custom behaviors, custom objects, extensions.....
Definition: PropertiesContainer.h:17
String represents an UTF8 encoded string.
Definition: String.h:33
bool empty() const
Returns true if the string is empty.
Definition: String.h:157
Definition: CommonTools.h:24
Definition: EventsCodeGenerator.h:166
const std::set< gd::String > requiredObjects
Definition: EventsCodeGenerator.h:185
const gd::String argumentsList
Definition: EventsCodeGenerator.h:180
const gd::String functionName
Definition: EventsCodeGenerator.h:172