예제 #1
0
        public void LoadProject(string projectFileName, InitializationWindow initializationWindow)
        {
            TimeManager.Initialize();
            var topSection = Section.GetAndStartContextAndTime("All");

            ////////////////// EARLY OUT!!!!!!!!!
            if (!File.Exists(projectFileName))
            {
                GlueGui.ShowException("Could not find the project " + projectFileName + "\n\nOpening Glue without a project.", "Error Loading Project", null);
                return;
            }
            //////////////////// End EARLY OUT////////////////////////////////

            FileWatchManager.PerformFlushing = false;

            bool closeInitWindow = PrepareInitializationWindow(initializationWindow);

            ClosePreviousProject(projectFileName);


            SetInitWindowText("Loading code project");


            ProjectManager.ProjectBase = ProjectCreator.CreateProject(projectFileName);

            bool shouldLoad = true;

            if (ProjectManager.ProjectBase == null)
            {
                DialogResult result = MessageBox.Show(
                    "The project\n\n" + projectFileName + "\n\nis an unknown project type.  Would you like more " +
                    "info on how to fix this problem?", "Unknown Project Type", MessageBoxButtons.YesNo);

                if (result == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start("http://www.flatredball.com/frb/docs/index.php?title=Glue:Reference:Projects:csproj_File");
                }
                shouldLoad = false;
            }

            // see if this project references any plugins that aren't installed:
            var glueFileName = FileManager.RemoveExtension(projectFileName) + ".glux";

            if (System.IO.File.Exists(glueFileName))
            {
                try
                {
                    var tempGlux = GlueProjectSaveExtensions.Load(glueFileName);

                    var requiredPlugins = tempGlux.PluginData.RequiredPlugins;

                    List <string> missingPlugins = new List <string>();
                    foreach (var requiredPlugin in requiredPlugins)
                    {
                        if (PluginManager.AllPluginContainers.Any(item => item.Name == requiredPlugin) == false)
                        {
                            missingPlugins.Add(requiredPlugin);
                        }
                    }

                    if (missingPlugins.Count != 0)
                    {
                        var message = $"The project {glueFileName} requires the following plugins:";

                        foreach (var item in missingPlugins)
                        {
                            message += "\n" + item;
                        }

                        message += "\nWould you like to load the project anyway? It may not run, or may run incorrectly until all plugins are installed.";

                        var result = MessageBox.Show(message, "Missing Plugins", MessageBoxButtons.YesNo);

                        shouldLoad = result == DialogResult.Yes;
                    }
                }
                catch (Exception e)
                {
                    GlueGui.ShowMessageBox($"Could not load .glux file {glueFileName}. Error:\n\n{e.ToString()}");
                    shouldLoad = false;
                }
            }

            if (shouldLoad)
            {
                ProjectManager.ProjectBase.Load(projectFileName);


                SetInitWindowText("Finding Game class");


                FileWatchManager.UpdateToProjectDirectory();
                FileManager.RelativeDirectory = FileManager.GetDirectory(projectFileName);
                // this will make other threads work properly:
                FileManager.DefaultRelativeDirectory = FileManager.RelativeDirectory;

                ElementViewWindow.AddDirectoryNodes();

                #region Load the GlueProjectSave file if one exists

                string glueProjectFile = ProjectManager.GlueProjectFileName;
                bool   shouldSaveGlux  = false;

                if (!FileManager.FileExists(glueProjectFile))
                {
                    ProjectManager.GlueProjectSave = new GlueProjectSave();

                    // temporary - eventually this will just be done in the .glux itself
                    Plugins.EmbeddedPlugins.CameraPlugin.CameraMainPlugin.CreateGlueProjectSettingsFor(ProjectManager.GlueProjectSave);


                    ProjectManager.FindGameClass();
                    GluxCommands.Self.SaveGlux();

                    // no need to do this - will do it in PerformLoadGlux:
                    //PluginManager.ReactToLoadedGlux(ProjectManager.GlueProjectSave, glueProjectFile);
                    //shouldSaveGlux = true;

                    //// There's not a lot of code to generate so we can do it on the main thread
                    //// so we get the save to occur after
                    //GlueCommands.Self.GenerateCodeCommands.GenerateAllCodeSync();
                    //ProjectManager.SaveProjects();
                }
                PerformGluxLoad(projectFileName, glueProjectFile);

                #endregion

                SetInitWindowText("Cleaning extra Screens and Entities");


                foreach (ScreenTreeNode screenNode in ElementViewWindow.AllScreens)
                {
                    if (screenNode.ScreenSave == null)
                    {
                        ScreenSave screenSave = new ScreenSave();
                        screenSave.Name = screenNode.Text;

                        ProjectManager.GlueProjectSave.Screens.Add(screenSave);
                        screenNode.ScreenSave = screenSave;
                    }
                }

                foreach (EntityTreeNode entityNode in ElementViewWindow.AllEntities)
                {
                    if (entityNode.EntitySave == null)
                    {
                        EntitySave entitySave = new EntitySave();
                        entitySave.Name = entityNode.Text;
                        entitySave.Tags.Add("GLUE");
                        entitySave.Source = "GLUE";

                        ProjectManager.GlueProjectSave.Entities.Add(entitySave);
                        entityNode.EntitySave = entitySave;
                    }
                }


                UnreferencedFilesManager.Self.RefreshUnreferencedFiles(true);

                MainGlueWindow.Self.Text = "FlatRedBall Glue - " + projectFileName;
                MainGlueWindow.Self.SaveRecentProject(projectFileName);

                if (shouldSaveGlux)
                {
                    GluxCommands.Self.SaveGlux();
                }

                TaskManager.Self.AddSync(GlueCommands.Self.ProjectCommands.SaveProjects, "Save all projects");

                FileWatchManager.PerformFlushing = true;
                FileWatchManager.FlushAndClearIgnores();
            }
            if (closeInitWindow)
            {
                mCurrentInitWindow.Close();
            }


            Section.EndContextAndTime();
            // If we ever want to make things go faster, turn this back on and let's see what's going on.
            //topSection.Save("Sections.xml");
        }
