void GD_CORE_API ProjectStripper::StripProjectForExternalLayoutEdition( gd::Project& project, const gd::String& externalLayoutName) { while (project.GetExternalEventsCount() > 0) project.RemoveExternalEvents(project.GetExternalEvents(0).GetName()); gd::String associatedLayoutName; if (project.HasExternalLayoutNamed(externalLayoutName)) { associatedLayoutName = project.GetExternalLayout(externalLayoutName).GetAssociatedLayout(); } for (unsigned int i = 0; i < project.GetLayoutsCount(); ++i) { auto& layout = project.GetLayout(i); if (!associatedLayoutName.empty() && associatedLayoutName == layout.GetName()) continue; project.GetLayout(i).GetEvents().Clear(); project.GetLayout(i).GetInitialInstances().Clear(); } for (unsigned int i = 0; i < project.GetExternalEventsCount(); ++i) { project.GetExternalEvents(i).GetEvents().Clear(); } for (unsigned int i = 0; i < project.GetExternalLayoutsCount(); ++i) { auto& externalLayout = project.GetExternalLayout(i); if (externalLayoutName == externalLayout.GetName()) continue; externalLayout.GetInitialInstances().Clear(); } }
void GD_CORE_API ProjectStripper::StripProjectForExport(gd::Project& project) { project.GetObjectGroups().Clear(); while (project.GetExternalEventsCount() > 0) project.RemoveExternalEvents(project.GetExternalEvents(0).GetName()); for (unsigned int i = 0; i < project.GetLayoutsCount(); ++i) { project.GetLayout(i).GetObjectGroups().Clear(); project.GetLayout(i).GetEvents().Clear(); } }
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 EventsChangesNotifier::NotifyChangesInEventsOfScene(gd::Project& project, gd::Layout& layout) { for (std::size_t j = 0; j < project.GetUsedPlatforms().size(); ++j) project.GetUsedPlatforms()[j]->GetChangesNotifier().OnEventsModified( project, layout); // Notify others scenes, which include the changed scene ( even indirectly ), // that their events has changed for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) { if (&project.GetLayout(i) == &layout) continue; std::vector<gd::Layout*> linkedScenes; std::vector<gd::ExternalEvents*> notUsed; GetScenesAndExternalEventsLinkedTo( project.GetLayout(i).GetEvents(), project, linkedScenes, notUsed); for (std::size_t j = 0; j < linkedScenes.size(); ++j) { if (linkedScenes[j]->GetName() == layout.GetName()) { for (std::size_t k = 0; k < project.GetUsedPlatforms().size(); ++k) project.GetUsedPlatforms()[k]->GetChangesNotifier().OnEventsModified( project, project.GetLayout(i), /*indirectChange=*/true, layout.GetName()); } } } // Also notify external events for (std::size_t i = 0; i < project.GetExternalEventsCount(); ++i) { std::vector<gd::Layout*> linkedScenes; std::vector<gd::ExternalEvents*> notUsed; GetScenesAndExternalEventsLinkedTo(project.GetExternalEvents(i).GetEvents(), project, linkedScenes, notUsed); for (std::size_t j = 0; j < linkedScenes.size(); ++j) { if (linkedScenes[j]->GetName() == layout.GetName()) { for (std::size_t k = 0; k < project.GetUsedPlatforms().size(); ++k) project.GetUsedPlatforms()[k]->GetChangesNotifier().OnEventsModified( project, project.GetExternalEvents(i), /*indirectChange=*/true, layout.GetName()); } } } }
bool AndroidExporter::ExportEventsCode(gd::Project& project, gd::String outputDir) { for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) { gd::Layout& exportedLayout = project.GetLayout(i); gd::String eventsOutput = EventsCodeGenerator::GenerateSceneEventsCompleteCode( project, exportedLayout, exportedLayout.GetEvents(), true); gd::String filename = "scene" + gd::String::From(i) + ".cpp"; if (!fs.WriteToFile(outputDir + "/jni/" + filename, eventsOutput)) return false; } for (std::size_t i = 0; i < project.GetExternalEventsCount(); ++i) { gd::ExternalEvents& externalEvents = project.GetExternalEvents(i); DependenciesAnalyzer analyzer(project, externalEvents); if (!analyzer.ExternalEventsCanBeCompiledForAScene().empty()) { gd::String eventsOutput = EventsCodeGenerator::GenerateExternalEventsCompleteCode( project, externalEvents, true); gd::String filename = "externalEvents" + gd::String::From(i) + ".cpp"; if (!fs.WriteToFile(outputDir + "/jni/" + filename, eventsOutput)) return false; } } return true; }
bool AndroidExporter::ExportMainFile(gd::Project& project, gd::String outputDir) { gd::String layoutFunctionDeclarations; gd::String functionAssignmentCode; for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) { auto layout = project.GetLayout(i); gd::String layoutFunctionName = "GDSceneEvents" + gd::SceneNameMangler::GetMangledSceneName(layout.GetName()); gd::EventsCodeGenerator codeGenerator(project, layout, CppPlatform::Get()); layoutFunctionDeclarations += "extern \"C\" int " + layoutFunctionName + "(RuntimeContext * runtimeContext);\n"; functionAssignmentCode += "\t\tif (scene.GetName() == \"" + codeGenerator.ConvertToString(layout.GetName()) + "\") function = &" + layoutFunctionName + ";\n"; } gd::String mainFile = fs.ReadFile(GetAndroidProjectPath() + "/jni/main.cpp") .FindAndReplace("/* GDCPP_EVENTS_DECLARATIONS */", layoutFunctionDeclarations) .FindAndReplace("/* GDCPP_EVENTS_ASSIGNMENTS */", functionAssignmentCode); return fs.WriteToFile(outputDir + "/jni/main.cpp", mainFile); }
void LinkEvent::ReplaceLinkByLinkedEvents(gd::Project & project, EventsList & eventList, unsigned int indexOfTheEventInThisList) { //Finding what to link to. const EventsList * eventsToInclude = NULL; gd::ExternalEvents * linkedExternalEvents = NULL; if ( project.HasExternalEventsNamed(GetTarget()) ) { linkedExternalEvents = &project.GetExternalEvents(GetTarget()); eventsToInclude = &project.GetExternalEvents(GetTarget()).GetEvents(); } else if ( project.HasLayoutNamed(GetTarget()) ) eventsToInclude = &project.GetLayout(GetTarget()).GetEvents(); if ( eventsToInclude != NULL ) { unsigned int firstEvent = IncludeAllEvents() ? 0 : GetIncludeStart(); unsigned int lastEvent = IncludeAllEvents() ? eventsToInclude->size() - 1 : GetIncludeEnd(); //Check bounds if ( firstEvent >= eventsToInclude->size() ) { std::cout << "Unable to get events from a link ( Invalid start )" << std::endl; linkWasInvalid = true; return; } if ( lastEvent >= eventsToInclude->size() ) { std::cout << "Unable to get events from a link ( Invalid end )" << std::endl; linkWasInvalid = true; return; } if ( firstEvent > lastEvent ) { std::cout << "Unable to get events from a link ( End is before start )" << std::endl; linkWasInvalid = true; return; } //Insert an empty event to replace the link event ( we'll delete the link event at the end ) //( If we just erase the link event without adding a blank event to replace it, //the first event inserted by the link will not be preprocessed ( and it can be annoying if it require preprocessing, such as another link event ). ) gd::EmptyEvent emptyEvent; eventList.InsertEvent(emptyEvent, indexOfTheEventInThisList); eventList.InsertEvents(*eventsToInclude, firstEvent, lastEvent, indexOfTheEventInThisList+1); //Delete the link event ( which is now at the end of the list of events we've just inserted ) eventList.RemoveEvent(indexOfTheEventInThisList + 1 + static_cast<unsigned>(lastEvent-firstEvent)+1); } else { std::cout << "Unable to get events from a link." << std::endl; linkWasInvalid = true; //Delete the link event eventList.RemoveEvent(indexOfTheEventInThisList); return; } linkWasInvalid = false; }
void ChangesNotifier::RequestFullRecompilation(gd::Project& game, gd::Layout* scene) const { #if !defined(GD_NO_WX_GUI) // Compilation is not supported when wxWidgets // support is disabled. if (scene) { // Notify the scene it has been changed... scene->SetRefreshNeeded(); //...as well as the dependencies DependenciesAnalyzer analyzer(game, *scene); if (!analyzer.Analyze()) { std::cout << "WARNING: Circular dependency for scene " << scene->GetName() << std::endl; return; } std::set<gd::String> externalEventsDependencies = analyzer.GetExternalEventsDependencies(); for (std::set<gd::String>::const_iterator i = externalEventsDependencies.begin(); i != externalEventsDependencies.end(); ++i) { if (game.HasExternalEventsNamed(*i)) game.GetExternalEvents(*i).SetLastChangeTimeStamp( wxDateTime::Now().GetTicks()); } // And ask for a recompilation of everything. CodeCompilationHelpers::CreateSceneEventsCompilationTask(game, *scene); } else // Scene pointer is NULL: Mark all scenes as modified { for (std::size_t i = 0; i < game.GetLayoutsCount(); ++i) { game.GetLayout(i).SetRefreshNeeded(); game.GetLayout(i).SetCompilationNeeded(); } for (std::size_t i = 0; i < game.GetExternalEventsCount(); ++i) { game.GetExternalEvents(i).SetLastChangeTimeStamp( wxDateTime::Now() .GetTicks()); // Do no forget external events as they can have // been compiled separately from scenes. } } #endif }
void ObjectsPropgridHelper::UpdateBehaviorsSharedData(gd::Project & project, gd::Layout * scene) const { if ( scene ) scene->UpdateBehaviorsSharedData(project); else //Scene pointer is NULL: Update shared data of all scenes { for (std::size_t i = 0;i<project.GetLayoutsCount();++i) project.GetLayout(i).UpdateBehaviorsSharedData(project); } }
void ChangesNotifier::OnBehaviorEdited(gd::Project & game, gd::Layout * scene, gd::Object & object, gd::Behavior & behavior) const { if ( scene ) scene->SetRefreshNeeded(); else //Scene pointer is not NULL: Update shared data of all scenes { for (std::size_t i = 0;i<game.GetLayoutsCount();++i) game.GetLayout(i).SetRefreshNeeded(); } }
void ChangesNotifier::OnObjectVariablesChanged(gd::Project & game, gd::Layout * scene, gd::Object & object) const { #if !defined(GD_NO_WX_GUI) //Compilation is not supported when wxWidgets support is disabled. if ( scene ) scene->SetRefreshNeeded(); else //Scene pointer is NULL: Update shared data of all scenes { for (std::size_t i = 0;i<game.GetLayoutsCount();++i) { game.GetLayout(i).SetRefreshNeeded(); game.GetLayout(i).SetCompilationNeeded(); } for (std::size_t i = 0;i<game.GetExternalEventsCount();++i) { game.GetExternalEvents(i).SetLastChangeTimeStamp(wxDateTime::Now().GetTicks()); //Do no forget external events as they can have been compiled separately from scenes. } } #endif }
void ChangesNotifier::OnAutomatismEdited(gd::Project & game, gd::Layout * scene, gd::Object & object, gd::Automatism & automatism) const { if ( scene ) scene->SetRefreshNeeded(); else //Scene pointer is not NULL: Update shared data of all scenes { for (unsigned int i = 0;i<game.GetLayoutsCount();++i) game.GetLayout(i).SetRefreshNeeded(); } }
std::set < std::string > EventsVariablesFinder::FindAllGlobalVariables(const gd::Platform & platform, const gd::Project & project) { std::set < std::string > results; for (unsigned int i = 0;i<project.GetLayoutsCount();++i) { std::set < std::string > results2 = FindArgumentsInEvents(platform, project, project.GetLayout(i), project.GetLayout(i).GetEvents(), "globalvar"); results.insert(results2.begin(), results2.end()); } return results; }
void GD_CORE_API ProjectStripper::StripProjectForLayoutEdition( gd::Project& project, const gd::String& layoutName) { while (project.GetExternalEventsCount() > 0) project.RemoveExternalEvents(project.GetExternalEvents(0).GetName()); for (unsigned int i = 0; i < project.GetLayoutsCount(); ++i) { auto& layout = project.GetLayout(i); if (layoutName == layout.GetName()) continue; project.GetLayout(i).GetEvents().Clear(); project.GetLayout(i).GetInitialInstances().Clear(); } for (unsigned int i = 0; i < project.GetExternalEventsCount(); ++i) { project.GetExternalEvents(i).GetEvents().Clear(); } for (unsigned int i = 0; i < project.GetExternalLayoutsCount(); ++i) { project.GetExternalLayout(i).GetInitialInstances().Clear(); } }
void EventsChangesNotifier::GetScenesAndExternalEventsLinkedTo( const gd::EventsList& events, gd::Project& project, std::vector<gd::Layout*>& layouts, std::vector<gd::ExternalEvents*>& externalEvents) { for (std::size_t i = 0; i < events.size(); ++i) { try { const gd::LinkEvent& linkEvent = dynamic_cast<const gd::LinkEvent&>(events[i]); // We've got a link event, search now linked scene/external events if (project.HasExternalEventsNamed(linkEvent.GetTarget())) { gd::ExternalEvents& linkedExternalEvents = project.GetExternalEvents(linkEvent.GetTarget()); // Protect against circular references if (find(externalEvents.begin(), externalEvents.end(), &linkedExternalEvents) == externalEvents.end()) { externalEvents.push_back(&linkedExternalEvents); GetScenesAndExternalEventsLinkedTo(linkedExternalEvents.GetEvents(), project, layouts, externalEvents); } } else if (project.HasLayoutNamed(linkEvent.GetTarget())) { gd::Layout& linkedLayout = project.GetLayout(linkEvent.GetTarget()); // Protect against circular references if (find(layouts.begin(), layouts.end(), &linkedLayout) == layouts.end()) { layouts.push_back(&linkedLayout); GetScenesAndExternalEventsLinkedTo( linkedLayout.GetEvents(), project, layouts, externalEvents); } } } catch (...) { } if (events[i].CanHaveSubEvents()) GetScenesAndExternalEventsLinkedTo( events[i].GetSubEvents(), project, layouts, externalEvents); } }
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; }
bool ChooseBehaviorTypeDialog::ChooseAndAddBehaviorToObject(wxWindow * parent, gd::Project & project, gd::Object * object, gd::Layout * layout, bool isGlobalObject) { gd::ChooseBehaviorTypeDialog dialog(parent, project); if ( dialog.ShowModal() == 1) { //Find behavior metadata std::shared_ptr<gd::PlatformExtension> extension = std::shared_ptr<gd::PlatformExtension> (); std::vector < std::shared_ptr<gd::PlatformExtension> > extensions = project.GetCurrentPlatform().GetAllPlatformExtensions(); for (std::size_t i = 0;i<extensions.size();++i) { std::vector<gd::String> behaviorsTypes = extensions[i]->GetBehaviorsTypes(); if ( find(behaviorsTypes.begin(), behaviorsTypes.end(), dialog.GetSelectedBehaviorType()) != behaviorsTypes.end() ) extension = extensions[i]; } gd::BehaviorMetadata metadata = extension->GetBehaviorMetadata(dialog.GetSelectedBehaviorType()); //Add behavior to object gd::String autoName = metadata.GetDefaultName(); for (std::size_t j = 2;object->HasBehaviorNamed(autoName);++j) autoName = metadata.GetDefaultName()+gd::String::From(j); object->AddNewBehavior(project, dialog.GetSelectedBehaviorType(), autoName); //Let the scene know about the new behavior if ( isGlobalObject && layout ) layout->UpdateBehaviorsSharedData(project); else //Scene pointer is NULL: Update shared data of all layouts { for (std::size_t i = 0;i<project.GetLayoutsCount();++i) project.GetLayout(i).UpdateBehaviorsSharedData(project); } for (std::size_t j = 0; j < project.GetUsedPlatforms().size();++j) project.GetUsedPlatforms()[j]->GetChangesNotifier().OnBehaviorAdded(project, isGlobalObject ? NULL : layout, *object, object->GetBehavior(autoName)); return true; } return false; }
LinkEventEditor::LinkEventEditor(wxWindow* parent, LinkEvent& event, const gd::Project& project) : LinkEventEditorBase(parent), editedEvent(event), project(project) { // Add all the scenes and external events into the combobox. for (std::size_t i = 0; i < project.GetExternalEventsCount(); ++i) m_eventsComboBox->Append(project.GetExternalEvents(i).GetName()); for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) m_eventsComboBox->Append(project.GetLayout(i).GetName()); m_includeAllEventsRadio->SetValue(editedEvent.GetIncludeConfig() == LinkEvent::INCLUDE_ALL); m_includeEventsGroupRadio->SetValue(editedEvent.GetIncludeConfig() == LinkEvent::INCLUDE_EVENTS_GROUP); m_includeEventsByIndexRadio->SetValue(editedEvent.GetIncludeConfig() == LinkEvent::INCLUDE_BY_INDEX); m_eventsComboBox->SetValue(editedEvent.GetTarget()); if (editedEvent.GetIncludeConfig() == LinkEvent::INCLUDE_EVENTS_GROUP) { m_eventsGroupComboBox->SetValue(editedEvent.GetEventsGroupName()); } else if (editedEvent.GetIncludeConfig() == LinkEvent::INCLUDE_BY_INDEX) { m_startTextCtrl->SetValue( gd::String::From<std::size_t>(editedEvent.GetIncludeStart() + 1)); m_endTextCtrl->SetValue( gd::String::From<std::size_t>(editedEvent.GetIncludeEnd() + 1)); } // Display the deprecated features if the event was using them m_includeEventsByIndexRadio->Show(editedEvent.GetIncludeConfig() == LinkEvent::INCLUDE_BY_INDEX); m_deprecatedPanel->Show(editedEvent.GetIncludeConfig() == LinkEvent::INCLUDE_BY_INDEX); GetSizer()->Fit(this); EnableControls(); UpdateEventsGroupsList(); }