public ValidationResponse AddNewCustomClass(string className, out CustomClassSave customClassSave) { ValidationResponse validationResponse = new ValidationResponse(); customClassSave = null; string whyIsntValid; if (!NameVerifier.IsCustomClassNameValid(className, out whyIsntValid)) { validationResponse.OperationResult = OperationResult.Failure; validationResponse.Message = whyIsntValid; } else if (ProjectManager.GlueProjectSave.GetCustomClass(className) != null) { validationResponse.OperationResult = OperationResult.Failure; validationResponse.Message = $"The custom class {className} already exists"; } else { validationResponse.OperationResult = OperationResult.Success; customClassSave = new CustomClassSave(); customClassSave.Name = className; ProjectManager.GlueProjectSave.CustomClasses.Add(customClassSave); GlueCommands.Self.GluxCommands.SaveGlux(); GlueCommands.Self.GenerateCodeCommands.GenerateCustomClassesCode(); } return(validationResponse); }
private void UpdateTreeView(bool refreshClasses) { if (refreshClasses) { TreeView.Nodes.Clear(); } for (int i = 0; i < ProjectManager.GlueProjectSave.CustomClasses.Count; i++) { CustomClassSave ccs = ProjectManager.GlueProjectSave.CustomClasses[i]; TreeNode treeNode = null; if (refreshClasses) { treeNode = new TreeNode(ccs.Name); treeNode.Tag = ccs; TreeView.Nodes.Add(treeNode); } else { treeNode = TreeView.Nodes[i]; treeNode.Nodes.Clear(); } foreach (string fileUsingCustomClass in ccs.CsvFilesUsingThis) { treeNode.Nodes.Add(fileUsingCustomClass); } } }
private static void GenerateCustomClass(CustomClassSave customClass) { if (customClass.GenerateCode) { string fileName = ""; ICodeBlock codeBlock = new CodeDocument(); List <TypedMemberBase> members; Dictionary <string, string> untypedMembers; ReferencedFileSave rfs = null; if (customClass.CsvFilesUsingThis.Count != 0) { rfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(customClass.CsvFilesUsingThis[0]); } if (rfs != null) { // let's just use the existing code flow, even though it's less efficient: GenerateAndSaveDataClass(rfs, rfs.CsvDelimiter); } else { fileName = GetClassInfo(fileName, null, customClass, out members, out untypedMembers); bool succeeded = GenerateClassFromMembers(rfs, true, customClass.Name, members, untypedMembers); } } //return fileName; }
private static string GetClassInfoFromCsvs(ReferencedFileSave rfs, string fileName, RuntimeCsvRepresentation rcr, out string className, out List <TypedMemberBase> members, out Dictionary <string, string> untypedMembers) { className = rfs.GetUnqualifiedTypeForCsv(); CustomClassSave customClass = GetCustomClassForCsv(rfs.Name); fileName = GetClassInfo(fileName, rcr, customClass, out members, out untypedMembers); return(fileName); }
public CsvAndCustomClassSameName(ReferencedFileSave rfs, CustomClassSave customClass) { File = rfs; CustomClass = customClass; Details = $"The file {rfs} has the same name as the custom class " + $"{customClass}, but the file does not use the custom class. " + $"This can result in codegen errors."; }
public void HandleUseThisClassClick(CustomClassSave classToUse) { ReferencedFileSave currentReferencedFile = EditorLogic.CurrentReferencedFile; if (EditorLogic.CurrentReferencedFile != null) { if (classToUse != null) { CustomClassController.Self.SetCsvRfsToUseCustomClass(currentReferencedFile, classToUse, force: false); } } }
bool TryAdd(string memberName, string type, object defaultValue, CustomClassSave tileMapInfoClass) { bool shouldAdd = tileMapInfoClass.RequiredProperties.Any(item => item.Member == memberName) == false; if (shouldAdd) { InstructionSave instruction = new InstructionSave(); instruction.Member = memberName; instruction.Type = type; instruction.Value = null; tileMapInfoClass.RequiredProperties.Add(instruction); } return(shouldAdd); }
public void AddAndModifyTileMapInfoClass() { var glux = GlueState.Self.CurrentGlueProject; CustomClassSave tileMapInfoClass = glux.CustomClasses.FirstOrDefault(item => item.Name == "TileMapInfo"); bool wasAnythingAdded = false; if (tileMapInfoClass == null) { tileMapInfoClass = new CustomClassSave(); tileMapInfoClass.Name = "TileMapInfo"; glux.CustomClasses.Add(tileMapInfoClass); wasAnythingAdded = true; } if (TryAdd(TilesetController.HasCollisionVariableName, "bool", false, tileMapInfoClass)) { wasAnythingAdded = true; } if (TryAdd(TilesetController.EntityToCreatePropertyName, "string", null, tileMapInfoClass)) { wasAnythingAdded = true; } if (TryAdd("Name", "string", null, tileMapInfoClass)) { wasAnythingAdded = true; } if (TryAdd("EmbeddedAnimation", "System.Collections.Generic.List<FlatRedBall.Content.AnimationChain.AnimationFrameSaveBase>", null, tileMapInfoClass)) { wasAnythingAdded = true; } if (wasAnythingAdded) { // Let's generate this asap: GlueCommands.Self.GenerateCodeCommands.GenerateCustomClassesCode(); GlueCommands.Self.GluxCommands.SaveGlux(); GlueCommands.Self.ProjectCommands.SaveProjects(); } }
public void PopulateWithReferencesTo(ReferencedFileSave rfs) { List <IElement> elements = ObjectFinder.Self.GetAllElementsReferencingFile(rfs.Name); foreach (IElement element in elements) { var rfsInThisElement = element.GetReferencedFileSave(rfs.Name); listBox1.Items.Add(rfsInThisElement); foreach (var namedObject in element.AllNamedObjects) { if (namedObject.SourceType == SourceType.File && namedObject.SourceFile == rfsInThisElement.Name) { listBox1.Items.Add(namedObject); } } } // If this is a CSV, then loop through all of the variables and see if any of them use this type if (rfs.IsCsvOrTreatedAsCsv) { string className = rfs.Name; CustomClassSave customClass = ObjectFinder.Self.GlueProject.GetCustomClassReferencingFile(rfs.Name); if (customClass != null) { className = customClass.Name; } foreach (IElement element in ObjectFinder.Self.GlueProject.Screens) { foreach (CustomVariable customVariable in element.CustomVariables.Where(customVariable => customVariable.Type == className)) { listBox1.Items.Add(customVariable); } } foreach (IElement element in ObjectFinder.Self.GlueProject.Entities) { foreach (CustomVariable customVariable in element.CustomVariables.Where(customVariable => customVariable.Type == className)) { listBox1.Items.Add(customVariable); } } } }
public bool SetCsvRfsToUseCustomClass(ReferencedFileSave currentReferencedFile, CustomClassSave classToUse, bool force) { bool succeeded = false; if (classToUse != null) { succeeded = SetRfsToUseNonNullClass(currentReferencedFile, classToUse, force); } else { CustomClassSave oldCustomClass = null; DialogResult result = DialogResult.Yes; if (currentReferencedFile != null) { oldCustomClass = GetCustomClassSaveIncludingThis(currentReferencedFile.Name); result = System.Windows.Forms.MessageBox.Show("Make the " + currentReferencedFile.Name + " file no longer use the " + oldCustomClass.Name + " class?", "Remove Custom Class Association", MessageBoxButtons.YesNo); } if (result == System.Windows.Forms.DialogResult.Yes) { if (currentReferencedFile == null) { MessageBox.Show("You've just encountered a Glue error that someone needs to fix. Error details: " + "Attempting to remove a ReferencedFileSave from a CustomClass, but the RFS doesn't actually exist"); } else { oldCustomClass.CsvFilesUsingThis.Remove(currentReferencedFile.Name); GluxCommands.Self.SaveGlux(); succeeded = true; } } } return(succeeded); }
public static bool IsError(ReferencedFileSave file, CustomClassSave customClass) { var glueProject = GlueState.Self.CurrentGlueProject; if (glueProject == null) { return(false); } string className; if (!string.IsNullOrEmpty(customClass.CustomNamespace)) { className = customClass.CustomNamespace + "." + customClass.Name; } else { className = EditorObjects.IoC.Container.Get <IVsProjectState>().DefaultNamespace + ".DataTypes." + customClass.Name; } var areSameName = file.GetTypeForCsvFile() == className; if (areSameName == false) { return(false); } if (ObjectFinder.Self.GetAllReferencedFiles().Contains(file) == false) { return(false); } if (glueProject.CustomClasses.Contains(customClass) == false) { return(false); } if (customClass.CsvFilesUsingThis.Contains(file.Name)) { return(false); } return(true); }
private static void GetClassInfoFromCsv(List <RuntimeCsvRepresentation> rcrsForClass, CustomClassSave customClass, out List <TypedMemberBase> members, out Dictionary <string, string> untypedMembers) { members = new List <TypedMemberBase>(); untypedMembers = new Dictionary <string, string>(); //List<RuntimeCsvRepresentation> rcrsForClass = new List<RuntimeCsvRepresentation>(); List <string> membersAlreadyAdded = new List <string>(); //rcrsForClass.Add(rcr); foreach (RuntimeCsvRepresentation rcr in rcrsForClass) { GetMembersForRcr(members, untypedMembers, membersAlreadyAdded, rcr); } if (customClass != null) { foreach (var item in customClass.RequiredProperties) { string memberName = item.Member; string type = item.Type; TryAddMember(members, untypedMembers, membersAlreadyAdded, memberName, null, type); } } }
private static string GetClassInfo(string fileName, RuntimeCsvRepresentation rcr, CustomClassSave customClass, out List <TypedMemberBase> members, out Dictionary <string, string> untypedMembers) { bool usesCustomClass = customClass != null; List <RuntimeCsvRepresentation> rcrsForClass = new List <RuntimeCsvRepresentation>(); if (usesCustomClass) { foreach (string name in customClass.CsvFilesUsingThis) { ReferencedFileSave foundRfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(name); if (foundRfs == null) { int m = 3; } else { fileName = foundRfs.Name; fileName = ProjectManager.MakeAbsolute(fileName); RuntimeCsvRepresentation runtimeToAdd = null; try { runtimeToAdd = CsvFileManager.CsvDeserializeToRuntime(fileName); } catch (Exception e) { MessageBox.Show("Error trying to parse CSV:\n" + e.ToString()); } if (runtimeToAdd != null) { rcrsForClass.Add(runtimeToAdd); } } } } else if (rcr != null) { rcrsForClass.Add(rcr); } GetClassInfoFromCsv(rcrsForClass, customClass, out members, out untypedMembers); return(fileName); }
private static bool CreateConstsForCsvEntries(ReferencedFileSave initialRfs, List <TypedMemberBase> members, Dictionary <string, string> untypedMembers, ICodeBlock codeBlock) { bool succeeded = true; bool addToOrderedLists = true; CustomClassSave customClass = GetCustomClassForCsv(initialRfs.Name); bool usesCustomClass = customClass != null; List <ReferencedFileSave> rfsesForClass = new List <ReferencedFileSave>(); if (usesCustomClass) { foreach (string name in customClass.CsvFilesUsingThis) { ReferencedFileSave foundRfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(name); if (foundRfs != null) { rfsesForClass.Add(foundRfs); } } } else { rfsesForClass.Add(initialRfs); } foreach (ReferencedFileSave rfs in rfsesForClass) { if (rfs.CreatesDictionary) { string fileName = rfs.Name; fileName = ProjectManager.MakeAbsolute(fileName); var rcr = CsvFileManager.CsvDeserializeToRuntime(fileName); rcr.RemoveHeaderWhitespaceAndDetermineIfRequired(); int requiredIndex = rcr.GetRequiredIndex(); if (requiredIndex == -1) { succeeded = false; GlueGui.ShowMessageBox("The file " + rfs.Name + " is marked as a dictionary but has no column marked as required"); } else { string type = GetRequiredKeyType(rcr, members, untypedMembers, requiredIndex); FillCodeBlockWithKeys(codeBlock, type, rcr); // The first entry will be the "primary" one? if (addToOrderedLists) { FillOrderedListWithKeys(codeBlock, type, rcr); addToOrderedLists = false; } } } } return(succeeded); }
private static bool UsesAlterntaiveClass(ReferencedFileSave rfs) { CustomClassSave ccs = ObjectFinder.Self.GlueProject.GetCustomClassReferencingFile(rfs.Name); return(ccs != null); }
private static bool CreateConstsForCsvEntries(ReferencedFileSave initialRfs, List <TypedMemberBase> members, Dictionary <string, string> untypedMembers, ICodeBlock codeBlock) { bool succeeded = true; bool addToOrderedLists = true; CustomClassSave customClass = GetCustomClassForCsv(initialRfs.Name); bool usesCustomClass = customClass != null; List <ReferencedFileSave> rfsesForClass = new List <ReferencedFileSave>(); if (usesCustomClass) { foreach (string name in customClass.CsvFilesUsingThis) { ReferencedFileSave foundRfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(name); // A dupe was added one during a Glue crash, so let's protect against that: if (foundRfs != null && rfsesForClass.Contains(foundRfs) == false) { rfsesForClass.Add(foundRfs); } } } else { rfsesForClass.Add(initialRfs); } Dictionary <ReferencedFileSave, RuntimeCsvRepresentation> representations = new Dictionary <ReferencedFileSave, RuntimeCsvRepresentation>(); List <string> allKeys = new List <string>(); foreach (ReferencedFileSave rfs in rfsesForClass) { if (rfs.CreatesDictionary) { string fileName = rfs.Name; fileName = ProjectManager.MakeAbsolute(fileName); var rcr = CsvFileManager.CsvDeserializeToRuntime(fileName); representations.Add(rfs, rcr); rcr.RemoveHeaderWhitespaceAndDetermineIfRequired(); int requiredIndex = rcr.GetRequiredIndex(); if (requiredIndex == -1) { succeeded = false; GlueGui.ShowMessageBox("The file " + rfs.Name + " is marked as a dictionary but has no column marked as required"); } else { var requiredValues = RequiredColumnValues(rcr); allKeys.AddRange(requiredValues); } } } if (allKeys.Any()) { var distinct = allKeys.Distinct(); var firstRcr = representations.First().Value; int requiredIndex = firstRcr.GetRequiredIndex(); string type = GetRequiredKeyType(firstRcr, members, untypedMembers, requiredIndex); FillCodeBlockWithKeys(codeBlock, type, firstRcr, allKeys.Distinct().ToArray()); // the first rcr defines the ordered keys. Others won't add themselves to this list FillOrderedListWithKeys(codeBlock, type, firstRcr); } return(succeeded); }
private bool SetRfsToUseNonNullClass(ReferencedFileSave currentReferencedFile, CustomClassSave classToUse, bool force) { bool succeeded = false; // See if this file is already using one Custom class, and if so, change it CustomClassSave customClassAlreadyBeingUsed = GetCustomClassSaveIncludingThis( currentReferencedFile.Name); if (customClassAlreadyBeingUsed != null) { // This could fail due to threading issues, so ignore failures: try { customClassAlreadyBeingUsed.CsvFilesUsingThis.Remove(currentReferencedFile.Name); } catch (Exception e) { int m = 3; } succeeded = true; } else { // This guy was using its own class, so let's tell the user and see if it should be removed string file = currentReferencedFile.GetTypeForCsvFile(); // "file" is fully qualified, but we only want the non-qualified if (file.Contains(".")) { int lastDot = file.LastIndexOf('.'); file = file.Substring(lastDot + 1); } file = FlatRedBall.IO.FileManager.RelativeDirectory + "DataTypes/" + file + ".Generated.cs"; if (ProjectManager.ProjectBase.IsFilePartOfProject(file, BuildItemMembershipType.CompileOrContentPipeline)) { DialogResult result; if (force) { result = DialogResult.Yes; } else { result = MessageBox.Show("The CSV\n\n" + currentReferencedFile.Name + "\n\nwas using the file\n\n" + file + "\n\nThis file is no associated with this CSV file. Would you like to remove this file?", "Remove unused file?", MessageBoxButtons.YesNo); } if (result == System.Windows.Forms.DialogResult.Yes) { ProjectManager.ProjectBase.RemoveItem(file); try { FileHelper.DeleteFile(file); } catch { PluginManager.ReceiveError("Could not delete file " + file); // Even though the file couldn't be removed, we're going to succeed - the // old file will remain there, and the CSV will use the new one. } } succeeded = true; } else { succeeded = true; } } classToUse.CsvFilesUsingThis.Add(currentReferencedFile.Name); return(succeeded); }
public static void GenerateAndSaveDataClass(ReferencedFileSave rfs, AvailableDelimiters delimiter) { string fileName = rfs.Name; fileName = ProjectManager.MakeAbsolute(fileName); #region See if the CSV file doesn't exist and warn the user if not if (!System.IO.File.Exists(fileName)) { MessageBox.Show("Could not find the CSV file " + fileName + " when trying to generate a data file"); } #endregion else // CSV exists { #region Save off the old delimiter and switch to using the new one - we need the old one so we can switch back after this function finishes char oldDelimiter = CsvFileManager.Delimiter; CsvFileManager.Delimiter = delimiter.ToChar(); #endregion if (!string.IsNullOrEmpty(rfs.UniformRowType)) { // This simply // checks to make // sure the CSV is // set up right - it // doesn't actually generate // any code because the CSV will // deserialize to an array of primitives. CheckUniformTypeValidity(rfs, fileName, oldDelimiter); } else { RuntimeCsvRepresentation rcr; bool succeeded; DeserializeToRcr(delimiter, fileName, out rcr, out succeeded); if (succeeded) { CsvFileManager.Delimiter = oldDelimiter; string whyIsCsvWrong = GetWhyCsvIsWrong(rcr, rfs.CreatesDictionary, fileName); if (!string.IsNullOrEmpty(whyIsCsvWrong)) { GlueGui.ShowMessageBox(whyIsCsvWrong); succeeded = false; } else { string className; List <TypedMemberBase> members; Dictionary <string, string> untypedMembers; CustomClassSave customClass = GetCustomClassForCsv(rfs.Name); if (customClass == null || customClass.GenerateCode) { fileName = GetClassInfoFromCsvs(rfs, fileName, rcr, out className, out members, out untypedMembers); succeeded = GenerateClassFromMembers(rfs, succeeded, className, members, untypedMembers); } } } } } }