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(); // 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 static bool UpdateFile(string changedFile) { bool shouldSave = false; bool handled = false; lock (mUpdateFileLock) { if (ProjectManager.ProjectBase != null) { 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) { GlueCommands.Self.PrintError("Error saving Class from CSV " + rfs.Name + "\n" + e.ToString()); } } } #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 |= GlueCommands.Self.ProjectCommands.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 |= GlueCommands.Self.ProjectCommands.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 { try { // It's a directory, so let's just rebuild our directory TreeNodes ElementViewWindow.AddDirectoryNodes(); } catch (System.IO.IOException) { // this could be because something else is accessing the directory, so sleep, try again System.Threading.Thread.Sleep(100); 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); }
public void RefreshDirectoryTreeNodes() { ElementViewWindow.AddDirectoryNodes(); }
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"); }