예제 #2
0
        public static bool UpdateFile(string changedFile)
        {
            bool shouldSave = false;
            bool handled    = false;

            lock (mUpdateFileLock)
            {
                handled = TryHandleProjectFileChanges(changedFile);

                string projectFileName = ProjectManager.ProjectBase.FullFileName;

                var standardizedGlux = FileManager.RemoveExtension(FileManager.Standardize(projectFileName).ToLower()) + ".glux";
                var partialGlux      = FileManager.RemoveExtension(FileManager.Standardize(projectFileName).ToLower()) + @"\..*\.generated\.glux";
                var partialGluxRegex = new Regex(partialGlux);
                if (!handled && ((changedFile.ToLower() == standardizedGlux) || partialGluxRegex.IsMatch(changedFile.ToLower())))
                {
                    TaskManager.Self.OnUiThread(ReloadGlux);
                    handled = true;
                }

                if (ProjectManager.IsContent(changedFile))
                {
                    PluginManager.ReactToChangedFile(changedFile);
                }

                #region If it's a CSV, then re-generate the code for the objects

                string extension = FileManager.GetExtension(changedFile);

                if (extension == "csv" ||
                    extension == "txt")
                {
                    ReferencedFileSave rfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(changedFile);

                    bool shouldGenerate = rfs != null &&
                                          (extension == "csv" || rfs.TreatAsCsv) &&
                                          rfs.IsDatabaseForLocalizing == false;

                    if (shouldGenerate)
                    {
                        try
                        {
                            CsvCodeGenerator.GenerateAndSaveDataClass(rfs, rfs.CsvDelimiter);

                            shouldSave = true;
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show("Error saving Class from CSV " + rfs.Name);
                        }
                    }
                }


                #endregion

                #region If it's a file that references other content we may need to update the project

                if (FileHelper.DoesFileReferenceContent(changedFile))
                {
                    ReferencedFileSave rfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(changedFile);


                    if (rfs != null)
                    {
                        string error;
                        rfs.RefreshSourceFileCache(false, out error);

                        if (!string.IsNullOrEmpty(error))
                        {
                            ErrorReporter.ReportError(rfs.Name, error, false);
                        }
                        else
                        {
                            handled = true;
                        }

                        handled   |= ProjectManager.UpdateFileMembershipInProject(rfs);
                        shouldSave = true;

                        MainGlueWindow.Self.Invoke((MethodInvoker) delegate
                        {
                            if (rfs.GetContainerType() == ContainerType.Entity)
                            {
                                if (EditorLogic.CurrentEntityTreeNode != null)
                                {
                                    if (EditorLogic.CurrentEntitySave == rfs.GetContainer())
                                    {
                                        PluginManager.RefreshCurrentElement();
                                    }
                                }
                            }
                            else if (rfs.GetContainerType() == ContainerType.Screen)
                            {
                                if (EditorLogic.CurrentScreenTreeNode != null)
                                {
                                    if (EditorLogic.CurrentScreenSave == rfs.GetContainer())
                                    {
                                        PluginManager.RefreshCurrentElement();
                                    }
                                }
                            }
                        });
                    }
                    else
                    {
                        // There may not be a RFS for this in Glue, but even if there's not,
                        // this file may be referenced by other RFS's.  I don't want to do a full
                        // project scan, so we'll just see if this file is part of Visual Studio.  If so
                        // then let's add its children

                        if (ProjectManager.ContentProject.IsFilePartOfProject(changedFile))
                        {
                            string relativePath = ProjectManager.MakeRelativeContent(changedFile);

                            shouldSave |= ProjectManager.UpdateFileMembershipInProject(
                                ProjectManager.ProjectBase, relativePath, false, false);
                            handled |= shouldSave;
                        }
                    }
                }

                #endregion

                #region If it's a .cs file, we should see if we've added a new .cs file, and if so refresh the Element for it
                if (extension == "cs")
                {
                    TaskManager.Self.OnUiThread(() => ReactToChangedCodeFile(changedFile));
                }


                #endregion

                #region Maybe it's a directory that was added or removed

                if (FileManager.GetExtension(changedFile) == "")
                {
                    ElementViewWindow.Invoke((MethodInvoker) delegate
                    {
                        // It's a directory, so let's just rebuild our directory TreeNodes
                        ElementViewWindow.AddDirectoryNodes();
                    });
                }

                #endregion


                #region Check for broken references to objects in file - like an Entity may reference an object in a file but it may have been removed

                if (ObjectFinder.Self.GetReferencedFileSaveFromFile(changedFile) != null)
                {
                    // This is a file that is part of the project, so let's see if any named objects are missing references
                    CheckForBrokenReferencesToObjectsInFile(changedFile);
                }

                #endregion

                // This could be an externally built file:

                ProjectManager.UpdateExternallyBuiltFile(changedFile);

                if (handled)
                {
                    PluginManager.ReceiveOutput("Handled changed file: " + changedFile);
                }

                if (shouldSave)
                {
                    ProjectManager.SaveProjects();
                }
            }

            return(handled);
        }
예제 #3
0
        private void PerformGluxLoad(string projectFileName, string glueProjectFile)
        {
            SetInitWindowText("Loading .glux");


            bool succeeded = true;

            succeeded = DeserializeGluxXmlInternal(projectFileName, glueProjectFile);

            if (succeeded)
            {
                // This seems to take some time (like 1 second). Can we possibly
                // make it faster by having it chek Game1.cs first? Why is this so slow?
                ProjectManager.FindGameClass();

                AvailableAssetTypes.Self.AdditionalExtensionsToTreatAsAssets.Clear();

                IdentifyAdditionalAssetTypes();

                SetInitWindowText("Finding and fixing .glux errors");
                ProjectManager.GlueProjectSave.FixErrors(true);
                ProjectManager.GlueProjectSave.RemoveInvalidStatesFromNamedObjects(true);

                FixProjectErrors();

                SetUnsetValues();



                ProjectManager.LoadOrCreateProjectSpecificSettings(FileManager.GetDirectory(projectFileName));

                SetInitWindowText("Notifying plugins of project...");


                // The project specific settings are needed before the plugins do their thing...
                PluginManager.ReactToLoadedGluxEarly(ProjectManager.GlueProjectSave);

                // and after that's done we can validate that the build tools are there
                BuildToolAssociationManager.Self.ProjectSpecificBuildTools.ValidateBuildTools(FileManager.GetDirectory(projectFileName));

                ProjectManager.GlueProjectSave.UpdateIfTranslationIsUsed();

                Section.GetAndStartContextAndTime("Add items");

                SetInitWindowText("Creating project view...");


                AddEmptyTreeItems();

                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("RefreshSourceFileCache");

                // This has to be done before the tree nodes are created.  The reason is because a user
                // may create a ReferencedFileSave using a source type, but not check in the built file.
                // Glue depends on the built file being there, so we gotta build to make sure that file gets
                // generated.
                // Update on May 4, 2011:  This should be done AFTER BuildAllOutOfDateFiles because Refreshing
                // source file cache requires looking at all referenced files, and this requires the files existing
                // so that dependencies can be tracked.
                // Update May 4, 2011 Part 2:  The SourceFileCache is used when building files.  So instead, the refreshing
                // of the source file cache will also build a file if it encounters a missing file.  This should greatly reduce
                // popup count.
                SetInitWindowText("Refreshing Source File Cache...");
                RefreshSourceFileCache();

                SetInitWindowText("Checking for additional missing files...");

                SetInitWindowText("Building out of date external files...");
                BuildAllOutOfDateFiles();
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("RefreshGlobalContentDirectory");

                SetInitWindowText("Refreshing global content dictionary...");
                ReferencedFileSaveCodeGenerator.RefreshGlobalContentDictionary();
                ContentLoadWriter.SuppressGlobalContentDictionaryRefresh = true;

                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("Screens");

                SetInitWindowText("Creating tree nodes...");

                CreateScreenTreeNodes();
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("Entities");

                CreateEntityTreeNodes();
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("SortEntities");



                ElementViewWindow.SortEntities();

                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("PrepareSyncedProjects");

                PrepareSyncedProjects(projectFileName);

                mLastLoadedFilename = projectFileName;
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("MakeGeneratedItemsNested");

                // This should happen after loading synced projects
                MakeGeneratedItemsNested();
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("GlobalContent");


                #region Update GlobalContent UI and code

                SetInitWindowText("Updating global content");

                ElementViewWindow.UpdateGlobalContentTreeNodes(false);

                // Screens and Entities have the membership of their files
                // automatically updated when the tree nodes are created. This
                // is bad. GlobalContent does this better by requiring the call
                // to be explicitly made:
                UpdateGlobalContentFileProjectMembership();

                ContentLoadWriter.UpdateLoadGlobalContentCode();

                #endregion
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("Startup");

                SetInitWindowText("Setting StartUp Screen");


                #region Set the Startup Screen

                if (!string.IsNullOrEmpty(ProjectManager.GlueProjectSave.StartUpScreen))
                {
                    TreeNode startUpTreeNode = GlueState.Self.Find.ScreenTreeNode(ProjectManager.GlueProjectSave.StartUpScreen);

                    ElementViewWindow.StartUpScreen = startUpTreeNode;

                    if (startUpTreeNode == null)
                    {
                        ProjectManager.GlueProjectSave.StartUpScreen = "";
                    }
                }

                #endregion

                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("Performance code");


                FactoryCodeGenerator.AddGeneratedPerformanceTypes();
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("CSV generation");

                CsvCodeGenerator.RegenerateAllCsvs();
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("PluginManager Init");

                PluginManager.Initialize(false);

                SetInitWindowText("Notifying Plugins of startup");


                PluginManager.ReactToLoadedGlux(ProjectManager.GlueProjectSave, glueProjectFile, SetInitWindowText);
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("GenerateAllCode");
                SetInitWindowText("Generating all code");
                GlueCommands.Self.GenerateCodeCommands.GenerateAllCode();
                Section.EndContextAndTime();
                ContentLoadWriter.SuppressGlobalContentDictionaryRefresh = false;
            }
        }
