void ChangesNotifier::OnEventsModified( gd::Project& game, gd::Layout& scene, bool indirectChange, gd::String sourceOfTheIndirectChange) const { #if !defined(GD_NO_WX_GUI) // Compilation is not supported when wxWidgets // support is disabled. std::cout << "Changes occured inside " << scene.GetName() << "..."; scene.SetRefreshNeeded(); if (!indirectChange || !game.HasExternalEventsNamed( sourceOfTheIndirectChange)) // Changes occured directly in the scene: // Recompile it. { scene.SetCompilationNeeded(); CodeCompilationHelpers::CreateSceneEventsCompilationTask(game, scene); std::cout << "Recompilation triggered." << std::endl; } else { DependenciesAnalyzer analyzer( game, game.GetExternalEvents(sourceOfTheIndirectChange)); if (analyzer.ExternalEventsCanBeCompiledForAScene() == scene.GetName()) { // Do nothing: Changes occured in an external event which is compiled // separately std::cout << "But nothing to do." << std::endl; } else { // Changes occurred in an external event which is directly included in the // scene events. scene.SetCompilationNeeded(); std::cout << "Recompilation asked for later." << std::endl; } } #endif }
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 RuntimeScene::LoadFromSceneAndCustomInstances( const gd::Layout & scene, const gd::InitialInstancesContainer & instances ) { std::cout << "Loading RuntimeScene from a scene."; if (!game) { std::cout << "..No valid gd::Project associated to the RuntimeScene. Aborting loading." << std::endl; return false; } //Copy inherited scene Scene::operator=(scene); //Clear RuntimeScene datas objectsInstances.Clear(); timeManager.Reset(); std::cout << "."; codeExecutionEngine->runtimeContext.scene = this; inputManager.DisableInputWhenFocusIsLost(IsInputDisabledWhenFocusIsLost()); //Initialize variables variables = scene.GetVariables(); //Initialize layers std::cout << "."; layers.clear(); sf::View defaultView( sf::FloatRect( 0.0f, 0.0f, game->GetMainWindowDefaultWidth(), game->GetMainWindowDefaultHeight() ) ); for (std::size_t i = 0;i<GetLayersCount();++i) { layers.push_back(RuntimeLayer(GetLayer(i), defaultView)); } //Create object instances which are originally positioned on scene std::cout << "."; CreateObjectsFrom(instances); //Behaviors shared data std::cout << "."; behaviorsSharedDatas.LoadFrom(scene.behaviorsInitialSharedDatas); std::cout << "."; //Extensions specific initialization for (std::size_t i = 0;i<game->GetUsedExtensions().size();++i) { std::shared_ptr<gd::PlatformExtension> gdExtension = CppPlatform::Get().GetExtension(game->GetUsedExtensions()[i]); std::shared_ptr<ExtensionBase> extension = std::dynamic_pointer_cast<ExtensionBase>(gdExtension); if ( extension != std::shared_ptr<ExtensionBase>() ) { extension->SceneLoaded(*this); if ( extension->ToBeNotifiedOnObjectDeletion() ) extensionsToBeNotifiedOnObjectDeletion.push_back(extension.get()); } } std::cout << "."; if ( StopSoundsOnStartup() ) {game->GetSoundManager().ClearAllSoundsAndMusics(); } if ( renderWindow ) renderWindow->setTitle(GetWindowDefaultTitle()); std::cout << " Done." << std::endl; return true; }
void CodeCompiler::DisableTaskRelatedTo(gd::Layout & scene) { sf::Lock lock(pendingTasksMutex); //Disallow modifying pending tasks. std::cout << "Disabling tasks related to scene:" << scene.GetName() << endl; vector<Scene*>::iterator it = find(compilationDisallowed.begin(), compilationDisallowed.end(), &scene); if ( it == compilationDisallowed.end()) compilationDisallowed.push_back(&scene); }
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); // Generate whole events code codeGenerator.SetGenerateCodeForRuntime(compilationForRuntime); codeGenerator.PreprocessEventList(generatedEvents); gd::String wholeEventsCode = codeGenerator.GenerateEventsListCode(generatedEvents, 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/Runtime/RuntimeContext.h\"\n#include " "\"GDCpp/Runtime/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" "extern \"C\" int GDSceneEvents" + gd::SceneNameMangler::GetMangledSceneName(scene.GetName()) + "(RuntimeContext * runtimeContext)\n" "{\n" + "runtimeContext->StartNewFrame();\n" + wholeEventsCode + "return 0;\n" "}\n"; return output; }
gd::String FunctionEvent::MangleFunctionName(const gd::Layout & layout, const FunctionEvent & functionEvent) { //To generate a "unique" name for the function, the name is mangled and suffixed with the //pointer to the (original) event of the function. const gd::BaseEvent * ptr = &functionEvent; std::shared_ptr<gd::BaseEvent> originalEvent = functionEvent.originalEvent.lock(); if (originalEvent != std::shared_ptr<gd::BaseEvent>()) { ptr = originalEvent.get(); } return "GDFunction"+layout.GetMangledName() +gd::SceneNameMangler::GetMangledSceneName(functionEvent.GetName()) +gd::String::From(ptr); };
void GD_API CodeCompilationHelpers::CreateSceneEventsCompilationTask(gd::Project & game, gd::Layout & scene) { CodeCompilerTask task; task.compilerCall.compilationForRuntime = false; task.compilerCall.optimize = false; task.compilerCall.eventsGeneratedCode = true; task.compilerCall.inputFile = string(CodeCompiler::Get()->GetOutputDirectory()+"GD"+ToString(&scene)+"EventsSource.cpp"); task.compilerCall.outputFile = string(CodeCompiler::Get()->GetOutputDirectory()+"GD"+ToString(&scene)+"ObjectFile.o"); task.scene = &scene; task.preWork = std::shared_ptr<CodeCompilerExtraWork>(new EventsCodeCompilerPreWork(&game, &scene)); task.postWork = std::shared_ptr<CodeCompilerExtraWork>(new EventsCodeCompilerPostWork(&game, &scene)); task.userFriendlyName = "Compilation of events of scene "+scene.GetName(); CodeCompiler::Get()->AddTask(task); }
gd::String GD_CORE_API GetTypeOfBehavior(const gd::Project & project, const gd::Layout & layout, gd::String name, bool searchInGroups) { for (std::size_t i = 0;i<layout.GetObjectsCount();++i) { vector < gd::String > behaviors = layout.GetObject(i).GetAllBehaviorNames(); for (std::size_t j = 0;j<behaviors.size();++j) { if ( layout.GetObject(i).GetBehavior(behaviors[j]).GetName() == name ) return layout.GetObject(i).GetBehavior(behaviors[j]).GetTypeName(); } } for (std::size_t i = 0;i<project.GetObjectsCount();++i) { vector < gd::String > behaviors = project.GetObject(i).GetAllBehaviorNames(); for (std::size_t j = 0;j<behaviors.size();++j) { if ( project.GetObject(i).GetBehavior(behaviors[j]).GetName() == name ) return project.GetObject(i).GetBehavior(behaviors[j]).GetTypeName(); } } return ""; }
void CodeCompiler::EnableTaskRelatedTo(gd::Layout & scene) { bool mustLaunchCompilation = false; { sf::Lock lock(pendingTasksMutex); //Disallow modifying pending tasks. std::cout << "Enabling tasks related to scene:" << scene.GetName() << endl; vector<Scene*>::iterator it = find(compilationDisallowed.begin(), compilationDisallowed.end(), &scene); if ( it != compilationDisallowed.end()) compilationDisallowed.erase(it); mustLaunchCompilation = !pendingTasks.empty(); } //Launch pending tasks if needed if ( !processLaunched && mustLaunchCompilation ) { std::cout << "Launching compilation thread..."; processLaunched = true; StartTheNextTask(); } }
std::set < std::string > EventsVariablesFinder::FindAllObjectVariables(const gd::Platform & platform, const gd::Project & project, const gd::Layout & layout, const gd::Object & object) { std::set < std::string > results; std::set < std::string > results2 = FindArgumentsInEvents(platform, project, layout, layout.GetEvents(), "objectvar", object.GetName()); results.insert(results2.begin(), results2.end()); return results; }
bool RuntimeScene::LoadFromScene( const gd::Layout & scene ) { return LoadFromSceneAndCustomInstances(scene, scene.GetInitialInstances()); }
void ParameterEditorLauncher::LaunchEditor(wxWindow * parent, gd::Project & project, gd::Layout & layout, const gd::ParameterMetadata & metadata, std::vector<wxTextCtrl * > & paramEdits, std::size_t paramIndex) { if (paramIndex >= paramEdits.size()) return; wxTextCtrl * editCtrl = paramEdits.at(paramIndex); if (!editCtrl) return; if ( gd::ParameterMetadata::IsObject(metadata.GetType()) ) { gd::ChooseObjectDialog dialog(parent, project, layout, true, metadata.GetExtraInfo()); if ( dialog.ShowModal() == 1 ) { editCtrl->ChangeValue(dialog.GetChosenObject()); } return; } else if ( metadata.GetType() == "behavior" ) { gd::String object = paramEdits.empty() ? "" : paramEdits[0]->GetValue(); gd::ChooseBehaviorDialog dialog(parent, project, layout, object, metadata.GetExtraInfo()); if (dialog.DeduceBehavior() || dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.GetChosenBehavior()); return; } else if ( metadata.GetType() == "expression" ) { gd::EditExpressionDialog dialog(parent, editCtrl->GetValue(), project, layout); if ( dialog.ShowModal() == 1 ) { editCtrl->ChangeValue(dialog.GetExpression()); } return; } else if ( metadata.GetType() == "mouse" ) { ChoixBouton dialog(parent, editCtrl->GetValue()); if ( dialog.ShowModal() == 1 ) { editCtrl->ChangeValue(dialog.bouton); } return; } else if ( metadata.GetType() == "key" ) { ChoixClavier dialog(parent, editCtrl->GetValue()); if ( dialog.ShowModal() == 1 ) { editCtrl->ChangeValue(dialog.selectedKey); } return; } else if ( metadata.GetType() == "string" ) { gd::EditStrExpressionDialog dialog(parent, editCtrl->GetValue(), project, layout); if ( dialog.ShowModal() == 1 ) { editCtrl->ChangeValue(dialog.GetExpression()); } return; } else if ( metadata.GetType() == "relationalOperator" ) { SigneTest dialog(parent); int chosenOperator = dialog.ShowModal(); if ( chosenOperator == 1 ) editCtrl->ChangeValue("="); if ( chosenOperator == 2 ) editCtrl->ChangeValue(">"); if ( chosenOperator == 3 ) editCtrl->ChangeValue("<"); if ( chosenOperator == 4 ) editCtrl->ChangeValue(">="); if ( chosenOperator == 5 ) editCtrl->ChangeValue("<="); if ( chosenOperator == 6 ) editCtrl->ChangeValue("!="); return; } else if ( metadata.GetType() == "color" ) { wxColour color = wxGetColourFromUser(parent, wxColour(0,0,0)); if ( color.IsOk() ) { wxString r; r << static_cast<int>(color.Red()); wxString v; v << static_cast<int>(color.Green()); wxString b; b << static_cast<int>(color.Blue()); wxString colorStr = "\""+r+";"+v+";"+b+"\""; editCtrl->ChangeValue(colorStr); } return; } else if ( metadata.GetType() == "police" ) { wxString projectDirectory = wxFileName::FileName(project.GetProjectFile()).GetPath(); wxFileDialog dialog(parent, _("Choose a font ( ttf/ttc files )"), projectDirectory, "", "Polices (*.ttf, *.ttc)|*.ttf;*.ttc"); dialog.ShowModal(); if ( dialog.GetPath() != "" ) //Note that path is relative to the project file: { wxFileName filename(dialog.GetPath()); filename.MakeRelativeTo(projectDirectory); editCtrl->ChangeValue(filename.GetFullPath()); } return; } else if ( metadata.GetType() == "musicfile" ) { wxString projectDirectory = wxFileName::FileName(project.GetProjectFile()).GetPath(); wxFileDialog dialog(parent, _("Choose a music ( ogg files )"), projectDirectory, "", _("Audio files (*.ogg)|*.ogg")); dialog.ShowModal(); if ( dialog.GetPath() != "" ) //Note that path is relative to the project file: { wxFileName filename(dialog.GetPath()); filename.MakeRelativeTo(projectDirectory); editCtrl->ChangeValue(filename.GetFullPath()); } return; } else if ( metadata.GetType() == "soundfile" ) { wxString projectDirectory = wxFileName::FileName(project.GetProjectFile()).GetPath(); wxFileDialog dialog(parent, _("Choose a sound"), projectDirectory, "", _("Audio files (*.wav, *.ogg)|*.wav;*.ogg")); dialog.ShowModal(); if ( dialog.GetPath() != "" ) //Note that path is relative to the project file: { wxFileName filename(dialog.GetPath()); filename.MakeRelativeTo(projectDirectory); editCtrl->ChangeValue(filename.GetFullPath()); } return; } else if ( metadata.GetType() == "operator" ) { SigneModification dialog(parent); int retour = dialog.ShowModal(); if ( retour == 1 ) editCtrl->ChangeValue("="); if ( retour == 2 ) editCtrl->ChangeValue("+"); if ( retour == 3 ) editCtrl->ChangeValue("-"); if ( retour == 4 ) editCtrl->ChangeValue("*"); if ( retour == 5 ) editCtrl->ChangeValue("/"); return; } else if ( metadata.GetType() == "password" ) { GeneratePassword dialog(parent); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.mdp); return; } else if ( metadata.GetType() == "trueorfalse" ) { TrueOrFalse dialog(parent, _("Choose True or False to fill the parameter"), _("True or False")); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(_("True")); else editCtrl->ChangeValue(_("False")); } else if ( metadata.GetType() == "yesorno" ) { if (wxMessageBox(_("Choose yes or no to fullfil parent parameter:"), _("Yes or no") ,wxYES_NO ) == wxYES) editCtrl->ChangeValue(_("yes")); else editCtrl->ChangeValue(_("no")); return; } else if ( metadata.GetType() == "layer" ) { gd::ChooseLayerDialog dialog(parent, layout); if( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.GetChosenLayer()); return; } else if ( metadata.GetType() == "joyaxis" ) { ChoiceJoyAxis dialog(parent, editCtrl->GetValue(), project, layout); if( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.joyaxis); return; } else if ( metadata.GetType() == "file" ) { ChoiceFile dialog(parent, editCtrl->GetValue(), project, layout); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.file); return; } else if ( metadata.GetType() == "objectvar" ) { if ( paramEdits.empty() ) return; gd::String objectWanted = paramEdits[0]->GetValue(); gd::Object * object = NULL; if ( layout.HasObjectNamed(objectWanted) ) object = &layout.GetObject(objectWanted); else if ( project.HasObjectNamed(objectWanted) ) object = &project.GetObject(objectWanted); else return; gd::ChooseVariableDialog dialog(parent, object->GetVariables()); dialog.SetAssociatedObject(&project, &layout, object); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.GetSelectedVariable()); return; } else if ( metadata.GetType() == "scenevar" ) { gd::ChooseVariableDialog dialog(parent, layout.GetVariables()); dialog.SetAssociatedLayout(&project, &layout); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.GetSelectedVariable()); return; } else if ( metadata.GetType() == "globalvar" ) { gd::ChooseVariableDialog dialog(parent, project.GetVariables()); dialog.SetAssociatedProject(&project); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.GetSelectedVariable()); return; } }
std::set < gd::String > EventsVariablesFinder::FindAllLayoutVariables(const gd::Platform & platform, const gd::Project & project, const gd::Layout & layout) { std::set < gd::String > results; std::set < gd::String > results2 = FindArgumentsInEvents(platform, project, layout, layout.GetEvents(), "scenevar"); results.insert(results2.begin(), results2.end()); return results; }
void ExternalLayoutEditor::SetupForScene(gd::Layout & layout) { bool useExternalEditor = false; wxConfigBase::Get()->Read("/SceneEditor/ExternalSceneEditor", &useExternalEditor, false); if ( &layout == &emptyLayout ) { layoutPanel->Hide(); externalEditorPanel->Hide(); helpPanel->Show(); } else { if (useExternalEditor) { layoutPanel->Hide(); externalEditorPanel->Show(); helpPanel->Hide(); CreateExternalLayoutEditor(); } else { layoutPanel->Show(); externalEditorPanel->Hide(); helpPanel->Hide(); } gd::InitialInstancesContainer & instanceContainer = externalLayout.GetInitialInstances(); //Destroy any existing editor if (objectsEditor != std::shared_ptr<ObjectsEditor>()) m_mgr.DetachPane(objectsEditor.get()); if (layersEditor != std::shared_ptr<LayersEditorPanel>()) m_mgr.DetachPane(layersEditor.get()); if (propertiesPnl != std::shared_ptr<LayoutEditorPropertiesPnl>()) m_mgr.DetachPane(propertiesPnl.get()); if (initialInstancesBrowser != std::shared_ptr<InitialPositionBrowserDlg>()) m_mgr.DetachPane(initialInstancesBrowser.get()); //(Re)create layout canvas if ( layoutEditorCanvas ) delete layoutEditorCanvas; layoutEditorCanvas = new gd::LayoutEditorCanvas(layoutPanel, project, layout, instanceContainer, externalLayout.GetAssociatedSettings(), mainFrameWrapper, &externalLayout); layoutEditorCanvas->SetParentAuiManager( &m_mgr ); layoutEditorCanvas->SetScrollbars(scrollBar1, scrollBar2); //Creating external editors and linking them to the layout canvas objectsEditor = std::make_shared<gd::ObjectsEditor>(this, project, layout, mainFrameWrapper); layersEditor = std::make_shared<LayersEditorPanel>(this, project, layout, mainFrameWrapper); propertiesPnl = std::make_shared<LayoutEditorPropertiesPnl>(this, project, layout, layoutEditorCanvas, mainFrameWrapper); initialInstancesBrowser = std::make_shared<InitialPositionBrowserDlg>(this, instanceContainer, *layoutEditorCanvas); layoutEditorCanvas->AddAssociatedEditor(objectsEditor.get()); layoutEditorCanvas->AddAssociatedEditor(layersEditor.get()); layoutEditorCanvas->AddAssociatedEditor(propertiesPnl.get()); layoutEditorCanvas->AddAssociatedEditor(initialInstancesBrowser.get()); layersEditor->SetAssociatedLayoutEditorCanvas(layoutEditorCanvas); objectsEditor->SetAssociatedPropertiesPanel(propertiesPnl.get(), &m_mgr); //Display editors in panes m_mgr.AddPane( objectsEditor.get(), wxAuiPaneInfo().Name( wxT( "EO" ) ).Right().CloseButton( true ).Caption( _( "Objects' editor" ) ).MaximizeButton( true ).MinimizeButton( false ).CaptionVisible(true).MinSize(208, 100) ); m_mgr.AddPane( layersEditor.get(), wxAuiPaneInfo().Name( wxT( "EL" ) ).Right().CloseButton( true ).Caption( _( "Layers' editor" ) ).MaximizeButton( true ).MinimizeButton( false ).CaptionVisible(true).MinSize(208, 100).Show(false) ); m_mgr.AddPane( propertiesPnl.get(), wxAuiPaneInfo().Name( wxT( "PROPERTIES" ) ).Float().CloseButton( true ).Caption( _( "Properties" ) ).MaximizeButton( true ).MinimizeButton( false ).CaptionVisible(true).MinSize(50, 50).BestSize(230,200).Show(true) ); m_mgr.AddPane( initialInstancesBrowser.get(), wxAuiPaneInfo().Name( wxT( "InstancesBrowser" ) ).Float().CloseButton( true ).Caption( _( "Instances list" ) ).MaximizeButton( true ).MinimizeButton( false ).CaptionVisible(true).MinSize(50, 50).BestSize(230,200).Show(true) ); wxString perspective; wxConfigBase::Get()->Read("/ExternalLayoutEditor/LastWorkspace", &perspective); m_mgr.LoadPerspective(perspective); objectsEditor->OnChange([this](gd::String changeScope) { if (!externalLayoutEditor) return; if (changeScope == "object-added") externalLayoutEditor->SendUpdate("", true); else externalLayoutEditor->SetDirty(); }); layersEditor->OnChange([this](gd::String changeScope) { if (externalLayoutEditor) externalLayoutEditor->SetDirty(); }); m_mgr.Update(); EditorDisplayed(); } //Save the choice externalLayout.SetAssociatedLayout(layout.GetName()); if (onAssociatedLayoutChangedCb) onAssociatedLayoutChangedCb(); }
vector < gd::String > GD_CORE_API GetBehaviorsOfObject(const gd::Project & project, const gd::Layout & layout, gd::String name, bool searchInGroups) { bool behaviorsAlreadyInserted = false; vector < gd::String > behaviors; //Search in objects if ( layout.HasObjectNamed(name) ) //We check first layout's objects' list. { std::vector < gd::String > objectBehaviors = layout.GetObject(name).GetAllBehaviorNames(); std::copy(objectBehaviors.begin(), objectBehaviors.end(), back_inserter(behaviors)); behaviorsAlreadyInserted = true; } else if ( project.HasObjectNamed(name) ) //Then the global object list { vector < gd::String > objectBehaviors = project.GetObject(name).GetAllBehaviorNames(); std::copy(objectBehaviors.begin(), objectBehaviors.end(), back_inserter(behaviors)); behaviorsAlreadyInserted = true; } //Search in groups if ( searchInGroups ) { for (std::size_t i = 0;i<layout.GetObjectGroups().size();++i) { if ( layout.GetObjectGroups()[i].GetName() == name ) { //A group has the name searched //Verifying now that all objects have common behaviors. vector < gd::String > groupsObjects = layout.GetObjectGroups()[i].GetAllObjectsNames(); for (std::size_t j = 0;j<groupsObjects.size();++j) { //Get behaviors of the object of the group and delete behavior which are not in commons. vector < gd::String > objectBehaviors = GetBehaviorsOfObject(project, layout, groupsObjects[j], false); if (!behaviorsAlreadyInserted) { behaviorsAlreadyInserted = true; behaviors = objectBehaviors; } else { for (std::size_t a = 0 ;a<behaviors.size();++a) { if ( find(objectBehaviors.begin(), objectBehaviors.end(), behaviors[a]) == objectBehaviors.end() ) { behaviors.erase(behaviors.begin() + a); --a; } } } } } } for (std::size_t i = 0;i<project.GetObjectGroups().size();++i) { if ( project.GetObjectGroups()[i].GetName() == name ) { //A group has the name searched //Verifying now that all objects have common behaviors. vector < gd::String > groupsObjects = project.GetObjectGroups()[i].GetAllObjectsNames(); for (std::size_t j = 0;j<groupsObjects.size();++j) { //Get behaviors of the object of the group and delete behavior which are not in commons. vector < gd::String > objectBehaviors = GetBehaviorsOfObject(project, layout, groupsObjects[j], false); if (!behaviorsAlreadyInserted) { behaviorsAlreadyInserted = true; behaviors = objectBehaviors; } else { for (std::size_t a = 0 ;a<behaviors.size();++a) { if ( find(objectBehaviors.begin(), objectBehaviors.end(), behaviors[a]) == objectBehaviors.end() ) { behaviors.erase(behaviors.begin() + a); --a; } } } } } } } return behaviors; }
gd::String GD_CORE_API GetTypeOfObject(const gd::Project & project, const gd::Layout & layout, gd::String name, bool searchInGroups) { gd::String type; //Search in objects if ( layout.HasObjectNamed(name) ) type = layout.GetObject(name).GetType(); else if ( project.HasObjectNamed(name) ) type = project.GetObject(name).GetType(); //Search in groups if ( searchInGroups ) { for (std::size_t i = 0;i<layout.GetObjectGroups().size();++i) { if ( layout.GetObjectGroups()[i].GetName() == name ) { //A group has the name searched //Verifying now that all objects have the same type. vector < gd::String > groupsObjects = layout.GetObjectGroups()[i].GetAllObjectsNames(); gd::String previousType = groupsObjects.empty() ? "" : GetTypeOfObject(project, layout, groupsObjects[0], false); for (std::size_t j = 0;j<groupsObjects.size();++j) { if ( GetTypeOfObject(project, layout, groupsObjects[j], false) != previousType ) return ""; //The group has more than one type. } if ( !type.empty() && previousType != type ) return ""; //The group has objects of different type, so the group has not any type. type = previousType; } } for (std::size_t i = 0;i<project.GetObjectGroups().size();++i) { if ( project.GetObjectGroups()[i].GetName() == name ) { //A group has the name searched //Verifying now that all objects have the same type. vector < gd::String > groupsObjects = project.GetObjectGroups()[i].GetAllObjectsNames(); gd::String previousType = groupsObjects.empty() ? "" : GetTypeOfObject(project, layout, groupsObjects[0], false); for (std::size_t j = 0;j<groupsObjects.size();++j) { if ( GetTypeOfObject(project, layout, groupsObjects[j], false) != previousType ) return ""; //The group has more than one type. } if ( !type.empty() && previousType != type ) return ""; //The group has objects of different type, so the group has not any type. type = previousType; } } } return type; }