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:
Florian Rival
2016-08-20 17:19:01 +02:00
committed by GitHub
7 changed files with 51 additions and 19 deletions

View File

@@ -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.

View File

@@ -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; };

View File

@@ -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") {

View File

@@ -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

View File

@@ -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.

View File

@@ -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());

View File

@@ -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