예제 #4
0
        private void CreateEntityTreeNodes()
        {
            //ProjectManager.GlueProjectSave.Entities[78].NamedObjects[9].UpdateCustomProperties();


            // Let's make this faster.
            //foreach (EntitySave entity in ProjectManager.GlueProjectSave.Entities)
            // Actually, the contained functions may show popups, and if 2 simultaneous popups
            // are shown, one can cancel the other out and this can cause Glue to freeze. This means
            // we can't parallel foreah it
            //Parallel.ForEach(ProjectManager.GlueProjectSave.Entities, (entity) =>
            foreach (EntitySave entity in ProjectManager.GlueProjectSave.Entities)
            {
                entity.UpdateCustomProperties();
                entity.UpdateFromBaseType();
            }

            for (int i = 0; i < ProjectManager.GlueProjectSave.Entities.Count; i++)
            {
                EntitySave entitySave = ProjectManager.GlueProjectSave.Entities[i];
                // This is so fast that we no longer need to show the
                // user details - and not doing it will make things even faster
                //SetInitWindowText("Creating Entity: " + entitySave.Name);

                EntityTreeNode entityTreeNode = GlueState.Self.Find.EntityTreeNode(entitySave.Name);

                #region If there is no EntityTreeNode

                if (entityTreeNode == null)
                {
                    // See if the file exists
                    string fileToSearchFor = FileManager.RelativeDirectory + entitySave.Name + ".cs";

                    if (System.IO.File.Exists(fileToSearchFor))
                    {
                        // If we got here that means there's probably not a build item for this file
                        MessageBox.Show("The Glue project has the following Entity:\n" + entitySave.Name + "\n" +
                                        "but this file is not part of Visual Studio.  This file may have been removed manually or " +
                                        "there may have been some saving error.  You should close Glue, manually add this and the Generated file " +
                                        "to Visual Studio, then restart Glue.");
                        MainGlueWindow.Self.HasErrorOccurred = true;
                    }
                    else
                    {
                        MultiButtonMessageBox mbmb = new MultiButtonMessageBox();

                        mbmb.MessageText = "Could not find the file name\n\n" + fileToSearchFor + "\n\nwhich is used by the entity\n\n" + entitySave.Name + "\n\n" +
                                           "What would you like to do?";


                        mbmb.AddButton("Create a new custom code file", DialogResult.Yes);
                        mbmb.AddButton("Delete this Entity", DialogResult.No);
                        mbmb.AddButton("Do nothing.  The Entity will not show up in Glue until this problem is fixed.", DialogResult.Cancel);

                        DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self);

                        switch (result)
                        {
                        case DialogResult.Yes:
                            if (entityTreeNode == null)
                            {
                                entityTreeNode = ElementViewWindow.AddEntity(entitySave);
                            }

                            CodeWriter.GenerateAndAddElementCustomCode(entitySave);

                            //entityTreeNode.GenerateCode(ProjectManager.EntityTemplateCode);

                            break;

                        case DialogResult.No:
                            ProjectManager.GlueProjectSave.Entities.RemoveAt(i);
                            i--;
                            continue;

                        //break;
                        case DialogResult.Cancel:
                            // do nothing
                            continue;

                            //break;
                        }

                        System.Windows.Forms.MessageBox.Show("Could not create the EntitySave for " + entitySave.Name +
                                                             " because the following file doesn't exist\n\n" + fileToSearchFor);
                    }
                    //mGlueProjectSave.Entities.RemoveAt(i);
                    //i--;
                }

                #endregion


                entityTreeNode.EntitySave = entitySave;

                CheckForMissingCustomFile(entityTreeNode);


                entityTreeNode.UpdateReferencedTreeNodes(performSave: false);

                // moved above
                //entityTreeNode.EntitySave.UpdateCustomProperties();
                //entityTreeNode.EntitySave.UpdateFromBaseType();
            }
        }
예제 #5
0
        public void AddScreen(ScreenSave screenSave, bool suppressAlreadyExistingFileMessage = false)
        {
            var glueProject = GlueState.Self.CurrentGlueProject;

            string screenName = FileManager.RemovePath(screenSave.Name);

            string fileName = screenSave.Name + ".cs";

            screenSave.Tags.Add("GLUE");
            screenSave.Source = "GLUE";

            glueProject.Screens.Add(screenSave);
            glueProject.Screens.SortByName();

            #region Create the Screen code (not the generated version)


            var item = ProjectManager.ProjectBase.AddCodeBuildItem(fileName);


            string projectNamespace = ProjectManager.ProjectNamespace;

            StringBuilder stringBuilder = new StringBuilder(CodeWriter.ScreenTemplateCode);

            CodeWriter.SetClassNameAndNamespace(
                projectNamespace + ".Screens",
                screenName,
                stringBuilder);

            string modifiedTemplate = stringBuilder.ToString();

            string fullNonGeneratedFileName = FileManager.RelativeDirectory + fileName;

            if (FileManager.FileExists(fullNonGeneratedFileName))
            {
                if (!suppressAlreadyExistingFileMessage)
                {
                    MessageBox.Show("There is already a file named\n\n" + fullNonGeneratedFileName + "\n\nThis file will be used instead of creating a new one just in case you have code that you want to keep there.");
                }
            }
            else
            {
                FileManager.SaveText(
                    modifiedTemplate,
                    fullNonGeneratedFileName
                    );
            }


            #endregion

            #region Create <ScreenName>.Generated.cs

            string generatedFileName = @"Screens\" + screenName + ".Generated.cs";
            ProjectManager.CodeProjectHelper.CreateAndAddPartialCodeFile(generatedFileName, true);


            #endregion

            // We used to set the
            // StartUpScreen whenever
            // the user made a new Screen.
            // The reason is we assumed that
            // the user wanted to work on this
            // Screen, so we set it as the startup
            // so they could run the game right away.
            // Now we only want to do it if there are no
            // other Screens.  Otherwise they can just use
            // GlueView.
            var screenTreeNode = ElementViewWindow.AddScreen(screenSave);
            if (glueProject.Screens.Count == 1)
            {
                ElementViewWindow.StartUpScreen = screenTreeNode;
            }

            PluginManager.ReactToNewScreenCreated(screenSave);


            ProjectManager.SaveProjects();

            GluxCommands.Self.SaveGlux();
        }
예제 #6
0
        public void AddEntity(EntitySave entitySave, bool suppressAlreadyExistingFileMessage)
        {
            string fileName = entitySave.Name + ".cs";

            entitySave.Tags.Add("GLUE");
            entitySave.Source = "GLUE";

            var glueProject = GlueState.Self.CurrentGlueProject;

            glueProject.Entities.Add(entitySave);
            glueProject.Entities.SortByName();


            #region Create the Entity (not the generated version)

            var vsProjectBase = GlueState.Self.CurrentMainProject;

            var item = vsProjectBase.AddCodeBuildItem(fileName);

            string projectNamespace = GlueState.Self.ProjectNamespace;


            string directory = FileManager.GetDirectory(entitySave.Name);
            if (!directory.ToLower().EndsWith(projectNamespace.ToLower() + "/entities/"))
            {
                GlueCommands.Self.GenerateCodeCommands.GetNamespaceForElement(entitySave);
                // test this on doubly-embedded Entities.
                projectNamespace = GlueCommands.Self.GenerateCodeCommands.GetNamespaceForElement(entitySave);
                // += (".Entities." + FileManager.RemovePath(directory)).Replace("/", "");
            }

            StringBuilder stringBuilder = new StringBuilder(CodeWriter.EntityTemplateCode);

            CodeWriter.SetClassNameAndNamespace(
                projectNamespace,
                entitySave.ClassName,
                stringBuilder);

            string modifiedTemplate = stringBuilder.ToString();

            string nonGeneratedFileName = FileManager.RelativeDirectory + fileName;

            if (FileManager.FileExists(nonGeneratedFileName))
            {
                if (!suppressAlreadyExistingFileMessage)
                {
                    MessageBox.Show("There is already a file named\n\n" + nonGeneratedFileName + "\n\nThis file will be used instead of creating a new one just in case you have code that you want to keep there.");
                }
            }
            else
            {
                FileManager.SaveText(modifiedTemplate, nonGeneratedFileName);
            }
            #endregion

            #region Create <EntityName>.Generated.cs



            string generatedFileName = FileManager.MakeRelative(directory).Replace("/", "\\") + entitySave.ClassName + ".Generated.cs";


            ProjectManager.CodeProjectHelper.CreateAndAddPartialCodeFile(generatedFileName, true);

            #endregion



            ElementViewWindow.AddEntity(entitySave);

            ProjectManager.SaveProjects();


            GluxCommands.Self.SaveGlux();
        }
