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"); }
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); }
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; } }
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(); } }
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(); }
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(); }
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); }
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(); }
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"); }
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(); }
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); }
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); } } } }
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); }
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(); } } }
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); }