/* * GDevelop Core * Copyright 2008-2015 Florian Rival (Florian.Rival@gmail.com). All rights reserved. * This project is released under the MIT License. */ #include #include #include "GDCore/String.h" #include #include #include #include #include "GDCore/IDE/Dialogs/ProjectExtensionsDialog.h" #include "GDCore/IDE/Dialogs/ProjectUpdateDialog.h" #include "GDCore/IDE/Dialogs/ChooseVariableDialog.h" #include "GDCore/IDE/ArbitraryResourceWorker.h" #include "GDCore/Extensions/Platform.h" #include "GDCore/Extensions/PlatformExtension.h" #include "GDCore/Project/Layout.h" #include "GDCore/Project/ExternalEvents.h" #include "GDCore/Project/ExternalLayout.h" #include "GDCore/Project/SourceFile.h" #include "GDCore/Project/ImageManager.h" #include "GDCore/Project/Object.h" #include "GDCore/Project/ResourcesManager.h" #include "GDCore/Project/ChangesNotifier.h" #include "GDCore/Extensions/Metadata/ExpressionMetadata.h" #include "GDCore/Serialization/SerializerElement.h" #include "GDCore/Serialization/Serializer.h" #include "GDCore/Extensions/Metadata/MetadataProvider.h" #include "GDCore/IDE/PlatformManager.h" #include "GDCore/IDE/wxTools/SafeYield.h" #include "GDCore/CommonTools.h" #include "GDCore/Utf8/utf8.h" #include "GDCore/TinyXml/tinyxml.h" #include "GDCore/Tools/VersionWrapper.h" #include "GDCore/Tools/Log.h" #include "GDCore/Tools/Localization.h" #include "GDCore/Serialization/Serializer.h" #include "GDCore/Serialization/Splitter.h" #include "Project.h" #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) #include #include #include #include #include #endif using namespace std; #undef CreateEvent namespace gd { Project::Project() : #if defined(GD_IDE_ONLY) name(_("Project")), packageName("com.example.gamename"), folderProject(false), #endif windowWidth(800), windowHeight(600), maxFPS(60), minFPS(10), verticalSync(false), imageManager(std::shared_ptr(new ImageManager)) #if defined(GD_IDE_ONLY) ,useExternalSourceFiles(false), currentPlatform(NULL), GDMajorVersion(gd::VersionWrapper::Major()), GDMinorVersion(gd::VersionWrapper::Minor()), dirty(false) #endif { imageManager->SetGame(this); #if defined(GD_IDE_ONLY) //Game use builtin extensions by default extensionsUsed.push_back("BuiltinObject"); extensionsUsed.push_back("BuiltinAudio"); extensionsUsed.push_back("BuiltinVariables"); extensionsUsed.push_back("BuiltinTime"); extensionsUsed.push_back("BuiltinMouse"); extensionsUsed.push_back("BuiltinKeyboard"); extensionsUsed.push_back("BuiltinJoystick"); extensionsUsed.push_back("BuiltinCamera"); extensionsUsed.push_back("BuiltinWindow"); extensionsUsed.push_back("BuiltinFile"); extensionsUsed.push_back("BuiltinNetwork"); extensionsUsed.push_back("BuiltinScene"); extensionsUsed.push_back("BuiltinAdvanced"); extensionsUsed.push_back("Sprite"); extensionsUsed.push_back("BuiltinCommonInstructions"); extensionsUsed.push_back("BuiltinCommonConversions"); extensionsUsed.push_back("BuiltinStringInstructions"); extensionsUsed.push_back("BuiltinMathematicalTools"); extensionsUsed.push_back("BuiltinExternalLayouts"); #endif #if !defined(GD_IDE_ONLY) platforms.push_back(&CppPlatform::Get()); #endif } Project::~Project() { } std::shared_ptr Project::CreateObject(const gd::String & type, const gd::String & name, const gd::String & platformName) { for (std::size_t i = 0;iGetName() != platformName ) continue; std::shared_ptr object = platforms[i]->CreateObject(type, name); //Create a base object if the type can't be found in the platform if ( object && object->GetType() == type ) return object; //If the object is valid and has the good type (not a base object), return it } return std::shared_ptr(); } gd::Behavior* Project::CreateBehavior(const gd::String & type, const gd::String & platformName) { for (std::size_t i = 0;iGetName() != platformName ) continue; gd::Behavior* behavior = platforms[i]->CreateBehavior(type); if ( behavior ) return behavior; } return NULL; } std::shared_ptr Project::CreateBehaviorSharedDatas(const gd::String & type, const gd::String & platformName) { for (std::size_t i = 0;iGetName() != platformName ) continue; std::shared_ptr behavior = platforms[i]->CreateBehaviorSharedDatas(type); if ( behavior ) return behavior; } return std::shared_ptr(); } #if defined(GD_IDE_ONLY) std::shared_ptr Project::CreateEvent(const gd::String & type, const gd::String & platformName) { for (std::size_t i = 0;iGetName() != platformName ) continue; std::shared_ptr event = platforms[i]->CreateEvent(type); if ( event ) return event; } return std::shared_ptr(); } Platform & Project::GetCurrentPlatform() const { if ( currentPlatform == NULL ) std::cout << "FATAL ERROR: Project has no assigned current platform. GD will crash." << std::endl; return *currentPlatform; } void Project::AddPlatform(Platform & platform) { for (std::size_t i = 0;iGetName() == platformName) { currentPlatform = platforms[i]; return; } } } bool Project::RemovePlatform(const gd::String & platformName) { if ( platforms.size() <= 1 ) return false; for (std::size_t i = 0;iGetName() == platformName) { //Remove the platform, ensuring that currentPlatform remains correct. if ( currentPlatform == platforms[i] ) currentPlatform = platforms.back(); if ( currentPlatform == platforms[i] ) currentPlatform = platforms[0]; platforms.erase(platforms.begin()+i); return true; } } return false; } #endif bool Project::HasLayoutNamed(const gd::String & name) const { return ( find_if(scenes.begin(), scenes.end(), bind2nd(gd::LayoutHasName(), name)) != scenes.end() ); } gd::Layout & Project::GetLayout(const gd::String & name) { return *(*find_if(scenes.begin(), scenes.end(), bind2nd(gd::LayoutHasName(), name))); } const gd::Layout & Project::GetLayout(const gd::String & name) const { return *(*find_if(scenes.begin(), scenes.end(), bind2nd(gd::LayoutHasName(), name))); } gd::Layout & Project::GetLayout(std::size_t index) { return *scenes[index]; } const gd::Layout & Project::GetLayout (std::size_t index) const { return *scenes[index]; } std::size_t Project::GetLayoutPosition(const gd::String & name) const { for (std::size_t i = 0;iGetName() == name ) return i; } return gd::String::npos; } std::size_t Project::GetLayoutsCount() const { return scenes.size(); } #if defined(GD_IDE_ONLY) void Project::SwapLayouts(std::size_t first, std::size_t second) { if ( first >= scenes.size() || second >= scenes.size() ) return; std::shared_ptr firstItem = scenes[first]; std::shared_ptr secondItem = scenes[second]; scenes[first] = secondItem; scenes[second] = firstItem; } #endif gd::Layout & Project::InsertNewLayout(const gd::String & name, std::size_t position) { std::shared_ptr newScene = std::shared_ptr(new Layout); if (positionSetName(name); #if defined(GD_IDE_ONLY) newScene->UpdateBehaviorsSharedData(*this); #endif return *newScene; } gd::Layout & Project::InsertLayout(const gd::Layout & layout, std::size_t position) { std::shared_ptr newScene = std::shared_ptr(new Layout(layout)); if (positionUpdateBehaviorsSharedData(*this); #endif return *newScene; } void Project::RemoveLayout(const gd::String & name) { std::vector< std::shared_ptr >::iterator scene = find_if(scenes.begin(), scenes.end(), bind2nd(gd::LayoutHasName(), name)); if ( scene == scenes.end() ) return; scenes.erase(scene); } #if defined(GD_IDE_ONLY) bool Project::HasExternalEventsNamed(const gd::String & name) const { return ( find_if(externalEvents.begin(), externalEvents.end(), bind2nd(gd::ExternalEventsHasName(), name)) != externalEvents.end() ); } gd::ExternalEvents & Project::GetExternalEvents(const gd::String & name) { return *(*find_if(externalEvents.begin(), externalEvents.end(), bind2nd(gd::ExternalEventsHasName(), name))); } const gd::ExternalEvents & Project::GetExternalEvents(const gd::String & name) const { return *(*find_if(externalEvents.begin(), externalEvents.end(), bind2nd(gd::ExternalEventsHasName(), name))); } gd::ExternalEvents & Project::GetExternalEvents(std::size_t index) { return *externalEvents[index]; } const gd::ExternalEvents & Project::GetExternalEvents (std::size_t index) const { return *externalEvents[index]; } std::size_t Project::GetExternalEventsPosition(const gd::String & name) const { for (std::size_t i = 0;iGetName() == name ) return i; } return gd::String::npos; } std::size_t Project::GetExternalEventsCount() const { return externalEvents.size(); } gd::ExternalEvents & Project::InsertNewExternalEvents(const gd::String & name, std::size_t position) { std::shared_ptr newExternalEvents(new gd::ExternalEvents); if (positionSetName(name); return *newExternalEvents; } void Project::InsertExternalEvents(const gd::ExternalEvents & events, std::size_t position) { if (position(new gd::ExternalEvents(events))); else externalEvents.push_back(std::shared_ptr(new gd::ExternalEvents(events))); } void Project::RemoveExternalEvents(const gd::String & name) { std::vector< std::shared_ptr >::iterator events = find_if(externalEvents.begin(), externalEvents.end(), bind2nd(gd::ExternalEventsHasName(), name)); if ( events == externalEvents.end() ) return; externalEvents.erase(events); } void Project::SwapExternalEvents(std::size_t first, std::size_t second) { if ( first >= externalEvents.size() || second >= externalEvents.size() ) return; std::shared_ptr firstItem = externalEvents[first]; std::shared_ptr secondItem = externalEvents[second]; externalEvents[first] = secondItem; externalEvents[second] = firstItem; } void Project::SwapExternalLayouts(std::size_t first, std::size_t second) { if ( first >= externalLayouts.size() || second >= externalLayouts.size() ) return; std::shared_ptr firstItem = externalLayouts[first]; std::shared_ptr secondItem = externalLayouts[second]; externalLayouts[first] = secondItem; externalLayouts[second] = firstItem; } #endif bool Project::HasExternalLayoutNamed(const gd::String & name) const { return ( find_if(externalLayouts.begin(), externalLayouts.end(), bind2nd(gd::ExternalLayoutHasName(), name)) != externalLayouts.end() ); } gd::ExternalLayout & Project::GetExternalLayout(const gd::String & name) { return *(*find_if(externalLayouts.begin(), externalLayouts.end(), bind2nd(gd::ExternalLayoutHasName(), name))); } const gd::ExternalLayout & Project::GetExternalLayout(const gd::String & name) const { return *(*find_if(externalLayouts.begin(), externalLayouts.end(), bind2nd(gd::ExternalLayoutHasName(), name))); } gd::ExternalLayout & Project::GetExternalLayout(std::size_t index) { return *externalLayouts[index]; } const gd::ExternalLayout & Project::GetExternalLayout (std::size_t index) const { return *externalLayouts[index]; } std::size_t Project::GetExternalLayoutPosition(const gd::String & name) const { for (std::size_t i = 0;iGetName() == name ) return i; } return gd::String::npos; } std::size_t Project::GetExternalLayoutsCount() const { return externalLayouts.size(); } gd::ExternalLayout & Project::InsertNewExternalLayout(const gd::String & name, std::size_t position) { std::shared_ptr newExternalLayout = std::shared_ptr(new gd::ExternalLayout); if (positionSetName(name); return *newExternalLayout; } void Project::InsertExternalLayout(const gd::ExternalLayout & layout, std::size_t position) { std::shared_ptr newLayout(new gd::ExternalLayout(layout)); if (position >::iterator externalLayout = find_if(externalLayouts.begin(), externalLayouts.end(), bind2nd(gd::ExternalLayoutHasName(), name)); if ( externalLayout == externalLayouts.end() ) return; externalLayouts.erase(externalLayout); } #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) //Compatibility with GD2.x class SpriteObjectsPositionUpdater : public gd::InitialInstanceFunctor { public: SpriteObjectsPositionUpdater(gd::Project & project_, gd::Layout & layout_) : project(project_), layout(layout_) {}; virtual ~SpriteObjectsPositionUpdater() {}; virtual void operator()(gd::InitialInstance * instancePtr) { gd::InitialInstance & instance = *instancePtr; gd::Object * object = NULL; if ( layout.HasObjectNamed(instance.GetObjectName())) object = &layout.GetObject(instance.GetObjectName()); else if ( project.HasObjectNamed(instance.GetObjectName())) object = &project.GetObject(instance.GetObjectName()); else return; if ( object->GetType() != "Sprite") return; if ( !instance.HasCustomSize() ) return; wxSetWorkingDirectory(wxFileName::FileName(project.GetProjectFile()).GetPath()); object->LoadResources(project, layout); sf::Vector2f size = object->GetInitialInstanceDefaultSize(instance, project, layout); instance.SetX(instance.GetX() + size.x/2 - instance.GetCustomWidth()/2 ); instance.SetY(instance.GetY() + size.y/2 - instance.GetCustomHeight()/2 ); } private: gd::Project & project; gd::Layout & layout; }; //End of compatibility code #endif void Project::UnserializeFrom(const SerializerElement & element) { //Checking version #if defined(GD_IDE_ONLY) gd::String updateText; const SerializerElement & gdVersionElement = element.GetChild("gdVersion", 0, "GDVersion"); GDMajorVersion = gdVersionElement.GetIntAttribute("major", GDMajorVersion, "Major"); GDMinorVersion = gdVersionElement.GetIntAttribute("minor", GDMinorVersion, "Minor"); int build = gdVersionElement.GetIntAttribute("build", 0, "Build"); int revision = gdVersionElement.GetIntAttribute("revision", 0, "Revision"); if ( GDMajorVersion > gd::VersionWrapper::Major() ) gd::LogWarning( _( "The version of GDevelop used to create this game seems to be a new version.\nGDevelop may fail to open the game, or data may be missing.\nYou should check if a new version of GDevelop is available." ) ); else { if ( (GDMajorVersion == gd::VersionWrapper::Major() && GDMinorVersion > gd::VersionWrapper::Minor()) || (GDMajorVersion == gd::VersionWrapper::Major() && GDMinorVersion == gd::VersionWrapper::Minor() && build > gd::VersionWrapper::Build()) || (GDMajorVersion == gd::VersionWrapper::Major() && GDMinorVersion == gd::VersionWrapper::Minor() && build == gd::VersionWrapper::Build() && revision > gd::VersionWrapper::Revision()) ) { gd::LogWarning( _( "The version of GDevelop used to create this game seems to be greater.\nGDevelop may fail to open the game, or data may be missing.\nYou should check if a new version of GDevelop is available." ) ); } } //Compatibility code if ( GDMajorVersion <= 1 ) { gd::LogError( _("The game was saved with version of GDevelop which is too old. Please open and save the game with one of the first version of GDevelop 2. You will then be able to open your game with this GDevelop version.")); return; } //End of Compatibility code #endif const SerializerElement & propElement = element.GetChild("properties", 0, "Info"); SetName(propElement.GetChild("name", 0, "Nom").GetValue().GetString()); SetDefaultWidth(propElement.GetChild("windowWidth", 0, "WindowW").GetValue().GetInt()); SetDefaultHeight(propElement.GetChild("windowHeight", 0, "WindowH").GetValue().GetInt()); SetMaximumFPS(propElement.GetChild("maxFPS", 0, "FPSmax").GetValue().GetInt()); SetMinimumFPS(propElement.GetChild("minFPS", 0, "FPSmin").GetValue().GetInt()); SetVerticalSyncActivatedByDefault(propElement.GetChild("verticalSync").GetValue().GetBool()); #if defined(GD_IDE_ONLY) SetAuthor(propElement.GetChild("author", 0, "Auteur").GetValue().GetString()); SetPackageName(propElement.GetStringAttribute("packageName")); SetFolderProject(propElement.GetBoolAttribute("folderProject")); SetLastCompilationDirectory(propElement.GetChild("latestCompilationDirectory", 0, "LatestCompilationDirectory").GetValue().GetString()); winExecutableFilename = propElement.GetStringAttribute("winExecutableFilename"); winExecutableIconFile = propElement.GetStringAttribute("winExecutableIconFile"); linuxExecutableFilename = propElement.GetStringAttribute("linuxExecutableFilename"); macExecutableFilename = propElement.GetStringAttribute("macExecutableFilename"); useExternalSourceFiles = propElement.GetBoolAttribute("useExternalSourceFiles"); #endif const SerializerElement & extensionsElement = propElement.GetChild("extensions", 0, "Extensions"); extensionsElement.ConsiderAsArrayOf("extension", "Extension"); for(std::size_t i = 0;iGetPlatform(name); if ( platform ) { AddPlatform(*platform); if ( platform->GetName() == currentPlatformName || currentPlatformName.empty() ) currentPlatform = platform; } else { std::cout << "Platform \"" << name << "\" is unknown." << std::endl; } } //Compatibility code if ( platformsElement.GetChildrenCount() == 0 ) { //Compatibility with GD2.x platforms.push_back(gd::PlatformManager::Get()->GetPlatform("GDevelop C++ platform")); currentPlatform = platforms.back(); } //End of Compatibility code if (currentPlatform == NULL && !platforms.empty()) currentPlatform = platforms.back(); #endif //Compatibility code #if defined(GD_IDE_ONLY) if ( VersionWrapper::IsOlder(GDMajorVersion, 0, 0, 0, 3, 0, 0, 0) ) { updateText += _("Sprite scaling has changed since GD 2: The resizing is made so that the origin point of the object won't move whatever the scale of the object.\n"); updateText += _("You may have to slightly change the position of some objects if you have changed their size.\n\n"); updateText += _("Thank you for your understanding.\n"); } #endif //End of Compatibility code //Compatibility code #if defined(GD_IDE_ONLY) if ( VersionWrapper::IsOlderOrEqual(GDMajorVersion, GDMinorVersion, revision, build, 2,2,1,10822) ) { if ( std::find(GetUsedExtensions().begin(), GetUsedExtensions().end(), "BuiltinExternalLayouts") == GetUsedExtensions().end() ) GetUsedExtensions().push_back("BuiltinExternalLayouts"); } #endif //Compatibility code #if defined(GD_IDE_ONLY) if ( VersionWrapper::IsOlderOrEqual(GDMajorVersion, GDMinorVersion, revision, build, 3,3,3,0) ) { if ( std::find(GetUsedExtensions().begin(), GetUsedExtensions().end(), "AStarBehavior") != GetUsedExtensions().end() ) { GetUsedExtensions().erase( std::remove( GetUsedExtensions().begin(), GetUsedExtensions().end(), "AStarBehavior" ), GetUsedExtensions().end() ); GetUsedExtensions().push_back("PathfindingBehavior"); updateText += _("The project is using the pathfinding behavior. This behavior has been replaced by a new one:\n"); updateText += _("You must add the new 'Pathfinding' behavior to the objects that need to be moved, and add the 'Pathfinding Obstacle' to the objects that must act as obstacles."); } } #endif //Compatibility code #if defined(GD_IDE_ONLY) if ( VersionWrapper::IsOlderOrEqual(GDMajorVersion, GDMinorVersion, revision, build, 4,0,85,0) ) { for(unsigned int i = 0;i < extensionsUsed.size();++i) extensionsUsed[i] = extensionsUsed[i].FindAndReplace("Automatism", "Behavior"); } #endif #if defined(GD_IDE_ONLY) ObjectGroup::UnserializeFrom(GetObjectGroups(), element.GetChild("objectsGroups", 0, "ObjectGroups")); #endif resourcesManager.UnserializeFrom(element.GetChild( "resources", 0, "Resources" )); UnserializeObjectsFrom(*this, element.GetChild("objects", 0, "Objects")); GetVariables().UnserializeFrom(element.GetChild("variables", 0, "Variables")); const SerializerElement & layoutsElement = element.GetChild("layouts", 0, "Scenes"); layoutsElement.ConsiderAsArrayOf("layout", "Scene"); for(std::size_t i = 0;i newExternalLayout(new gd::ExternalLayout); newExternalLayout->UnserializeFrom(externalLayoutElement); externalLayouts.push_back(newExternalLayout); } #if defined(GD_IDE_ONLY) const SerializerElement & externalSourceFilesElement = element.GetChild("externalSourceFiles", 0, "ExternalSourceFiles"); externalSourceFilesElement.ConsiderAsArrayOf("sourceFile", "SourceFile"); for(std::size_t i = 0;i newSourceFile(new gd::SourceFile); newSourceFile->UnserializeFrom(sourceFileElement); externalSourceFiles.push_back(newSourceFile); } #if !defined(GD_NO_WX_GUI) if (!updateText.empty()) //TODO { ProjectUpdateDialog updateDialog(NULL, updateText); updateDialog.ShowModal(); } dirty = false; #endif #endif } #if defined(GD_IDE_ONLY) void Project::SerializeTo(SerializerElement & element) const { SerializerElement & versionElement = element.AddChild("gdVersion"); versionElement.SetAttribute("major", gd::VersionWrapper::Major() ); versionElement.SetAttribute("minor", gd::VersionWrapper::Minor() ); versionElement.SetAttribute("build", gd::VersionWrapper::Build() ); versionElement.SetAttribute("revision", gd::VersionWrapper::Revision() ); SerializerElement & propElement = element.AddChild("properties"); propElement.AddChild("name").SetValue(GetName()); propElement.AddChild("author").SetValue(GetAuthor()); propElement.AddChild("windowWidth").SetValue(GetMainWindowDefaultWidth()); propElement.AddChild("windowHeight").SetValue(GetMainWindowDefaultHeight()); propElement.AddChild("latestCompilationDirectory").SetValue(GetLastCompilationDirectory()); propElement.AddChild("maxFPS").SetValue(GetMaximumFPS()); propElement.AddChild("minFPS").SetValue(GetMinimumFPS()); propElement.AddChild("verticalSync").SetValue(IsVerticalSynchronizationEnabledByDefault()); propElement.SetAttribute("folderProject", folderProject); propElement.SetAttribute("packageName", packageName); propElement.SetAttribute("winExecutableFilename", winExecutableFilename); propElement.SetAttribute("winExecutableIconFile", winExecutableIconFile); propElement.SetAttribute("linuxExecutableFilename", linuxExecutableFilename); propElement.SetAttribute("macExecutableFilename", macExecutableFilename); propElement.SetAttribute("useExternalSourceFiles", useExternalSourceFiles); SerializerElement & extensionsElement = propElement.AddChild("extensions"); extensionsElement.ConsiderAsArrayOf("extension"); for (std::size_t i =0;iGetName()); } if (currentPlatform != NULL) propElement.AddChild("currentPlatform").SetValue(currentPlatform->GetName()); else std::cout << "ERROR: The project current platform is NULL."; resourcesManager.SerializeTo(element.AddChild("resources")); SerializeObjectsTo(element.AddChild("objects")); ObjectGroup::SerializeTo(GetObjectGroups(), element.AddChild("objectsGroups")); GetVariables().SerializeTo(element.AddChild("variables")); element.SetAttribute("firstLayout", firstLayout); gd::SerializerElement & layoutsElement = element.AddChild("layouts"); layoutsElement.ConsiderAsArrayOf("layout"); for ( std::size_t i = 0;i < GetLayoutsCount();i++ ) GetLayout(i).SerializeTo(layoutsElement.AddChild("layout")); SerializerElement & externalEventsElement = element.AddChild("externalEvents"); externalEventsElement.ConsiderAsArrayOf("externalEvents"); for (std::size_t i =0;iSerializeTo(externalLayoutsElement.AddChild("externalLayout")); SerializerElement & externalSourceFilesElement = element.AddChild("externalSourceFiles"); externalSourceFilesElement.ConsiderAsArrayOf("sourceFile"); for (std::size_t i =0;iSerializeTo(externalSourceFilesElement.AddChild("sourceFile")); #if defined(GD_IDE_ONLY) dirty = false; #endif } bool Project::ValidateObjectName(const gd::String & name) { gd::String allowedCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; return !(name.find_first_not_of(allowedCharacters) != gd::String::npos); } gd::String Project::GetBadObjectNameWarning() { return _("Please use only letters, digits\nand underscores ( _ )."); } void Project::ExposeResources(gd::ArbitraryResourceWorker & worker) { //Add project resources std::vector resources = GetResourcesManager().GetAllResourcesList(); for ( std::size_t i = 0;i < resources.size() ;i++ ) { if ( GetResourcesManager().GetResource(resources[i]).UseFile() ) worker.ExposeResource(GetResourcesManager().GetResource(resources[i])); } #if !defined(GD_NO_WX_GUI) gd::SafeYield::Do(); #endif //Add layouts resources for ( std::size_t s = 0;s < GetLayoutsCount();s++ ) { for (std::size_t j = 0;j >::const_iterator sourceFile = find_if(externalSourceFiles.begin(), externalSourceFiles.end(), bind2nd(gd::ExternalSourceFileHasName(), name)); if (sourceFile == externalSourceFiles.end()) return false; return language.empty() || (*sourceFile)->GetLanguage() == language; } gd::SourceFile & Project::GetSourceFile(const gd::String & name) { return *(*find_if(externalSourceFiles.begin(), externalSourceFiles.end(), bind2nd(gd::ExternalSourceFileHasName(), name))); } const gd::SourceFile & Project::GetSourceFile(const gd::String & name) const { return *(*find_if(externalSourceFiles.begin(), externalSourceFiles.end(), bind2nd(gd::ExternalSourceFileHasName(), name))); } void Project::RemoveSourceFile(const gd::String & name) { std::vector< std::shared_ptr >::iterator sourceFile = find_if(externalSourceFiles.begin(), externalSourceFiles.end(), bind2nd(gd::ExternalSourceFileHasName(), name)); if ( sourceFile == externalSourceFiles.end() ) return; externalSourceFiles.erase(sourceFile); } gd::SourceFile & Project::InsertNewSourceFile(const gd::String & name, const gd::String & language, std::size_t position) { if (HasSourceFile(name, language)) return GetSourceFile(name); std::shared_ptr newSourceFile(new SourceFile); newSourceFile->SetLanguage(language); newSourceFile->SetFileName(name); if (positionAppend( new wxPropertyCategory(_("Properties")) ); grid->Append( new wxStringProperty(_("Name of the project"), wxPG_LABEL, GetName()) ); grid->Append( new wxStringProperty(_("Package name"), wxPG_LABEL, GetPackageName()) ); grid->Append( new wxStringProperty(_("Author"), wxPG_LABEL, GetAuthor()) ); grid->Append( new wxStringProperty(_("Globals variables"), wxPG_LABEL, _("Click to edit...")) ); grid->Append( new wxStringProperty(_("Extensions"), wxPG_LABEL, _("Click to edit...")) ); grid->Append( new wxPropertyCategory(_("Window")) ); grid->Append( new wxUIntProperty(_("Width"), wxPG_LABEL, GetMainWindowDefaultWidth()) ); grid->Append( new wxUIntProperty(_("Height"), wxPG_LABEL, GetMainWindowDefaultHeight()) ); grid->Append( new wxBoolProperty(_("Vertical Synchronization"), wxPG_LABEL, IsVerticalSynchronizationEnabledByDefault()) ); grid->Append( new wxBoolProperty(_("Limit the framerate"), wxPG_LABEL, GetMaximumFPS() != -1) ); grid->Append( new wxIntProperty(_("Maximum FPS"), wxPG_LABEL, GetMaximumFPS()) ); grid->Append( new wxUIntProperty(_("Minimum FPS"), wxPG_LABEL, GetMinimumFPS()) ); grid->SetPropertyCell(wxString(_("Globals variables")), 1, _("Click to edit..."), wxNullBitmap, wxSystemSettings::GetColour(wxSYS_COLOUR_HOTLIGHT )); grid->SetPropertyReadOnly(wxString(_("Globals variables"))); grid->SetPropertyCell(wxString(_("Extensions")), 1, _("Click to edit..."), wxNullBitmap, wxSystemSettings::GetColour(wxSYS_COLOUR_HOTLIGHT )); grid->SetPropertyReadOnly(wxString(_("Extensions"))); if ( GetMaximumFPS() == -1 ) { grid->GetProperty(_("Maximum FPS"))->Enable(false); grid->GetProperty(_("Maximum FPS"))->SetValue(""); } else grid->GetProperty(_("Maximum FPS"))->Enable(true); grid->Append( new wxPropertyCategory(_("Generation")) ); grid->Append( new wxStringProperty(_("Windows executable name"), wxPG_LABEL, winExecutableFilename) ); grid->Append( new wxImageFileProperty(_("Windows executable icon"), wxPG_LABEL, winExecutableIconFile) ); grid->Append( new wxStringProperty(_("Linux executable name"), wxPG_LABEL, linuxExecutableFilename) ); grid->Append( new wxStringProperty(_("Mac OS executable name"), wxPG_LABEL, macExecutableFilename) ); grid->Append( new wxPropertyCategory(_("C++ features")) ); grid->Append( new wxBoolProperty(_("Activate the use of C++/JS source files"), wxPG_LABEL, useExternalSourceFiles) ); } void Project::UpdateFromPropertyGrid(wxPropertyGrid * grid) { if ( grid->GetProperty(_("Name of the project")) != NULL) SetName(grid->GetProperty(_("Name of the project"))->GetValueAsString()); if ( grid->GetProperty(_("Author")) != NULL) SetAuthor(grid->GetProperty(_("Author"))->GetValueAsString()); if ( grid->GetProperty(_("Package name")) != NULL) SetPackageName(grid->GetProperty(_("Package name"))->GetValueAsString()); if ( grid->GetProperty(_("Width")) != NULL) SetDefaultWidth(grid->GetProperty(_("Width"))->GetValue().GetInteger()); if ( grid->GetProperty(_("Height")) != NULL) SetDefaultHeight(grid->GetProperty(_("Height"))->GetValue().GetInteger()); if ( grid->GetProperty(_("Vertical Synchronization")) != NULL) SetVerticalSyncActivatedByDefault(grid->GetProperty(_("Vertical Synchronization"))->GetValue().GetBool()); if ( grid->GetProperty(_("Limit the framerate")) != NULL && !grid->GetProperty(_("Limit the framerate"))->GetValue().GetBool()) SetMaximumFPS(-1); else if ( grid->GetProperty(_("Maximum FPS")) != NULL) SetMaximumFPS(grid->GetProperty(_("Maximum FPS"))->GetValue().GetInteger()); if ( grid->GetProperty(_("Minimum FPS")) != NULL) SetMinimumFPS(grid->GetProperty(_("Minimum FPS"))->GetValue().GetInteger()); if ( grid->GetProperty(_("Windows executable name")) != NULL) winExecutableFilename = grid->GetProperty(_("Windows executable name"))->GetValueAsString(); if ( grid->GetProperty(_("Windows executable icon")) != NULL) winExecutableIconFile = grid->GetProperty(_("Windows executable icon"))->GetValueAsString(); if ( grid->GetProperty(_("Linux executable name")) != NULL) linuxExecutableFilename = grid->GetProperty(_("Linux executable name"))->GetValueAsString(); if ( grid->GetProperty(_("Mac OS executable name")) != NULL) macExecutableFilename = grid->GetProperty(_("Mac OS executable name"))->GetValueAsString(); if ( grid->GetProperty(_("Activate the use of C++/JS source files")) != NULL) useExternalSourceFiles =grid->GetProperty(_("Activate the use of C++/JS source files"))->GetValue().GetBool(); } void Project::OnChangeInPropertyGrid(wxPropertyGrid * grid, wxPropertyGridEvent & event) { if (event.GetPropertyName() == _("Limit the framerate") ) grid->EnableProperty(wxString(_("Maximum FPS")), grid->GetProperty(_("Limit the framerate"))->GetValue().GetBool()); UpdateFromPropertyGrid(grid); } void Project::OnSelectionInPropertyGrid(wxPropertyGrid * grid, wxPropertyGridEvent & event) { if ( event.GetColumn() == 1) //Manage button-like properties { if ( event.GetPropertyName() == _("Extensions") ) { gd::ProjectExtensionsDialog dialog(NULL, *this); dialog.ShowModal(); } else if ( event.GetPropertyName() == _("Globals variables") ) { gd::ChooseVariableDialog dialog(NULL, GetVariables(), /*editingOnly=*/true); dialog.SetAssociatedProject(this); dialog.ShowModal(); } } } #endif #endif Project::Project(const Project & other) { Init(other); } Project& Project::operator=(const Project & other) { if ( this != &other ) Init(other); return *this; } void Project::Init(const gd::Project & game) { //Some properties name = game.name; windowWidth = game.windowWidth; windowHeight = game.windowHeight; maxFPS = game.maxFPS; minFPS = game.minFPS; verticalSync = game.verticalSync; #if defined(GD_IDE_ONLY) author = game.author; packageName = game.packageName; folderProject = game.folderProject; latestCompilationDirectory = game.latestCompilationDirectory; objectGroups = game.objectGroups; GDMajorVersion = game.GDMajorVersion; GDMinorVersion = game.GDMinorVersion; currentPlatform = game.currentPlatform; #endif extensionsUsed = game.extensionsUsed; platforms = game.platforms; //Resources resourcesManager = game.resourcesManager; imageManager = std::shared_ptr(new ImageManager(*game.imageManager)); imageManager->SetGame(this); GetObjects().clear(); for (std::size_t i =0;i(game.GetObjects()[i]->Clone()) ); scenes.clear(); for (std::size_t i =0;i(new gd::Layout(*game.scenes[i])) ); #if defined(GD_IDE_ONLY) externalEvents.clear(); for (std::size_t i =0;i(new gd::ExternalEvents(*game.externalEvents[i])) ); #endif externalLayouts.clear(); for (std::size_t i =0;i(new gd::ExternalLayout(*game.externalLayouts[i])) ); #if defined(GD_IDE_ONLY) useExternalSourceFiles = game.useExternalSourceFiles; externalSourceFiles.clear(); for (std::size_t i =0;i(new gd::SourceFile(*game.externalSourceFiles[i])) ); #endif variables = game.GetVariables(); #if defined(GD_IDE_ONLY) gameFile = game.GetProjectFile(); imagesChanged = game.imagesChanged; winExecutableFilename = game.winExecutableFilename; winExecutableIconFile = game.winExecutableIconFile; linuxExecutableFilename = game.linuxExecutableFilename; macExecutableFilename = game.macExecutableFilename; #endif } }