예제 #7
0
        public ReferencedFileSave AddSingleFileTo(string fileName, string rfsName, string extraCommandLineArguments,
                                                  BuildToolAssociation buildToolAssociation, bool isBuiltFile, string options, IElement sourceElement, string directoryOfTreeNode)
        {
            ReferencedFileSave toReturn = null;

            //string directoryOfTreeNode = EditorLogic.CurrentTreeNode.GetRelativePath();

            string targetDirectory = FlatRedBall.Glue.Plugins.ExportedImplementations.CommandInterfaces.ElementCommands.GetFullPathContentDirectory(sourceElement, directoryOfTreeNode);
            string targetFile      = fileName;

            string errorMessage = null;
            bool   failed       = false;

            if (isBuiltFile)
            {
                targetFile = targetDirectory + rfsName + "." + buildToolAssociation.DestinationFileType;
            }

            string targetFileWithOriginalExtension = FileManager.RemoveExtension(targetFile) + "." + FileManager.GetExtension(fileName);

            bool copied = false;

            var projectRootDirectory = ProjectManager.ProjectRootDirectory;

            if (!FileManager.IsRelativeTo(fileName, projectRootDirectory) && isBuiltFile)
            {
                copied = PluginManager.TryCopyFile(fileName, targetFileWithOriginalExtension);

                if (!copied)
                {
                    errorMessage = $"Could not add the file\n{fileName}\n\nBecause it is not relative to\n{ProjectManager.ProjectRootDirectory}\n\nPlease move this file to a folder inside your project and try again";
                    failed       = true;
                }
                else
                {
                    // the file was copied - from now on just use the copied file name:
                    fileName = targetFileWithOriginalExtension;
                }
            }

            if (!failed)
            {
                if (isBuiltFile)
                {
                    errorMessage = buildToolAssociation.PerformBuildOn(fileName, targetFile, extraCommandLineArguments, PluginManager.ReceiveOutput, PluginManager.ReceiveError);
                    failed       = true;
                }
            }

            if (!failed)
            {
                string creationReport;

                string directoryToUse = null;

                if (!isBuiltFile)
                {
                    directoryToUse = directoryOfTreeNode;
                }

                var assetTypeInfo = AvailableAssetTypes.Self.GetAssetTypeFromExtension(FileManager.GetExtension(targetFile));


                toReturn = CreateReferencedFileSaveForExistingFile(
                    sourceElement, directoryToUse, targetFile, PromptHandleEnum.Prompt,
                    assetTypeInfo,
                    out creationReport, out errorMessage);

                if (!string.IsNullOrEmpty(errorMessage))
                {
                    failed = true;
                }
                else if (toReturn != null && string.IsNullOrEmpty(toReturn.Name))
                {
                    errorMessage = "There was an error creating the named object for\n" + fileName;
                    failed       = true;
                }
            }

            if (!failed)
            {
                if (isBuiltFile)
                {
                    toReturn.SourceFile          = ProjectManager.MakeRelativeContent(fileName);
                    toReturn.AdditionalArguments = extraCommandLineArguments;
                    toReturn.BuildTool           = buildToolAssociation.ToString();

                    // If a background sync is happening, this can lock the thread, so we want to
                    // make sure this doesn't happen at the same time as a background sync:
                    TaskManager.Self.AddAsyncTask(() =>
                    {
                        UpdateReactor.UpdateFile(ProjectManager.MakeAbsolute(toReturn.Name));
                    },
                                                  "Updating file " + toReturn.Name);
                    string directoryOfFile = FileManager.GetDirectory(ProjectManager.MakeAbsolute(fileName));

                    RightClickHelper.SetExternallyBuiltFileIfHigherThanCurrent(directoryOfFile, false);
                }
            }

            if (!failed)
            {
                TaskManager.Self.OnUiThread(() =>
                {
                    ElementViewWindow.UpdateChangedElements();
                });

                if (sourceElement == null)
                {
                    GlueCommands.Self.RefreshCommands.RefreshGlobalContent();
                }

                PluginManager.ReactToNewFile(toReturn);
                GluxCommands.Self.SaveGlux();
                TaskManager.Self.AddSync(GluxCommands.Self.ProjectCommands.SaveProjects, "Saving projects after adding file");
            }

            if (!string.IsNullOrWhiteSpace(errorMessage))
            {
                PluginManager.ReceiveError(errorMessage);
                // I think we should show an error message.  I had a user
                // try to add a file and no popup appeared telling them that
                // the entity was named that.
                //MessageBox.Show(errorMessage);
                GlueCommands.Self.DialogCommands.ShowMessageBox(errorMessage);
            }

            if (toReturn != null)
            {
                ApplyOptions(toReturn, options);

                TaskManager.Self.AddSync(() =>
                                         TaskManager.Self.OnUiThread(() =>
                                                                     GlueState.Self.CurrentReferencedFileSave = toReturn), "Select new file");
            }

            return(toReturn);
        }
예제 #8
0
        public void RemoveReferencedFile(ReferencedFileSave referencedFileToRemove, List <string> additionalFilesToRemove, bool regenerateCode)
        {
            var isContained = GlueState.Self.Find.IfReferencedFileSaveIsReferenced(referencedFileToRemove);

            /////////////////////////Early Out//////////////////////////////
            if (!isContained)
            {
                return;
            }
            ////////////////////////End Early Out/////////////////////////////



            // There are some things that need to happen:
            // 1.  Remove the ReferencedFileSave from the Glue project (GLUX)
            // 2.  Remove the GUI item
            // 3.  Remove the item from the Visual Studio project.
            IElement container = referencedFileToRemove.GetContainer();

            #region Remove the file from the current Screen or Entity if there is a current Screen or Entity

            if (container != null)
            {
                // The referenced file better be a globally referenced file


                if (!container.ReferencedFiles.Contains(referencedFileToRemove))
                {
                    throw new ArgumentException();
                }
                else
                {
                    container.ReferencedFiles.Remove(referencedFileToRemove);
                }
                // Ask about any NamedObjects that reference this file.
                for (int i = container.NamedObjects.Count - 1; i > -1; i--)
                {
                    var nos = container.NamedObjects[i];
                    if (nos.SourceType == SourceType.File && nos.SourceFile == referencedFileToRemove.Name)
                    {
                        MainGlueWindow.Self.Invoke(() =>
                        {
                            // Ask the user what to do here - remove it?  Keep it and not compile?
                            MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                            mbmb.MessageText           = "The object\n" + nos.ToString() + "\nreferences the file\n" + referencedFileToRemove.Name +
                                                         "\nWhat would you like to do?";
                            mbmb.AddButton("Remove this object", DialogResult.Yes);
                            mbmb.AddButton("Keep it (object will not be valid until changed)", DialogResult.No);

                            var result = mbmb.ShowDialog();

                            if (result == DialogResult.Yes)
                            {
                                container.NamedObjects.RemoveAt(i);
                            }
                        });
                    }
                    nos.ResetVariablesReferencing(referencedFileToRemove);
                }

                MainGlueWindow.Self.Invoke(() =>
                {
                    if (EditorLogic.CurrentScreenTreeNode != null)
                    {
                        EditorLogic.CurrentScreenTreeNode.UpdateReferencedTreeNodes();
                    }
                    else if (EditorLogic.CurrentEntityTreeNode != null)
                    {
                        EditorLogic.CurrentEntityTreeNode.UpdateReferencedTreeNodes();
                    }
                    if (regenerateCode)
                    {
                        ElementViewWindow.GenerateSelectedElementCode();
                    }
                });
            }
            #endregion

            #region else, the file is likely part of the GlobalContentFile

            else
            {
                ProjectManager.GlueProjectSave.GlobalFiles.Remove(referencedFileToRemove);
                ProjectManager.GlueProjectSave.GlobalContentHasChanged = true;

                // Much faster to just remove the tree node.  This was done
                // to reuse code and make things reactive, but this has gotten
                // slow on bigger projects.
                //ElementViewWindow.UpdateGlobalContentTreeNodes(false); // don't save here because projects will get saved below

                Action refreshUiAction = () =>
                {
                    TreeNode treeNode = GlueState.Self.Find.ReferencedFileSaveTreeNode(referencedFileToRemove);
                    if (treeNode != null)
                    {
                        // treeNode can be null if the user presses delete + enter really really fast, stacking 2 remove
                        // actions
                        if (treeNode.Tag != referencedFileToRemove)
                        {
                            throw new Exception("Error removing the tree node - the selected tree node doesn't reference the file being removed");
                        }

                        treeNode.Parent.Nodes.Remove(treeNode);
                    }
                };

                MainGlueWindow.Self.Invoke((MethodInvoker) delegate
                {
                    refreshUiAction();
                }
                                           );


                GlobalContentCodeGenerator.UpdateLoadGlobalContentCode();

                List <IElement> elements = ObjectFinder.Self.GetAllElementsReferencingFile(referencedFileToRemove.Name);

                foreach (IElement element in elements)
                {
                    if (regenerateCode)
                    {
                        CodeWriter.GenerateCode(element);
                    }
                }
            }

            #endregion


            // November 10, 2015
            // I feel like this may
            // have been old code before
            // we had full dependency tracking
            // in Glue. This file should only be
            // removed from the project if nothing
            // else references it, including no entities.
            // This code does just entities/screens/global
            // content, but doesn't check the full dependency
            // tree. I think we can just remove it and depend on
            // the code below.
            // Actually, removing this seems to cause problems - files
            // that should be removed aren't. So instead we'll chnage the
            // call to use the dependency tree:
            // replace:

            List <string> referencedFiles =
                GlueCommands.Self.FileCommands.GetAllReferencedFileNames().Select(item => item.ToLowerInvariant()).ToList();

            string absoluteToLower   = GlueCommands.Self.GetAbsoluteFileName(referencedFileToRemove).ToLowerInvariant();
            string relativeToProject = FileManager.MakeRelative(absoluteToLower, GlueState.Self.ContentDirectory);

            bool isReferencedByOtherContent = referencedFiles.Contains(relativeToProject);

            if (isReferencedByOtherContent == false)
            {
                additionalFilesToRemove.Add(referencedFileToRemove.GetRelativePath());

                string itemName     = referencedFileToRemove.GetRelativePath();
                string absoluteName = ProjectManager.MakeAbsolute(referencedFileToRemove.Name, true);

                // I don't know why we were removing the file from the ProjectBase - it should
                // be from the Content project
                //ProjectManager.RemoveItemFromProject(ProjectManager.ProjectBase, itemName);
                ProjectManager.RemoveItemFromProject(ProjectManager.ProjectBase.ContentProject, itemName, performSave: false);

                foreach (ProjectBase syncedProject in ProjectManager.SyncedProjects)
                {
                    ProjectManager.RemoveItemFromProject(syncedProject.ContentProject, absoluteName);
                }
            }



            if (ProjectManager.IsContent(referencedFileToRemove.Name))
            {
                UnreferencedFilesManager.Self.RefreshUnreferencedFiles(false);
                foreach (var file in UnreferencedFilesManager.LastAddedUnreferencedFiles)
                {
                    additionalFilesToRemove.Add(file.FilePath);
                }
            }

            ReactToRemovalIfCsv(referencedFileToRemove, additionalFilesToRemove);

            GluxCommands.Self.SaveGlux();
        }
