void EventsChangesNotifier::NotifyChangesInEventsOfExternalEvents( gd::Project& project, gd::ExternalEvents& externalEvents) { for (std::size_t j = 0; j < project.GetUsedPlatforms().size(); ++j) project.GetUsedPlatforms()[j]->GetChangesNotifier().OnEventsModified( project, externalEvents); // Notify scenes, which include the external events ( even indirectly ), that // their events has changed for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) { std::vector<gd::Layout*> notUsed; std::vector<gd::ExternalEvents*> linkedExternalEvents; GetScenesAndExternalEventsLinkedTo(project.GetLayout(i).GetEvents(), project, notUsed, linkedExternalEvents); for (std::size_t j = 0; j < linkedExternalEvents.size(); ++j) { if (linkedExternalEvents[j]->GetName() == externalEvents.GetName()) { for (std::size_t k = 0; k < project.GetUsedPlatforms().size(); ++k) project.GetUsedPlatforms()[k]->GetChangesNotifier().OnEventsModified( project, project.GetLayout(i), /*indirectChange=*/true, externalEvents.GetName()); } } } // Also notify external events for (std::size_t i = 0; i < project.GetExternalEventsCount(); ++i) { std::vector<gd::Layout*> notUsed; std::vector<gd::ExternalEvents*> linkedExternalEvents; GetScenesAndExternalEventsLinkedTo(project.GetExternalEvents(i).GetEvents(), project, notUsed, linkedExternalEvents); for (std::size_t j = 0; j < linkedExternalEvents.size(); ++j) { if (linkedExternalEvents[j]->GetName() == externalEvents.GetName()) { for (std::size_t k = 0; k < project.GetUsedPlatforms().size(); ++k) project.GetUsedPlatforms()[k]->GetChangesNotifier().OnEventsModified( project, project.GetExternalEvents(i), /*indirectChange=*/true, externalEvents.GetName()); } } } }
void GD_API CodeCompilationHelpers::CreateExternalEventsCompilationTask(gd::Project & game, gd::ExternalEvents & events) { CodeCompilerTask task; task.compilerCall.compilationForRuntime = false; task.compilerCall.optimize = false; task.compilerCall.eventsGeneratedCode = true; task.compilerCall.inputFile = string(CodeCompiler::Get()->GetOutputDirectory()+"GD"+ToString(&events)+"EventsSource.cpp"); task.compilerCall.outputFile = string(CodeCompiler::Get()->GetOutputDirectory()+"GD"+ToString(&events)+"ObjectFile.o"); task.preWork = std::shared_ptr<CodeCompilerExtraWork>(new ExternalEventsCodeCompilerPreWork(&game, &events)); task.postWork = std::shared_ptr<CodeCompilerExtraWork>(new ExternalEventsCodeCompilerPostWork(&game, &events)); task.userFriendlyName = "Compilation of external events "+events.GetName(); CodeCompiler::Get()->AddTask(task); }
gd::String EventsCodeGenerator::GenerateExternalEventsCompleteCode(gd::Project & project, gd::ExternalEvents & events, bool compilationForRuntime) { DependenciesAnalyzer analyzer(project, events); gd::String associatedSceneName = analyzer.ExternalEventsCanBeCompiledForAScene(); if ( associatedSceneName.empty() || !project.HasLayoutNamed(associatedSceneName) ) { std::cout << "ERROR: Cannot generate code for an external event: No unique associated scene." << std::endl; return ""; } gd::Layout & associatedScene = project.GetLayout(project.GetLayoutPosition(associatedSceneName)); gd::String output; //Prepare the global context ( Used to get needed header files ) gd::EventsCodeGenerationContext context; EventsCodeGenerator codeGenerator(project, associatedScene); codeGenerator.PreprocessEventList(events.GetEvents()); codeGenerator.SetGenerateCodeForRuntime(compilationForRuntime); //Generate whole events code gd::String wholeEventsCode = codeGenerator.GenerateEventsListCode(events.GetEvents(), context); //Generate default code around events: //Includes output += "#include <vector>\n#include <map>\n#include <string>\n#include <algorithm>\n#include <SFML/System/Clock.hpp>\n#include <SFML/System/Vector2.hpp>\n#include <SFML/Graphics/Color.hpp>\n#include \"GDCpp/RuntimeContext.h\"\n#include \"GDCpp/RuntimeObject.h\"\n"; for ( set<gd::String>::iterator include = codeGenerator.GetIncludeFiles().begin() ; include != codeGenerator.GetIncludeFiles().end(); ++include ) output += "#include \""+*include+"\"\n"; //Extra declarations needed by events for ( set<gd::String>::iterator declaration = codeGenerator.GetCustomGlobalDeclaration().begin() ; declaration != codeGenerator.GetCustomGlobalDeclaration().end(); ++declaration ) output += *declaration+"\n"; output += codeGenerator.GetCustomCodeOutsideMain()+ "\n" "void "+EventsCodeNameMangler::Get()->GetExternalEventsFunctionMangledName(events.GetName())+"(RuntimeContext * runtimeContext)\n" "{\n" +codeGenerator.GetCustomCodeInMain() +wholeEventsCode+ "return;\n" "}\n"; return output; }
void ChangesNotifier::OnEventsModified( gd::Project& game, gd::ExternalEvents& events, bool indirectChange, gd::String sourceOfTheIndirectChange) const { #if !defined(GD_NO_WX_GUI) // Compilation is not supported when wxWidgets // support is disabled. DependenciesAnalyzer analyzer(game, events); gd::String associatedScene = analyzer.ExternalEventsCanBeCompiledForAScene(); bool externalEventsAreCompiledSeparately = !associatedScene.empty(); if (!externalEventsAreCompiledSeparately) return; std::cout << "Changes occured inside " << events.GetName() << " (compiled separately)..." << std::endl; // The external events are compiled separately from the scene events: // We need to recompile them if the changes occured inside them. if (!indirectChange || !game.HasExternalEventsNamed(sourceOfTheIndirectChange)) { // Changes occurred directly inside the external events: We need to // recompile them events.SetLastChangeTimeStamp(wxDateTime::Now().GetTicks()); CodeCompilationHelpers::CreateExternalEventsCompilationTask(game, events); std::cout << "Recompilation triggered." << std::endl; } else { DependenciesAnalyzer analyzer( game, game.GetExternalEvents(sourceOfTheIndirectChange)); if (analyzer.ExternalEventsCanBeCompiledForAScene() == associatedScene) { // Do nothing: Changes occurred in an external event which is compiled // separately std::cout << "But nothing to do." << std::endl; } else { // Changes occurred in an another external event which is directly // included in our external events. events.SetLastChangeTimeStamp(wxDateTime::Now().GetTicks()); CodeCompilationHelpers::CreateExternalEventsCompilationTask(game, events); std::cout << "Recompilation triggered." << std::endl; } } #endif }