mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Merge pull request #291 from 4ian/fix/code-generation
Fix code generation when multiple scenes link to the same events
This commit is contained in:
@@ -42,7 +42,7 @@ const EventsList * LinkEvent::GetLinkedEvents(const gd::Project & project) const
|
||||
return events;
|
||||
}
|
||||
|
||||
void LinkEvent::ReplaceLinkByLinkedEvents(gd::Project & project, EventsList & eventList, std::size_t indexOfTheEventInThisList)
|
||||
void LinkEvent::ReplaceLinkByLinkedEvents(const gd::Project & project, EventsList & eventList, std::size_t indexOfTheEventInThisList)
|
||||
{
|
||||
linkWasInvalid = false;
|
||||
//Finding what to link to.
|
||||
|
@@ -75,7 +75,7 @@ public:
|
||||
* When implementing a platform with a link event, you should call this function when preprocessing the events
|
||||
* (See gd::EventMetadata::codeGeneration).
|
||||
*/
|
||||
void ReplaceLinkByLinkedEvents(gd::Project & project, EventsList & eventList, std::size_t indexOfTheEventInThisList);
|
||||
void ReplaceLinkByLinkedEvents(const gd::Project & project, EventsList & eventList, std::size_t indexOfTheEventInThisList);
|
||||
|
||||
virtual bool IsExecutable() const { return true; };
|
||||
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/Builtin/GroupEvent.h"
|
||||
@@ -20,6 +21,29 @@
|
||||
#include <memory>
|
||||
|
||||
TEST_CASE( "Events", "[common][events]" ) {
|
||||
SECTION("InstructionsList") {
|
||||
gd::InstructionsList list;
|
||||
gd::Instruction instr("InstructionType");
|
||||
list.Insert(instr);
|
||||
list.Insert(instr);
|
||||
list.Insert(instr);
|
||||
|
||||
REQUIRE( list.size() == 3 );
|
||||
list[1].SetType("ChangedInstructionType");
|
||||
|
||||
REQUIRE( list[0].GetType() == "InstructionType" );
|
||||
REQUIRE( list[1].GetType() == "ChangedInstructionType" );
|
||||
|
||||
gd::InstructionsList list2 = list;
|
||||
REQUIRE( list2.size() == 3 );
|
||||
list2[0].SetType("YetAnotherInstructionType");
|
||||
|
||||
REQUIRE( list2[0].GetType() == "YetAnotherInstructionType" );
|
||||
REQUIRE( list2[1].GetType() == "ChangedInstructionType" );
|
||||
REQUIRE( list[0].GetType() == "InstructionType" );
|
||||
REQUIRE( list[1].GetType() == "ChangedInstructionType" );
|
||||
}
|
||||
|
||||
SECTION("StandardEvent") {
|
||||
gd::Instruction instr("InstructionType");
|
||||
gd::StandardEvent event;
|
||||
@@ -29,6 +53,10 @@ TEST_CASE( "Events", "[common][events]" ) {
|
||||
std::shared_ptr<gd::StandardEvent> cloned(event.Clone());
|
||||
REQUIRE( cloned->GetActions().size() == 1 );
|
||||
REQUIRE( cloned->GetActions()[0].GetType() == "InstructionType" );
|
||||
|
||||
cloned->GetActions()[0].SetType("ChangedInstructionType");
|
||||
REQUIRE( cloned->GetActions()[0].GetType() == "ChangedInstructionType" );
|
||||
REQUIRE( event.GetActions()[0].GetType() == "InstructionType" );
|
||||
}
|
||||
|
||||
SECTION("ForEachEvent") {
|
||||
|
@@ -409,18 +409,22 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(const gd::String & parame
|
||||
return argOutput;
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateSceneEventsCompleteCode(gd::Project & project, gd::Layout & scene, gd::EventsList & events, bool compilationForRuntime)
|
||||
gd::String EventsCodeGenerator::GenerateSceneEventsCompleteCode(gd::Project & project, gd::Layout & scene, const gd::EventsList & events, bool compilationForRuntime)
|
||||
{
|
||||
// Preprocessing then code generation can make changes to the events, so we need to do
|
||||
// the work on a copy of the events.
|
||||
gd::EventsList generatedEvents = events;
|
||||
|
||||
gd::String output;
|
||||
|
||||
//Prepare the global context ( Used to get needed header files )
|
||||
gd::EventsCodeGenerationContext context;
|
||||
EventsCodeGenerator codeGenerator(project, scene);
|
||||
codeGenerator.PreprocessEventList(scene.GetEvents());
|
||||
codeGenerator.SetGenerateCodeForRuntime(compilationForRuntime);
|
||||
|
||||
//Generate whole events code
|
||||
gd::String wholeEventsCode = codeGenerator.GenerateEventsListCode(events, context);
|
||||
codeGenerator.SetGenerateCodeForRuntime(compilationForRuntime);
|
||||
codeGenerator.PreprocessEventList(generatedEvents);
|
||||
gd::String wholeEventsCode = codeGenerator.GenerateEventsListCode(generatedEvents, context);
|
||||
|
||||
//Generate default code around events:
|
||||
//Includes
|
||||
|
@@ -31,7 +31,7 @@ public:
|
||||
* \param compilationForRuntime Set this to true if the code is generated for runtime.
|
||||
* \return C++ code
|
||||
*/
|
||||
static gd::String GenerateSceneEventsCompleteCode(gd::Project & project, gd::Layout & scene, gd::EventsList & events, bool compilationForRuntime = false);
|
||||
static gd::String GenerateSceneEventsCompleteCode(gd::Project & project, gd::Layout & scene, const gd::EventsList & events, bool compilationForRuntime = false);
|
||||
|
||||
/**
|
||||
* Generate complete C++ file for compiling external events.
|
||||
|
@@ -29,22 +29,24 @@ namespace gdjs
|
||||
{
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateSceneEventsCompleteCode(gd::Project & project,
|
||||
gd::Layout & scene,
|
||||
gd::EventsList & events,
|
||||
std::set < gd::String > & includeFiles,
|
||||
bool compilationForRuntime)
|
||||
const gd::Layout & scene, const gd::EventsList & events, std::set < gd::String > & includeFiles,
|
||||
bool compilationForRuntime)
|
||||
{
|
||||
// Preprocessing then code generation can make changes to the events, so we need to do
|
||||
// the work on a copy of the events.
|
||||
gd::EventsList generatedEvents = events;
|
||||
|
||||
gd::String output = "gdjs."+gd::SceneNameMangler::GetMangledSceneName(scene.GetName())+"Code = {};\n";
|
||||
|
||||
//Prepare the global context
|
||||
unsigned int maxDepthLevelReached = 0;
|
||||
gd::EventsCodeGenerationContext context(&maxDepthLevelReached);
|
||||
EventsCodeGenerator codeGenerator(project, scene);
|
||||
codeGenerator.SetGenerateCodeForRuntime(compilationForRuntime);
|
||||
codeGenerator.PreprocessEventList(events);
|
||||
|
||||
//Generate whole events code
|
||||
gd::String wholeEventsCode = codeGenerator.GenerateEventsListCode(events, context);
|
||||
codeGenerator.SetGenerateCodeForRuntime(compilationForRuntime);
|
||||
codeGenerator.PreprocessEventList(generatedEvents);
|
||||
gd::String wholeEventsCode = codeGenerator.GenerateEventsListCode(generatedEvents, context);
|
||||
|
||||
//Extra declarations needed by events
|
||||
for ( set<gd::String>::iterator declaration = codeGenerator.GetCustomGlobalDeclaration().begin() ;
|
||||
@@ -52,7 +54,7 @@ gd::String EventsCodeGenerator::GenerateSceneEventsCompleteCode(gd::Project & pr
|
||||
output += *declaration+"\n";
|
||||
|
||||
//Global objects lists
|
||||
auto generateDeclarations = [&project, &scene, &codeGenerator](gd::Object & object, unsigned int maxDepth,
|
||||
auto generateDeclarations = [&project, &scene, &codeGenerator](const gd::Object & object, unsigned int maxDepth,
|
||||
gd::String & globalObjectLists, gd::String & globalObjectListsReset) {
|
||||
|
||||
gd::String type = gd::GetTypeOfObject(project, scene, object.GetName());
|
||||
|
@@ -39,10 +39,8 @@ public:
|
||||
* \return JS code
|
||||
*/
|
||||
static gd::String GenerateSceneEventsCompleteCode(gd::Project & project,
|
||||
gd::Layout & scene,
|
||||
gd::EventsList & events,
|
||||
std::set < gd::String > & includeFiles,
|
||||
bool compilationForRuntime = false);
|
||||
const gd::Layout & scene, const gd::EventsList & events,
|
||||
std::set < gd::String > & includeFiles, bool compilationForRuntime = false);
|
||||
|
||||
/**
|
||||
* Generate code for executing a condition list
|
||||
|
Reference in New Issue
Block a user