예제 #9
0
        public void LoadProject(string projectFileName, InitializationWindow initializationWindow = null)
        {
            TimeManager.Initialize();
            var topSection = Section.GetAndStartContextAndTime("All");

            ////////////////// EARLY OUT!!!!!!!!!
            if (!File.Exists(projectFileName))
            {
                GlueGui.ShowException("Could not find the project " + projectFileName + "\n\nOpening Glue without a project.", "Error Loading Project", null);
                return;
            }
            //////////////////// End EARLY OUT////////////////////////////////

            FileWatchManager.PerformFlushing = false;

            bool closeInitWindow = PrepareInitializationWindow(initializationWindow);

            // close the project before turning off task processing...
            ClosePreviousProject(projectFileName);

            TaskManager.Self.WaitForAllTasksFinished(pumpEvents: true);

            // turn off task processing while this is loading, so that no background tasks are running while plugins are starting up.
            // Do this *after* closing previous project, because closing previous project waits for all tasks to finish.
            TaskManager.Self.IsTaskProcessingEnabled = false;

            SetInitWindowText("Loading code project");

            var result = ProjectCreator.CreateProject(projectFileName);

            ProjectManager.ProjectBase = result.Project;

            bool shouldLoad = result.Project != null;

            if (shouldLoad && result.ShouldTryToLoadProject)
            {
                shouldLoad = DetermineIfShouldLoad(projectFileName);
            }

            if (shouldLoad)
            {
                ProjectManager.ProjectBase.Load(projectFileName);

                var sln = GlueState.Self.CurrentSlnFileName;

                if (sln == null)
                {
                    GlueCommands.Self.PrintError("Could not find .sln file for project - this may cause file reference errors, and may need to be manually fixed");
                }


                SetInitWindowText("Finding Game class");


                FileWatchManager.UpdateToProjectDirectory();
                FileManager.RelativeDirectory = FileManager.GetDirectory(projectFileName);
                // this will make other threads work properly:
                FileManager.DefaultRelativeDirectory = FileManager.RelativeDirectory;

                ElementViewWindow.AddDirectoryNodes();

                #region Load the GlueProjectSave file if one exists

                string glueProjectFile = ProjectManager.GlueProjectFileName;
                bool   shouldSaveGlux  = false;

                if (!FileManager.FileExists(glueProjectFile))
                {
                    ProjectManager.GlueProjectSave = new GlueProjectSave();

                    GlueCommands.Self.PrintOutput($"Trying to load {glueProjectFile}, but could not find it, so" +
                                                  $"creating a new .glux file");

                    // temporary - eventually this will just be done in the .glux itself, or by the plugin
                    // but for now we do it here because we only want to do it on new projects
                    Plugins.EmbeddedPlugins.CameraPlugin.CameraMainPlugin.CreateGlueProjectSettingsFor(ProjectManager.GlueProjectSave);


                    ProjectManager.FindGameClass();
                    GluxCommands.Self.SaveGlux();

                    // no need to do this - will do it in PerformLoadGlux:
                    //PluginManager.ReactToLoadedGlux(ProjectManager.GlueProjectSave, glueProjectFile);
                    //shouldSaveGlux = true;

                    //// There's not a lot of code to generate so we can do it on the main thread
                    //// so we get the save to occur after
                    //GlueCommands.Self.GenerateCodeCommands.GenerateAllCodeSync();
                    //ProjectManager.SaveProjects();
                }
                PerformGluxLoad(projectFileName, glueProjectFile);

                #endregion

                SetInitWindowText("Cleaning extra Screens and Entities");


                foreach (ScreenTreeNode screenNode in ElementViewWindow.AllScreens)
                {
                    if (screenNode.SaveObject == null)
                    {
                        ScreenSave screenSave = new ScreenSave();
                        screenSave.Name = screenNode.Text;

                        ProjectManager.GlueProjectSave.Screens.Add(screenSave);
                        screenNode.SaveObject = screenSave;
                    }
                }

                foreach (EntityTreeNode entityNode in ElementViewWindow.AllEntities)
                {
                    if (entityNode.EntitySave == null)
                    {
                        EntitySave entitySave = new EntitySave();
                        entitySave.Name = entityNode.Text;
                        entitySave.Tags.Add("GLUE");
                        entitySave.Source = "GLUE";

                        ProjectManager.GlueProjectSave.Entities.Add(entitySave);
                        entityNode.EntitySave = entitySave;
                    }
                }


                UnreferencedFilesManager.Self.RefreshUnreferencedFiles(true);

                MainGlueWindow.Self.Text = "FlatRedBall Glue - " + projectFileName;

                if (shouldSaveGlux)
                {
                    GluxCommands.Self.SaveGlux();
                }

                TaskManager.Self.AddSync(() =>
                {
                    // Someone may have unloaded the project while it was starting up
                    if (GlueState.Self.CurrentGlueProject != null)
                    {
                        GlueCommands.Self.ProjectCommands.SaveProjects();
                    }
                }, "Save all projects after initial load");

                FileWatchManager.PerformFlushing = true;
                FileWatchManager.FlushAndClearIgnores();
            }
            if (closeInitWindow)
            {
                mCurrentInitWindow.Close();
            }


            Section.EndContextAndTime();

            TaskManager.Self.IsTaskProcessingEnabled = true;

            // If we ever want to make things go faster, turn this back on and let's see what's going on.
            //topSection.Save("Sections.xml");
        }
