public static void GenerateSelectedElementCode() { if (EditorLogic.CurrentElement != null) { CodeWriter.GenerateCode(EditorLogic.CurrentElement); } else if (EditorLogic.CurrentReferencedFile != null) { ReferencedFileSave rfs = EditorLogic.CurrentReferencedFile; GlobalContentCodeGenerator.UpdateLoadGlobalContentCode(); if (rfs.IsCsvOrTreatedAsCsv) { CsvCodeGenerator.GenerateAndSaveDataClass(EditorLogic.CurrentReferencedFile, rfs.CsvDelimiter); } } // Even though we may have generated a Screen/Entity, we still might want to see if we should update // CSVs: if (EditorLogic.CurrentReferencedFile != null) { ReferencedFileSave rfs = EditorLogic.CurrentReferencedFile; if (rfs.Name.ToLower().EndsWith(".csv")) { CsvCodeGenerator.GenerateAndSaveDataClass(EditorLogic.CurrentReferencedFile, rfs.CsvDelimiter); } } }
public void GenerateCurrentCsvCode() { ReferencedFileSave rfs = GlueState.CurrentReferencedFileSave; if (rfs != null && rfs.IsCsvOrTreatedAsCsv) { CsvCodeGenerator.GenerateAndSaveDataClass(rfs, rfs.CsvDelimiter); } }
public ReferencedFileSave ShowAddNewFileDialog() { ReferencedFileSave rfs = null; NewFileWindow nfw = CreateNewFileWindow(); if (nfw.ShowDialog(MainGlueWindow.Self) == DialogResult.OK) { string name = nfw.ResultName; AssetTypeInfo resultAssetTypeInfo = nfw.ResultAssetTypeInfo; string errorMessage; string directory = null; IElement element = EditorLogic.CurrentElement; if (EditorLogic.CurrentTreeNode.IsDirectoryNode()) { directory = EditorLogic.CurrentTreeNode.GetRelativePath().Replace("/", "\\"); } var option = nfw.GetOptionFor(resultAssetTypeInfo); rfs = GlueProjectSaveExtensionMethods.AddReferencedFileSave( element, directory, name, resultAssetTypeInfo, option, out errorMessage); if (!string.IsNullOrEmpty(errorMessage)) { MessageBox.Show(errorMessage); } else if (rfs != null) { var createdFile = ProjectManager.MakeAbsolute(rfs.GetRelativePath()); if (createdFile.EndsWith(".csv")) { string location = ProjectManager.MakeAbsolute(createdFile); CsvCodeGenerator.GenerateAndSaveDataClass(rfs, AvailableDelimiters.Comma); } ElementViewWindow.UpdateChangedElements(); ElementViewWindow.SelectedNode = GlueState.Self.Find.ReferencedFileSaveTreeNode(rfs); PluginManager.ReactToNewFile(rfs); GluxCommands.Self.SaveGlux(); } } return(rfs); }
private static void AddAutoCompleteFor(List <string> toFill, CustomVariable customVariable) { if (CustomVariableCodeGenerator.IsTypeFromCsv(customVariable)) { string fileName = ProjectManager.MakeAbsolute(customVariable.Type, true); ReferencedFileSave rfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(fileName); if (rfs?.IsCsvOrTreatedAsCsv == true) { toFill.AddRange(CsvCodeGenerator.GetMemberNamesFrom(rfs)); } } }
public static void AdjustDataFilesIfIsCsv(string oldName, ReferencedFileSave rfs) { // We'll remove the old file from the project, delete it, then have the RFS regenerate/add the new one to the project //////////////Early Out/////////////////// if (!rfs.IsCsvOrTreatedAsCsv || UsesAlterntaiveClass(rfs)) { return; } ////////////End Early Out///////////////// RemoveCodeForCsv(rfs, oldName); CsvCodeGenerator.GenerateAndSaveDataClass(rfs, rfs.CsvDelimiter); }
public void TestCsvGeneration() { string nameInCsv = "Name With Spaces and Invalids*~"; string constName = CsvCodeGenerator.GetConstNameForValue(nameInCsv); if (constName.Contains(' ')) { throw new Exception("Const name for CSV is invalid!"); } if (constName.IndexOfAny(NameVerifier.InvalidCharacters) != -1) { throw new Exception("Const name contains invalid characters!"); } Type type = TypeManager.GetTypeFromString("bool"); if (type != typeof(bool)) { throw new Exception("TypeManager is not properly returning type from \"bool\""); } type = TypeManager.GetTypeFromString("System.Boolean"); if (type != typeof(bool)) { throw new Exception("TypeManager is not properly returning type from \"bool\""); } type = TypeManager.GetTypeFromString("Boolean"); if (type != typeof(bool)) { throw new Exception("TypeManager is not properly returning type from \"bool\""); } RuntimeCsvRepresentation rcr = new RuntimeCsvRepresentation(); rcr.Headers = new CsvHeader[2]; rcr.Headers[0].OriginalText = "Variable"; rcr.Headers[1].OriginalText = "Variable (float)"; string why = CsvCodeGenerator.GetWhyCsvIsWrong(rcr, false, null); if (string.IsNullOrEmpty(why)) { throw new Exception("Glue should be reporting errors on CSVs that have duplicate header names (but of different types)"); } }
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(); GlobalContentCodeGenerator.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 SetInitWindowText("Nesting generated items"); GlueCommands.Self.ProjectCommands.MakeGeneratedCodeItemsNested(); 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(); // I think this is handled automatically when regenerating all code... // Yes, down in GenerateAllCodeTask //GlobalContentCodeGenerator.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.GenerateAllCodeTask(); Section.EndContextAndTime(); GlobalContentCodeGenerator.SuppressGlobalContentDictionaryRefresh = false; } }
public ReferencedFileSave CreateReferencedFileSaveForExistingFile(IElement containerForFile, string directoryInsideContainer, string absoluteFileName, PromptHandleEnum unknownTypeHandle, AssetTypeInfo ati, out string creationReport, out string errorMessage) { creationReport = ""; errorMessage = null; ReferencedFileSave referencedFileSaveToReturn = null; string whyItIsntValid; // Let's see if there is already an Entity with the same name string fileWithoutPath = FileManager.RemovePath(FileManager.RemoveExtension(absoluteFileName)); bool isValid = NameVerifier.IsReferencedFileNameValid(fileWithoutPath, ati, referencedFileSaveToReturn, containerForFile, out whyItIsntValid); if (!isValid) { errorMessage = "Invalid file name:\n" + fileWithoutPath + "\n" + whyItIsntValid; } else { Zipper.UnzipAndModifyFileIfZip(ref absoluteFileName); string extension = FileManager.GetExtension(absoluteFileName); bool isValidExtensionOrIsConfirmedByUser; bool isUnknownType; FlatRedBall.Glue.Plugins.ExportedImplementations.CommandInterfaces.ElementCommands.CheckAndWarnAboutUnknownFileTypes(unknownTypeHandle, extension, out isValidExtensionOrIsConfirmedByUser, out isUnknownType); string fileToAdd = null; if (isValidExtensionOrIsConfirmedByUser) { string directoryThatFileShouldBeRelativeTo = FlatRedBall.Glue.Plugins.ExportedImplementations.CommandInterfaces.ElementCommands.GetFullPathContentDirectory(containerForFile, directoryInsideContainer); string projectDirectory = ProjectManager.ContentProject.GetAbsoluteContentFolder(); bool needsToCopy = !FileManager.IsRelativeTo(absoluteFileName, projectDirectory); if (needsToCopy) { fileToAdd = directoryThatFileShouldBeRelativeTo + FileManager.RemovePath(absoluteFileName); fileToAdd = FileManager.MakeRelative(fileToAdd, ProjectManager.ContentProject.GetAbsoluteContentFolder()); try { FileHelper.RecursivelyCopyContentTo(absoluteFileName, FileManager.GetDirectory(absoluteFileName), directoryThatFileShouldBeRelativeTo); } catch (System.IO.FileNotFoundException fnfe) { errorMessage = "Could not copy the files because of a missing file: " + fnfe.Message; } } else { fileToAdd = FlatRedBall.Glue.Plugins.ExportedImplementations.CommandInterfaces.ElementCommands.GetNameOfFileRelativeToContentFolder(absoluteFileName, directoryThatFileShouldBeRelativeTo, projectDirectory); } } if (string.IsNullOrEmpty(errorMessage)) { BuildToolAssociation bta = null; if (ati != null && !string.IsNullOrEmpty(ati.CustomBuildToolName)) { bta = BuildToolAssociationManager.Self.GetBuilderToolAssociationByName(ati.CustomBuildToolName); } if (containerForFile != null) { referencedFileSaveToReturn = containerForFile.AddReferencedFile(fileToAdd, ati, bta); } else { bool useFullPathAsName = false; // todo - support built files here referencedFileSaveToReturn = AddReferencedFileToGlobalContent(fileToAdd, useFullPathAsName); } // This will be null if there was an error above in creating this file if (referencedFileSaveToReturn != null) { if (containerForFile != null) { containerForFile.HasChanged = true; } if (fileToAdd.EndsWith(".csv")) { string fileToAddAbsolute = ProjectManager.MakeAbsolute(fileToAdd); CsvCodeGenerator.GenerateAndSaveDataClass(referencedFileSaveToReturn, referencedFileSaveToReturn.CsvDelimiter); } if (isUnknownType) { referencedFileSaveToReturn.LoadedAtRuntime = false; } string error; referencedFileSaveToReturn.RefreshSourceFileCache(false, out error); if (!string.IsNullOrEmpty(error)) { ErrorReporter.ReportError(referencedFileSaveToReturn.Name, error, false); } } } } return(referencedFileSaveToReturn); }
public void GenerateCustomClassesCode() { CsvCodeGenerator.GenerateAllCustomClasses(GlueState.CurrentGlueProject); }
static void GenerateAllCodeSync(object throwaway) { var glueProject = GlueState.CurrentGlueProject; CameraSetupCodeGenerator.UpdateOrAddCameraSetup(); CameraSetupCodeGenerator.GenerateCallInGame1(ProjectManager.GameClassFileName, true); //Parallel.For(0, layer.data[0].tiles.Count, (count) => GlueCommands.PrintOutput("Starting to generate all Screens"); // make sure the user hasn't exited the program foreach (var screen in glueProject.Screens) { #region Check for exiting the function becuase Glue is closing if (ProjectManager.WantsToClose) { PluginManager.ReceiveOutput("Stopping generation because the project is closing"); return; } #endregion CodeWriter.GenerateCode(screen); } GlueCommands.PrintOutput("Done generating Screens, starting Entities"); // not sure which is faster: // Currently the referenced file dictionary makes this not work well: //Parallel.ForEach(GlueState.Self.CurrentGlueProject.Entities, (entity) => // { // CodeWriter.GenerateCode(entity); // }); // Let's make this thread safe: IEnumerable <EntitySave> entityList = null; lock (glueProject.Entities) { entityList = glueProject.Entities.Where(item => true).ToList(); } foreach (var entity in entityList) { #region Check for exiting the function becuase Glue is closing if (ProjectManager.WantsToClose) { PluginManager.ReceiveOutput("Stopping generation because the project is closing"); return; } #endregion CodeWriter.GenerateCode(entity); } PluginManager.ReceiveOutput("Done generating Entities, starting GlobalContent"); #region Check for exiting the function becuase Glue is closing if (ProjectManager.WantsToClose) { PluginManager.ReceiveOutput("Stopping generation because the project is closing"); return; } #endregion GlobalContentCodeGenerator.UpdateLoadGlobalContentCode(); #region Check for exiting the function becuase Glue is closing if (ProjectManager.WantsToClose) { PluginManager.ReceiveOutput("Stopping generation because the project is closing"); return; } #endregion CsvCodeGenerator.RegenerateAllCsvs(); CsvCodeGenerator.GenerateAllCustomClasses(glueProject); if (glueProject.FileVersion >= (int)GlueProjectSave.GluxVersions.AddedGeneratedGame1) { GlueCommands.GenerateCodeCommands.GenerateGame1(); } GlueCommands.PrintOutput("Done with all generation"); }
internal void ReactToChangedReferencedFile(string changedMember, object oldValue, ref bool updateTreeView) { ReferencedFileSave rfs = GlueState.Self.CurrentReferencedFileSave; #region Opens With if (changedMember == "OpensWith") { if (rfs.OpensWith == "New Application...") { string newApplication = EditorData.FileAssociationSettings.SetApplicationForExtension(null, "New Application..."); if (!string.IsNullOrEmpty(newApplication)) { rfs.OpensWith = newApplication; } else { rfs.OpensWith = "<DEFAULT>"; } } } #endregion #region Name else if (changedMember == "Name") { if ((string)oldValue != rfs.Name && ProjectManager.GlueProjectSave != null) { if ((string)oldValue != null) { RenameReferencedFile((string)oldValue, rfs.Name, rfs, GlueState.Self.CurrentElement); } } } #endregion #region LoadedAtRuntime if (changedMember == "LoadedAtRuntime") { updateTreeView = false; } #endregion #region Loaded only when referenced else if (changedMember == "LoadedOnlyWhenReferenced") { updateTreeView = false; if (rfs.LoadedOnlyWhenReferenced) { // We need to make this public, or else it won't work on WP7 and Silverlight. // Update - The preferred method to get access to this stuff by string is either // GetMember or GetStaticMember, so there's no reason to force this stuff as public // when LoadedWhenReferenced is set to true. //rfs.HasPublicProperty = true; } } #endregion #region Has public property else if (changedMember == "HasPublicProperty") { updateTreeView = false; // GetMember and GetStaticMember // make it so we no longer require // the member to be public. //if (rfs.LoadedOnlyWhenReferenced && !rfs.HasPublicProperty) //{ // System.Windows.Forms.MessageBox.Show("This file must have a public property if it " + // "is \"Loaded Only When Referenced\" so that it can be accessed through reflection " + // "on non-PC platforms."); // rfs.HasPublicProperty = true; //} //if (rfs.ContainerType == ContainerType.None && rfs.HasPublicProperty == false) //{ // System.Windows.Forms.MessageBox.Show("Global content must be public so custom code can access it."); // rfs.HasPublicProperty = true; //} } #endregion #region IsSharedStatic else if (changedMember == "IsSharedStatic") { updateTreeView = false; // If this is made IsSharedStatic, that means that the file will not be added to managers // We should see if any named objects reference this and notify the user List <NamedObjectSave> namedObjects = EditorLogic.CurrentElement.NamedObjects; foreach (NamedObjectSave namedObject in namedObjects) { if (namedObject.SourceType == SourceType.File && namedObject.SourceFile == rfs.Name && namedObject.AddToManagers == false) { DialogResult result = MessageBox.Show("The object " + namedObject.InstanceName + " references this file. " + "Shared files are not added to the engine, but since the object has its AddToManagers also set to false " + "the content in this file will not be added to managers. Would you like to set the object's AddToManagers to " + "true?", "Add to managers?", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { namedObject.AddToManagers = true; } } } } #endregion #region IsDatabaseForLocalizing else if (changedMember == "IsDatabaseForLocalizing") { updateTreeView = false; bool oldValueAsBool = (bool)oldValue; bool newValue = rfs.IsDatabaseForLocalizing; if (newValue) { TaskManager.Self.AddSync(() => RemoveCodeForCsv(rfs), "Removing old CSV"); } else { CsvCodeGenerator.GenerateAndSaveDataClass(rfs, rfs.CsvDelimiter); } // Let's revert the change just to see if // things have changed project-wide, and if // have to tell the user to re-generate all code. rfs.IsDatabaseForLocalizing = oldValueAsBool; ObjectFinder.Self.GlueProject.UpdateIfTranslationIsUsed(); bool oldProjectLocalization = ObjectFinder.Self.GlueProject.UsesTranslation; rfs.IsDatabaseForLocalizing = newValue; ObjectFinder.Self.GlueProject.UpdateIfTranslationIsUsed(); bool newProjectLocalization = ObjectFinder.Self.GlueProject.UsesTranslation; if (oldProjectLocalization != newProjectLocalization) { MessageBox.Show("Because of the change to the \"Is Database For Localizing\" the generated code for the entire project is likely out of date." + "We recommend closing and re-opening the project in Glue to cause a full regeneration.", "Generated code is out of date"); } } #endregion #region UseContentPipeline else if (changedMember == "UseContentPipeline") { ContentPipelineHelper.ReactToUseContentPipelineChange(rfs); // Make sure that // all other RFS's // that use this file // get changed too. List <ReferencedFileSave> matchingRfses = ObjectFinder.Self.GetMatchingReferencedFiles(rfs); foreach (ReferencedFileSave rfsToUpdate in matchingRfses) { rfsToUpdate.UseContentPipeline = rfs.UseContentPipeline; // No need to // call this method // because there's only // one file in the project // even though there's multiple // ReferencedFileSaves, and this // method just modifies the content // project. //ContentPipelineHelper.ReactToUseContentPipelineChange(rfsToUpdate); IElement container = rfsToUpdate.GetContainer(); if (container != null) { CodeWriter.GenerateCode(container); } else { GlueCommands.Self.GenerateCodeCommands.GenerateGlobalContentCode(); } } updateTreeView = false; } #endregion #region TextureFormat else if (changedMember == "TextureFormat") { ContentPipelineHelper.UpdateTextureFormatFor(rfs); // See the UseContentPipeline section for comments on what this // code does. List <ReferencedFileSave> matchingRfses = ObjectFinder.Self.GetMatchingReferencedFiles(rfs); foreach (ReferencedFileSave rfsToUpdate in matchingRfses) { rfsToUpdate.TextureFormat = rfs.TextureFormat; IElement container = rfsToUpdate.GetContainer(); if (container != null) { CodeWriter.GenerateCode(container); } else { GlueCommands.Self.GenerateCodeCommands.GenerateGlobalContentCode(); } } updateTreeView = false; } #endregion #region IncludeDirectoryRelativeToContainer else if (changedMember == "IncludeDirectoryRelativeToContainer") { if (rfs.GetContainerType() == ContainerType.None) { // This RFS // is in GlobalContent // so we need to find all // RFS's that use this RFS // and regenerate them List <IElement> elements = ObjectFinder.Self.GetAllElementsReferencingFile(rfs.Name); foreach (IElement element in elements) { CodeWriter.GenerateCode(element); } } else { } } #endregion #region AdditionalArguments else if (changedMember == "AdditionalArguments") { rfs.PerformExternalBuild(runAsync: true); } #endregion #region CreatesDictionary else if (changedMember == "CreatesDictionary") { // This could change things like the constants added to the code file, so let's generate the code now. GlueCommands.Self.GenerateCodeCommands.GenerateCurrentCsvCode(); } #endregion }
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 ReferencedFileSave CreateReferencedFileSaveForExistingFile(IElement containerForFile, string directoryInsideContainer, string absoluteFileName, PromptHandleEnum unknownTypeHandle, AssetTypeInfo ati, out string creationReport, out string errorMessage) { creationReport = ""; errorMessage = null; ReferencedFileSave referencedFileSaveToReturn = null; string whyItIsntValid; // Let's see if there is already an Entity with the same name string fileWithoutPath = FileManager.RemovePath(FileManager.RemoveExtension(absoluteFileName)); bool isValid = NameVerifier.IsReferencedFileNameValid(fileWithoutPath, ati, referencedFileSaveToReturn, containerForFile, out whyItIsntValid); if (!isValid) { errorMessage = "Invalid file name:\n" + fileWithoutPath + "\n" + whyItIsntValid; } else { Zipper.UnzipAndModifyFileIfZip(ref absoluteFileName); string extension = FileManager.GetExtension(absoluteFileName); bool isValidExtensionOrIsConfirmedByUser; bool isUnknownType; CheckAndWarnAboutUnknownFileTypes(unknownTypeHandle, extension, out isValidExtensionOrIsConfirmedByUser, out isUnknownType); if (isValidExtensionOrIsConfirmedByUser) { string directoryThatFileShouldBeRelativeTo = GetFullPathContentDirectory(containerForFile, directoryInsideContainer); string projectDirectory = ProjectManager.ContentProject.GetAbsoluteContentFolder(); string fileToAdd = GetNameOfFileRelativeToContentFolder(absoluteFileName, directoryThatFileShouldBeRelativeTo, projectDirectory); BuildToolAssociation bta = null; if (ati != null && !string.IsNullOrEmpty(ati.CustomBuildToolName)) { bta = BuildToolAssociationManager.Self.GetBuilderToolAssociationByName(ati.CustomBuildToolName); } if (containerForFile != null) { referencedFileSaveToReturn = containerForFile.AddReferencedFile(fileToAdd, ati, bta); } else { bool useFullPathAsName = false; // todo - support built files here referencedFileSaveToReturn = AddReferencedFileToGlobalContent(fileToAdd, useFullPathAsName); } // This will be null if there was an error above in creating this file if (referencedFileSaveToReturn != null) { if (containerForFile != null) { containerForFile.HasChanged = true; } if (fileToAdd.EndsWith(".csv")) { string fileToAddAbsolute = ProjectManager.MakeAbsolute(fileToAdd); CsvCodeGenerator.GenerateAndSaveDataClass(referencedFileSaveToReturn, referencedFileSaveToReturn.CsvDelimiter); } if (isUnknownType) { referencedFileSaveToReturn.LoadedAtRuntime = false; } ProjectManager.UpdateFileMembershipInProject(referencedFileSaveToReturn); PluginManager.ReactToNewFile(referencedFileSaveToReturn); GluxCommands.Self.SaveGlux(); ProjectManager.SaveProjects(); UnreferencedFilesManager.Self.RefreshUnreferencedFiles(false); string error; referencedFileSaveToReturn.RefreshSourceFileCache(false, out error); if (!string.IsNullOrEmpty(error)) { ErrorReporter.ReportError(referencedFileSaveToReturn.Name, error, false); } } } } return(referencedFileSaveToReturn); }