예제 #10
0
        public void SetResetVariablesForEntitySave(EntitySave entitySave)
        {
            // set reset variables
            bool hasNamedObjectEntities = false;

            List <NamedObjectSave> skippedNoses = new List <NamedObjectSave>();

            #region Loop through the NamedObjects to identify which variables should be added
            foreach (NamedObjectSave nos in entitySave.NamedObjects)
            {
                hasNamedObjectEntities |= AddResetVariablesFor(skippedNoses, nos);
            }

            // let's make sure to get all the NOS's that are defined in base types too:
            foreach (var element in entitySave.GetAllBaseEntities())
            {
                foreach (NamedObjectSave nos in element.NamedObjects)
                {
                    if (!nos.DefinedByBase && !nos.SetByDerived)
                    {
                        hasNamedObjectEntities |= AddResetVariablesFor(skippedNoses, nos);
                    }
                }
            }

            if (skippedNoses.Count != 0)
            {
                string message = "Couldn't add reset variables for the following objects.  This may cause pooling to behave improperly for these objects:";

                foreach (NamedObjectSave skipped in skippedNoses)
                {
                    message += "\n " + skipped.InstanceName;
                }

                MessageBox.Show(message);
            }
            #endregion

            #region See if there are any variables to add

            bool areAnyVariablesBeingAdded = false;

            foreach (KeyValuePair <NamedObjectSave, List <string> > kvp in mResetVariablesToAdd)
            {
                NamedObjectSave nos       = kvp.Key;
                List <string>   variables = kvp.Value;

                // reverse loop here because we're removing from the list
                for (int i = variables.Count - 1; i > -1; i--)
                {
                    string variable = variables[i];

                    if (nos.VariablesToReset.Contains(variable))
                    {
                        variables.Remove(variable);
                    }
                    else
                    {
                        areAnyVariablesBeingAdded = true;
                    }
                }
            }
            #endregion

            #region If there are any variables, ask the user if resetting should be added

            if (areAnyVariablesBeingAdded)
            {
                DialogResult result = MessageBox.Show("Glue will add some best-guess variables to be reset " +
                                                      "to the objects in your Entity.  Existing variables will be preserved.  You may " +
                                                      "need to manually add additional variables depending on the logic contained in your Entity." +
                                                      "\n\nAdd variables?", "Add Variables for " + entitySave.Name + "?", MessageBoxButtons.YesNo);

                if (result == DialogResult.Yes)
                {
                    foreach (KeyValuePair <NamedObjectSave, List <string> > kvp in mResetVariablesToAdd)
                    {
                        NamedObjectSave nos       = kvp.Key;
                        List <string>   variables = kvp.Value;

                        foreach (string s in variables)
                        {
                            Plugins.PluginManager.ReceiveOutput("Added reset variable " + s + " in object " + nos);
                        }


                        nos.VariablesToReset.AddRange(variables);
                    }
                }

                GluxCommands.Self.SaveGlux();

                ElementViewWindow.GenerateSelectedElementCode();
            }
            else
            {
                Plugins.PluginManager.ReceiveOutput("No reset variables added to " + entitySave);
            }

            #endregion

            #region As the user if Glue should reset variables for all NamedObjects which are Entities

            if (hasNamedObjectEntities)
            {
                DialogResult result = MessageBox.Show(
                    "Would you like to set reset variables for all contained objects which reference Entities inside " + entitySave.Name + "?  This " +
                    "action is recommended.", "Reset objects referencing Entities?", MessageBoxButtons.YesNo);

                if (result == DialogResult.Yes)
                {
                    foreach (NamedObjectSave nos in entitySave.NamedObjects)
                    {
                        if (nos.SourceType == SourceType.Entity)
                        {
                            EntitySave containedEntitySave = nos.GetReferencedElement() as EntitySave;

                            if (containedEntitySave != null)
                            {
                                SetResetVariablesForEntitySave(containedEntitySave);
                            }
                        }
                    }
                }
            }
            #endregion

            #region Check for inheritance and ask if all derived Entities should have their variables reset too

            List <EntitySave> inheritingEntities = ObjectFinder.Self.GetAllEntitiesThatInheritFrom(entitySave);

            if (inheritingEntities.Count != 0)
            {
                string message =
                    "Would you like to set reset variables for Entities which inherit from " + entitySave.Name + "?  " +
                    "The following Entities will be modified:\n\n";

                foreach (EntitySave inheritingEntity in inheritingEntities)
                {
                    message += inheritingEntity.Name + "\n";
                }

                message += "\nThis " +
                           "action is recommended.";

                DialogResult result = MessageBox.Show(message,
                                                      "Reset Entites inheriting from this?", MessageBoxButtons.YesNo);

                if (result == DialogResult.Yes)
                {
                    foreach (EntitySave inheritingEntity in inheritingEntities)
                    {
                        SetResetVariablesForEntitySave(inheritingEntity);
                    }
                }
            }

            #endregion

            foreach (NamedObjectSave nos in entitySave.NamedObjects)
            {
                StringFunctions.RemoveDuplicates(nos.VariablesToReset);
            }

            CodeWriter.GenerateCode(entitySave);

            foreach (var element in entitySave.GetAllBaseEntities())
            {
                CodeWriter.GenerateCode(element);
            }
            // Not sure we don't save the project here...
            GluxCommands.Self.SaveGlux();
        }
예제 #11
0
        private static EntitySave CreateEntityAndObjects(AddEntityWindow window, string entityName, string directory)
        {
            var gluxCommands = GlueCommands.Self.GluxCommands;

            var newElement = gluxCommands.EntityCommands.AddEntity(
                directory + entityName, is2D: true);

            GlueState.Self.CurrentElement = newElement;

            if (window.SpriteChecked)
            {
                AddObjectViewModel addObjectViewModel = new AddObjectViewModel();
                addObjectViewModel.ObjectName      = "SpriteInstance";
                addObjectViewModel.SourceClassType = "Sprite";
                addObjectViewModel.SourceType      = SourceType.FlatRedBallType;
                gluxCommands.AddNewNamedObjectToSelectedElement(addObjectViewModel);
                GlueState.Self.CurrentElement = newElement;
            }

            if (window.TextChecked)
            {
                AddObjectViewModel addObjectViewModel = new AddObjectViewModel();
                addObjectViewModel.ObjectName      = "TextInstance";
                addObjectViewModel.SourceClassType = "Text";
                addObjectViewModel.SourceType      = SourceType.FlatRedBallType;
                gluxCommands.AddNewNamedObjectToSelectedElement(addObjectViewModel);
                GlueState.Self.CurrentElement = newElement;
            }

            if (window.CircleChecked)
            {
                AddObjectViewModel addObjectViewModel = new AddObjectViewModel();
                addObjectViewModel.ObjectName      = "CircleInstance";
                addObjectViewModel.SourceClassType = "Circle";
                addObjectViewModel.SourceType      = SourceType.FlatRedBallType;
                gluxCommands.AddNewNamedObjectToSelectedElement(addObjectViewModel);
                GlueState.Self.CurrentElement = newElement;
            }

            if (window.AxisAlignedRectangleChecked)
            {
                AddObjectViewModel addObjectViewModel = new AddObjectViewModel();
                addObjectViewModel.ObjectName      = "AxisAlignedRectangleInstance";
                addObjectViewModel.SourceClassType = "AxisAlignedRectangle";
                addObjectViewModel.SourceType      = SourceType.FlatRedBallType;
                gluxCommands.AddNewNamedObjectToSelectedElement(addObjectViewModel);
                GlueState.Self.CurrentElement = newElement;
            }

            // There are a few important things to note about this function:
            // 1. Whenever gluxCommands.AddNewNamedObjectToSelectedElement is called, Glue performs a full
            //    refresh and save. The reason for this is that gluxCommands.AddNewNamedObjectToSelectedElement
            //    is the standard way to add a new named object to an element, and it may be called by other parts
            //    of the code (and plugins) that expect the add to be a complete set of logic (add, refresh, save, etc).
            //    This is less efficient than adding all of them and saving only once, but that would require a second add
            //    method, which would add complexity. For now, we deal with the slower calls because it's not really noticeable.
            // 2. Some actions, like adding Points to a polygon, are done after the polygon is created and added, and that requires
            //    an additional save. Therefore, we do one last save/refresh at the end of this method in certain situations.
            //    Again, this is less efficient than if we performed just a single call, but a single call would be more complicated.
            //    because we'd have to suppress all the other calls.
            bool needsRefreshAndSave = false;

            if (window.PolygonChecked)
            {
                AddObjectViewModel addObjectViewModel = new AddObjectViewModel();
                addObjectViewModel.ObjectName      = "PolygonInstance";
                addObjectViewModel.SourceClassType = "Polygon";
                addObjectViewModel.SourceType      = SourceType.FlatRedBallType;

                var nos = gluxCommands.AddNewNamedObjectToSelectedElement(addObjectViewModel);
                CustomVariableInNamedObject instructions = null;
                instructions = nos.GetCustomVariable("Points");
                if (instructions == null)
                {
                    instructions        = new CustomVariableInNamedObject();
                    instructions.Member = "Points";
                    nos.InstructionSaves.Add(instructions);
                }
                var points = new List <Vector2>();
                points.Add(new Vector2(-16, 16));
                points.Add(new Vector2(16, 16));
                points.Add(new Vector2(16, -16));
                points.Add(new Vector2(-16, -16));
                points.Add(new Vector2(-16, 16));
                instructions.Value = points;


                needsRefreshAndSave = true;

                GlueState.Self.CurrentElement = newElement;
            }

            if (window.IVisibleChecked)
            {
                newElement.ImplementsIVisible = true;
                needsRefreshAndSave           = true;
            }

            if (window.IClickableChecked)
            {
                newElement.ImplementsIClickable = true;
                needsRefreshAndSave             = true;
            }

            if (window.IWindowChecked)
            {
                newElement.ImplementsIWindow = true;
                needsRefreshAndSave          = true;
            }

            if (window.ICollidableChecked)
            {
                newElement.ImplementsICollidable = true;
                needsRefreshAndSave = true;
            }

            if (needsRefreshAndSave)
            {
                MainGlueWindow.Self.PropertyGrid.Refresh();
                ElementViewWindow.GenerateSelectedElementCode();
                GluxCommands.Self.SaveGluxTask();
            }

            return(newElement);
        }
예제 #12
0
        private static void HandleAddVariableOk(AddVariableWindow addVariableWindow)
        {
            string   resultName     = addVariableWindow.ResultName;
            IElement currentElement = EditorLogic.CurrentElement;
            string   failureMessage;

            bool didFailureOccur = IsVariableInvalid(addVariableWindow, resultName, currentElement, out failureMessage);


            if (!didFailureOccur)
            {
                if (!string.IsNullOrEmpty(addVariableWindow.TunnelingObject) && string.IsNullOrEmpty(addVariableWindow.TunnelingVariable))
                {
                    didFailureOccur = true;
                    failureMessage  = $"You must select a variable on {addVariableWindow.TunnelingObject}";
                }
            }

            if (didFailureOccur)
            {
                MessageBox.Show(failureMessage);
            }
            else
            {
                // See if there is already a variable in the base with this name
                CustomVariable existingVariableInBase = EditorLogic.CurrentElement.GetCustomVariableRecursively(resultName);

                bool canCreate       = true;
                bool isDefinedByBase = false;
                if (existingVariableInBase != null)
                {
                    if (existingVariableInBase.SetByDerived)
                    {
                        isDefinedByBase = true;
                    }
                    else
                    {
                        MessageBox.Show("There is already a variable named\n\n" + resultName +
                                        "\n\nin the base element, but it is not SetByDerived.\nGlue will not " +
                                        "create a variable because it would result in a name conflict.");

                        canCreate = false;
                    }
                }

                if (canCreate)
                {
                    string type                 = addVariableWindow.ResultType;
                    string sourceObject         = addVariableWindow.TunnelingObject;
                    string sourceObjectProperty = null;
                    if (!string.IsNullOrEmpty(sourceObject))
                    {
                        sourceObjectProperty = addVariableWindow.TunnelingVariable;
                    }
                    string overridingType = addVariableWindow.OverridingType;
                    string typeConverter  = addVariableWindow.TypeConverter;

                    CustomVariable newVariable = new CustomVariable();
                    newVariable.Name                 = resultName;
                    newVariable.Type                 = type;
                    newVariable.SourceObject         = sourceObject;
                    newVariable.SourceObjectProperty = sourceObjectProperty;

                    newVariable.IsShared = addVariableWindow.IsStatic;



                    if (!string.IsNullOrEmpty(overridingType))
                    {
                        newVariable.OverridingPropertyType = overridingType;
                        newVariable.TypeConverter          = typeConverter;
                    }


                    RightClickHelper.CreateAndAddNewVariable(newVariable);

                    if (isDefinedByBase)
                    {
                        newVariable.DefinedByBase = isDefinedByBase;
                        // Refresh the UI - it's refreshed above in CreateAndAddNewVariable,
                        // but we're changing the DefinedByBase property which changes the color
                        // of the variable so refresh it again
                        EditorLogic.CurrentElementTreeNode.UpdateReferencedTreeNodes();
                    }
                    ElementViewWindow.ShowAllElementVariablesInPropertyGrid();


                    if (GlueState.Self.CurrentElement != null)
                    {
                        PluginManager.ReactToItemSelect(GlueState.Self.CurrentTreeNode);
                    }
                }
            }
        }
예제 #13
0
        public TreeNode MoveEntityOn(EntityTreeNode treeNodeMoving, TreeNode targetNode)
        {
            TreeNode newTreeNode = null;

            #region Moving the Entity into (or out of) a directory
            if (targetNode.IsDirectoryNode() || targetNode.IsRootEntityNode())
            {
                MoveEntityToDirectory(treeNodeMoving, targetNode);
            }

            #endregion

            #region Moving an Entity onto another element to create an instance

            else if (targetNode.IsEntityNode() || targetNode.IsScreenNode() || targetNode.IsRootNamedObjectNode())
            {
                bool isValidDrop = true;
                // Make sure that we don't drop an Entity into its own Objects
                if (targetNode.IsRootNamedObjectNode())
                {
                    if (treeNodeMoving == targetNode.GetContainingElementTreeNode())
                    {
                        isValidDrop = false;
                    }
                }
                if (isValidDrop)
                {
                    newTreeNode = MoveEntityOntoElement(treeNodeMoving, targetNode, newTreeNode);
                }
            }

            #endregion

            #region Moving an Entity onto a NamedObject (currently supports only Lists)

            else if (targetNode.IsNamedObjectNode())
            {
                // Allow drop only if it's a list or Layer
                NamedObjectSave targetNamedObjectSave = targetNode.Tag as NamedObjectSave;

                if (!targetNamedObjectSave.IsList && !targetNamedObjectSave.IsLayer)
                {
                    MessageBox.Show("The target is not a List or Layer so we can't add an Object to it.", "Target not valid");
                }
                if (targetNamedObjectSave.IsLayer)
                {
                    TreeNode parent = targetNode.Parent;

                    newTreeNode = MoveEntityOn(treeNodeMoving, parent);

                    // this created a new NamedObjectSave.  Let's put that on the Layer
                    DragDropManager.Self.MoveNamedObject(newTreeNode, targetNode);
                }
                else
                {
                    // Make sure that the two types match
                    string listType = targetNamedObjectSave.SourceClassGenericType;

                    bool isOfTypeOrInherits =
                        listType == treeNodeMoving.EntitySave.Name ||
                        treeNodeMoving.EntitySave.InheritsFrom(listType);

                    if (isOfTypeOrInherits == false)
                    {
                        MessageBox.Show("The target list type is of type\n\n" +
                                        listType +
                                        "\n\nBut the Entity is of type\n\n" +
                                        treeNodeMoving.EntitySave.Name +
                                        "\n\nCould not add an instance to the list", "Could not add instance");
                    }
                    else
                    {
                        NamedObjectSave namedObject = new NamedObjectSave();
                        namedObject.InstanceName =
                            FileManager.RemovePath(treeNodeMoving.EntitySave.Name) + "1";

                        StringFunctions.MakeNameUnique <NamedObjectSave>(
                            namedObject, targetNamedObjectSave.ContainedObjects);

                        // Not sure if we need to set this or not, but I think
                        // any instance added to a list will not be defined by base
                        namedObject.DefinedByBase = false;

                        NamedObjectSaveExtensionMethodsGlue.AddNamedObjectToCurrentNamedObjectList(namedObject);

                        ElementViewWindow.GenerateSelectedElementCode();
                        // Don't save the Glux, the caller of this method will take care of it
                        // GluxCommands.Self.SaveGlux();
                    }
                }
            }

            #endregion

            else if (targetNode.IsGlobalContentContainerNode())
            {
                AskAndAddAllContainedRfsToGlobalContent(treeNodeMoving.SaveObject);
            }

            return(newTreeNode);
        }
예제 #14
0
        public void MoveNamedObject(TreeNode treeNodeMoving, TreeNode targetNode)
        {
            if (targetNode != null)
            {
                NamedObjectSave targetNos = targetNode.Tag as NamedObjectSave;
                NamedObjectSave movingNos = treeNodeMoving.Tag as NamedObjectSave;

                bool succeeded = false;
                if (targetNode == null)
                {
                    // Didn't move on to anything
                }
                else if (targetNode.IsRootNamedObjectNode())
                {
                    succeeded = MoveObjectOnObjectsRoot(treeNodeMoving, targetNode, movingNos, succeeded);
                }
                else if (targetNode.IsRootCustomVariablesNode())
                {
                    MoveObjectOnRootCustomVariablesNode(treeNodeMoving, targetNode);
                }
                else if (targetNode.Tag is IElement)
                {
                    succeeded = DragDropNosIntoElement(movingNos, targetNode.Tag as IElement);
                }
                else if (targetNode.IsRootEventsNode())
                {
                    succeeded = DragDropNosOnRootEventsNode(treeNodeMoving, targetNode);
                }
                else if (targetNos != null && targetNos.SourceType == SourceType.FlatRedBallType)
                {
                    string targetClassType = targetNos.SourceClassType;

                    #region Failure cases

                    if (string.IsNullOrEmpty(targetClassType))
                    {
                        MessageBox.Show("The target Object does not have a defined type.  This operation is not valid");
                    }

                    #endregion

                    else if (targetClassType == "Layer")
                    {
                        // Only allow this if the NOS's are on the same object
                        if (ObjectFinder.Self.GetElementContaining(movingNos) ==
                            ObjectFinder.Self.GetElementContaining(targetNos))
                        {
                            succeeded         = true;
                            movingNos.LayerOn = targetNos.InstanceName;
                            MainGlueWindow.Self.PropertyGrid.Refresh();
                        }
                    }

                    else if (targetClassType == "ShapeCollection")
                    {
                        succeeded = HandleDropOnShapeCollection(treeNodeMoving, targetNode, targetNos, movingNos);
                    }

                    else if (targetClassType == "PositionedObjectList<T>")
                    {
                        succeeded = HandleDropOnList(treeNodeMoving, targetNode, targetNos, movingNos);
                    }
                }
                else
                {
                    MessageBox.Show("Invalid movement");
                }


                if (succeeded)
                {
                    if (EditorLogic.CurrentElement != null)
                    {
                        ElementViewWindow.GenerateSelectedElementCode();
                    }
                    else
                    {
                        GlobalContentCodeGenerator.UpdateLoadGlobalContentCode();
                    }
                    ProjectManager.SaveProjects();
                    GluxCommands.Self.SaveGlux();
                }
            }
        }
예제 #15
0
        public void ReactToPropertyChanged(string variableNameAsDisplayed, object oldValue, string variableName, string parentGridItemName)
        {
            var mPropertyGrid = MainGlueWindow.Self.PropertyGrid;


            bool updateTreeView = true;

            #region EventResponseSave
            if (EditorLogic.CurrentEventResponseSave != null)
            {
                Container.Get <EventResponseSaveSetVariableLogic>().ReactToChange(
                    variableNameAsDisplayed, oldValue, GlueState.Self.CurrentEventResponseSave, GlueState.Self.CurrentElement);
            }

            #endregion

            #region State

            else if (EditorLogic.CurrentStateSave != null)
            {
                Container.Get <StateSaveSetVariableLogic>().ReactToStateSaveChangedValue(
                    EditorLogic.CurrentStateSave, EditorLogic.CurrentStateSaveCategory, variableNameAsDisplayed, oldValue,
                    GlueState.Self.CurrentElement, ref updateTreeView);
            }

            #endregion

            #region StateCategory

            else if (EditorLogic.CurrentStateSaveCategory != null)
            {
                Container.Get <StateSaveCategorySetVariableLogic>().ReactToStateSaveCategoryChangedValue(
                    EditorLogic.CurrentStateSaveCategory, variableNameAsDisplayed, oldValue,
                    GlueState.Self.CurrentElement, ref updateTreeView);
            }

            #endregion

            #region NamedObject

            else if (EditorLogic.CurrentNamedObject != null)
            {
                Container.Get <NamedObjectSetVariableLogic>().ReactToNamedObjectChangedValue(
                    variableNameAsDisplayed, parentGridItemName, oldValue);
            }

            #endregion

            #region ReferencedFile

            else if (EditorLogic.CurrentReferencedFile != null)
            {
                Container.Get <ReferencedFileSaveSetVariableLogic>().ReactToChangedReferencedFile(
                    variableNameAsDisplayed, oldValue, ref updateTreeView);
            }

            #endregion

            #region CustomVariable

            else if (EditorLogic.CurrentCustomVariable != null)
            {
                Container.Get <CustomVariableSaveSetVariableLogic>().ReactToCustomVariableChangedValue(
                    variableNameAsDisplayed, EditorLogic.CurrentCustomVariable, oldValue);
            }
            else if (mPropertyGrid.SelectedObject != null && mPropertyGrid.SelectedObject is PropertyGridDisplayer &&
                     GlueState.Self.CurrentElement != null && GlueState.Self.CurrentElement.GetCustomVariableRecursively(variableName) != null)
            {
                Container.Get <CustomVariableSaveSetVariableLogic>().ReactToCustomVariableChangedValue(
                    variableName, GlueState.Self.CurrentElement.GetCustomVariableRecursively(variableName), oldValue);
            }
            #endregion

            // Check Entities and Screens after checking variables and objects
            #region Entity
            else if (EditorLogic.CurrentEntitySave != null)
            {
                Container.Get <EntitySaveSetVariableLogic>().ReactToEntityChangedValue(variableNameAsDisplayed, oldValue);
            }

            #endregion

            #region ScreenSave

            else if (EditorLogic.CurrentScreenSave != null)
            {
                Container.Get <ScreenSaveSetVariableLogic>().ReactToScreenChangedValue(variableNameAsDisplayed, oldValue);
            }

            #endregion

            #region Global content container node

            else if (EditorLogic.CurrentTreeNode.Root().IsGlobalContentContainerNode())
            {
                Container.Get <GlobalContentSetVariableLogic>().ReactToGlobalContentChangedValue(
                    variableNameAsDisplayed, oldValue, ref updateTreeView);
            }

            #endregion


            PluginManager.ReactToChangedProperty(variableNameAsDisplayed, oldValue);

            if (GlueState.Self.CurrentElement != null)
            {
                GlueCommands.Self.GenerateCodeCommands
                .GenerateElementAndReferencedObjectCodeTask(GlueState.Self.CurrentElement);
            }
            else if (EditorLogic.CurrentReferencedFile != null)
            {
                GlobalContentCodeGenerator.UpdateLoadGlobalContentCode();
            }

            // UpdateCurrentObjectReferencedTreeNodes
            // kicks off a save by default.  Therefore
            // we don't need to call SaveProjects if UpdateCurrentObjectReferencedTreeNodes
            // is called.
            if (updateTreeView)
            {
                ElementViewWindow.UpdateCurrentObjectReferencedTreeNodes();
            }
            else
            {
                TaskManager.Self.AddSync(ProjectManager.SaveProjects, "Saving due to variable change");
            }

            mPropertyGrid.Refresh();

            GluxCommands.Self.SaveGlux();

            // Vic says:  This was intented to refresh the variables at one point
            // but this is a messy feature.  I think we should just refresh the entire
            // glux whenever a change is made now that it's async
            //RemotingManager.RefreshVariables(false);
        }