private static void HandleCreatedByOtherEntitiesSet(EntitySave entitySave) { if (entitySave.CreatedByOtherEntities == true) { FactoryCodeGenerator.AddGeneratedPerformanceTypes(); FactoryCodeGenerator.UpdateFactoryClass(entitySave); ProjectManager.SaveProjects(); } else { FactoryCodeGenerator.RemoveFactory(entitySave); ProjectManager.SaveProjects(); } List<EntitySave> entitiesToRefresh = ObjectFinder.Self.GetAllEntitiesThatInheritFrom(entitySave); entitiesToRefresh.AddRange(entitySave.GetAllBaseEntities()); entitiesToRefresh.Add(entitySave); // We need to re-generate all objects that use this Entity foreach (EntitySave entityToRefresh in entitiesToRefresh) { List<NamedObjectSave> namedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(entityToRefresh.Name); foreach (NamedObjectSave nos in namedObjects) { IElement namedObjectContainer = nos.GetContainer(); if (namedObjectContainer != null) { CodeWriter.GenerateCode(namedObjectContainer); } } } PropertyGridHelper.UpdateDisplayedPropertyGridProperties(); }
internal void ReactToEntityChangedValue(string changedMember, object oldValue) { EntitySave entitySave = EditorLogic.CurrentEntitySave; #region BaseEntity changed if (changedMember == "BaseEntity") { // Not sure why we want to return here. Maybe the user used // to have this set to something but now is undoing it //if (string.IsNullOrEmpty(entitySave.BaseEntity)) //{ // return; //} ReactToChangedBaseEntity(oldValue, entitySave); } #endregion #region CreatedByOtherEntities changed else if (changedMember == "CreatedByOtherEntities") { HandleCreatedByOtherEntitiesSet(entitySave); } #endregion #region PooledByFactory else if (changedMember == nameof(entitySave.PooledByFactory) && (bool)oldValue != entitySave.PooledByFactory) { if (entitySave.PooledByFactory) { // We should ask the user // if Glue should set the reset // variables for all contained objects string message = "Would you like to add reset variables for all contained objects (recommended)"; DialogResult result = MessageBox.Show(message, "Add reset variables?", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { FactoryManager.Self.SetResetVariablesForEntitySave(entitySave); } } else // user set it to false { var hasResetVariables = entitySave.AllNamedObjects.Any(item => item.VariablesToReset?.Any() == true); if(hasResetVariables) { string message = "Would you like to remove reset variables for all contained objects? Select 'Yes' if you added reset variables earlier for pooling"; var dialogResult = MessageBox.Show(message, "Remove reset variables?", MessageBoxButtons.YesNo); if(dialogResult == DialogResult.Yes) { FactoryManager.Self.RemoveResetVariablesForEntitySave(entitySave); } } } FactoryCodeGenerator.AddGeneratedPerformanceTypes(); FactoryCodeGenerator.UpdateFactoryClass(entitySave); } #endregion #region Click Broadcast // Vic says: I don't think we need this anymore else if (changedMember == "ClickBroadcast") { if (string.IsNullOrEmpty((string)oldValue) && !entitySave.ImplementsIClickable ) { // Let the user know that this won't do anything unless the entity implements IClickable string message = "The Click Broadcast message will not be broadcasted unless this " + "Entity is made IClickable. Would you like to make it IClickable?"; DialogResult result = MessageBox.Show(message, "Make IClickable?", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { entitySave.ImplementsIClickable = true; } } } #endregion #region ImplementsIWindow else if (changedMember == "ImplementsIWindow") { if (entitySave.ImplementsIWindow && !entitySave.ImplementsIVisible) { MessageBox.Show("IWindows must also be IVisible. Automatically setting Implements IVisible to true"); entitySave.ImplementsIVisible = true; } RegenerateAllContainersForNamedObjectsThatUseCurrentEntity(); } #endregion #region ImplementsIVisible else if (changedMember == "ImplementsIVisible") { ReactToChangedImplementsIVisible(oldValue, entitySave); } #endregion #region ImplementsIClickable else if (changedMember == "ImplementsIClickable") { RegenerateAllContainersForNamedObjectsThatUseCurrentEntity(); } #endregion #region ItemType else if (changedMember == "ItemType") { EntitySave itemTypeEntity = ObjectFinder.Self.GetEntitySave(entitySave.ItemType); if (itemTypeEntity != null) { if (!itemTypeEntity.CreatedByOtherEntities) { MessageBox.Show("The Entity " + entitySave.ItemType + " must be \"Created By Other Entities\" to be used as an Item Type"); entitySave.ItemType = null; } } } #endregion #region ClassName else if (changedMember == "ClassName") { List<NamedObjectSave> allNamedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseElement(EditorLogic.CurrentElement); List<IElement> containers = new List<IElement>(); foreach (NamedObjectSave nos in allNamedObjects) { IElement element = nos.GetContainer(); if (!containers.Contains(element)) { containers.Add(element); } } foreach (IElement element in containers) { CodeGeneratorIElement.GenerateElement(element); } } #endregion }
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 bool MoveEntityToDirectory(EntitySave entitySave, string newRelativeDirectory) { bool succeeded = true; string targetDirectory = FileManager.RelativeDirectory + newRelativeDirectory; string oldName = entitySave.Name; string newName = newRelativeDirectory.Replace("/", "\\") + entitySave.ClassName; succeeded = MoveEntityCodeFilesToDirectory(entitySave, targetDirectory); if (succeeded) { entitySave.Name = newName; } if (succeeded) { // Do this after changing the name of the Entity so // namespaces come over properly succeeded = UpdateNamespaceOnCodeFiles(entitySave); } if (succeeded) { // 5: Change namespaces string newNamespace = ProjectManager.ProjectNamespace + "." + FileManager.MakeRelative(targetDirectory).Replace("/", "."); newNamespace = newNamespace.Substring(0, newNamespace.Length - 1); string customFileContents = FileManager.FromFileText(FileManager.RelativeDirectory + newName + ".cs"); customFileContents = CodeWriter.ReplaceNamespace(customFileContents, newNamespace); FileManager.SaveText(customFileContents, FileManager.RelativeDirectory + newName + ".cs"); // Generated will automatically have its namespace changed when it is re-generated // 6: Find all objects referending this NamedObjectSave and re-generate the code if (entitySave.CreatedByOtherEntities) { // Vic says: I'm tired. For now just ignore the directory. Fix this when it becomes a problem. FactoryCodeGenerator.UpdateFactoryClass(entitySave); } List <NamedObjectSave> namedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(oldName); // Let's get all the TreeNodes to regenerate. // We want to store them in a list so we only generate // each tree node once. List <BaseElementTreeNode> treeNodesForElementsToRegenerate = new List <BaseElementTreeNode>(); foreach (NamedObjectSave nos in namedObjects) { if (nos.SourceClassGenericType == oldName) { nos.SourceClassGenericType = newName; } if (nos.SourceClassType == oldName) { nos.SourceClassType = newName; } IElement element = nos.GetContainer(); BaseElementTreeNode treeNode = GlueState.Self.Find.ElementTreeNode(element); if (!treeNodesForElementsToRegenerate.Contains(treeNode)) { treeNodesForElementsToRegenerate.Add(treeNode); } } foreach (EntitySave esToTestForInheritance in ProjectManager.GlueProjectSave.Entities) { if (esToTestForInheritance.BaseEntity == oldName) { esToTestForInheritance.BaseEntity = newName; BaseElementTreeNode treeNode = GlueState.Self.Find.EntityTreeNode(esToTestForInheritance); if (!treeNodesForElementsToRegenerate.Contains(treeNode)) { treeNodesForElementsToRegenerate.Add(treeNode); } } } foreach (BaseElementTreeNode treeNode in treeNodesForElementsToRegenerate) { CodeWriter.GenerateCode(treeNode.SaveObject); } } return(succeeded); }
static void Main(string[] args) { string corePath = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName; var doc = XDocument.Load(Path.Combine(corePath, "eep.xml")); var rorgs = doc.Root.Elements(); var rangeRefDictionary = new Dictionary <string, Tuple <long, long> >(); var rorgTypes = new List <Rorg>(); var types = new List <string>(); foreach (var rorg in rorgs) { var number = rorg.Element("number"); var title = rorg.Element("title"); var fullName = rorg.Element("fullname"); var rorgModel = new Rorg(rorg.Element("number").Value.Replace("0x", "")) { Number = number.Value, Title = title.Value, FullName = fullName.Value }; rorgTypes.Add(rorgModel); foreach (var func in rorg.Elements("func")) { var funcNumber = func.Element("number"); var funcTitle = func.Element("title"); var function = new Function(rorgModel, func.Element("number").Value.Replace("0x", "")) { Number = funcNumber.Value, Title = funcTitle.Value }; rorgModel.Functions.Add(function); foreach (var type in func.Elements("type")) { foreach (var c in type.Elements("case")) { var typeNumber = type.Element("number"); var typeTitle = type.Element("title"); var typeModel = new Model.Type(function, type.Element("number").Value.Replace("0x", "")) { Number = typeNumber.Value, Title = typeTitle.Value, OrigTypeNumber = typeNumber.Value }; function.Types.Add(typeModel); var sbNumber = new StringBuilder(); sbNumber.Append(typeModel.Number); sbNumber.Append("_"); sbNumber.Append(function.Types.Count); typeModel.Number = sbNumber.ToString(); types.Add(typeModel.TypeId()); typeModel.TypeIndex = function.Types.Count; foreach (var dataField in c.Elements("datafield")) { var reserved = dataField.Descendants("reserved").Count() == 1; if (reserved) { continue; } var offset = dataField.Element("bitoffs").Value; var size = dataField.Element("bitsize").Value; var shortCut = dataField.Element("shortcut"); var data = dataField.Element("data"); var description = dataField.Element("description"); var unit = dataField.Element("unit"); var range = dataField.Element("range"); var scale = dataField.Element("scale"); var dataFieldModel = new DataField(typeModel) { Offset = Convert.ToInt32(offset), Length = Convert.ToInt32(size), Data = data.Value, Description = description.Value, ShortCut = shortCut.Value.Replace("(", "_").Replace(".", "_").Replace(")", "_").Replace("-", "_").Replace("/", "").Replace(" ", ""), Unit = unit?.Value }; try { if (range != null) { dataFieldModel.Range = new P3.Driver.EepParser.Model.Range();; var minEl = range.Element("min"); var maxEl = range.Element("max"); if (minEl != null && maxEl != null) { long min; long max; min = minEl.Value.Contains("0x") ? long.Parse(minEl.Value.Replace("0x", ""), NumberStyles.HexNumber) : Convert.ToInt64(minEl.Value); max = maxEl.Value.Contains("0x") ? long.Parse(maxEl.Value.Replace("0x", ""), NumberStyles.HexNumber) : Convert.ToInt64(maxEl.Value); if (!rangeRefDictionary.ContainsKey(shortCut.Value)) { rangeRefDictionary.Add(shortCut.Value, new Tuple <long, long>(min, max)); } dataFieldModel.Range.Min = min; dataFieldModel.Range.Max = max; } else { var refEl = range.Element("ref"); dataFieldModel.Range.Ref = refEl.Value; } } if (scale != null) { dataFieldModel.Scale = new Scale(); var minEl = scale.Element("min"); var maxEl = scale.Element("max"); var min = Convert.ToDecimal(minEl.Value, CultureInfo.InvariantCulture); var max = Convert.ToDecimal(maxEl.Value, CultureInfo.InvariantCulture); dataFieldModel.Scale.Min = min; dataFieldModel.Scale.Max = max; } } catch (Exception e) { Console.WriteLine($"Ignore type {e}"); } finally { if (!typeModel.DataFields.ContainsKey(dataFieldModel.ShortCut)) { typeModel.DataFields.Add(dataFieldModel.ShortCut, dataFieldModel); } else { Console.WriteLine($"Ignore datafield {dataFieldModel} already in list"); } } } } } } } var json = new JObject(); var builder = FactoryCodeGenerator.GenerateCode(rorgTypes, rangeRefDictionary, ref json); var tests = FactoryCodeTestGenerator.GenerateTests(rorgTypes, rangeRefDictionary); Console.WriteLine(builder); Console.WriteLine(tests); Console.ReadLine(); }
internal void ReactToEntityChangedValue(string changedMember, object oldValue) { EntitySave entitySave = EditorLogic.CurrentEntitySave; #region BaseEntity changed if (changedMember == "BaseEntity") { // Not sure why we want to return here. Maybe the user used // to have this set to something but now is undoing it //if (string.IsNullOrEmpty(entitySave.BaseEntity)) //{ // return; //} ReactToChangedBaseEntity(oldValue, entitySave); } #endregion #region CreatedByOtherEntities changed else if (changedMember == "CreatedByOtherEntities") { HandleCreatedByOtherEntitiesSet(entitySave); } #endregion #region PooledByFactory else if (changedMember == "PooledByFactory") { if ((bool)oldValue == false && entitySave.PooledByFactory) { // We should ask the user // if Glue should set the reset // variables for all contained objects string message = "Would you like to add reset variables for all contained objects (recommended)"; DialogResult result = MessageBox.Show(message, "Add reset variables?", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { FactoryManager.Self.SetResetVariablesForEntitySave(entitySave); // See if there are any base entities that have objects which are not exposed. // If so, those aren't going to get reset variables, so we need to warn the user // about that. // Actually it seems like glue does actually reset base entity variables, so... // we don't need this //var baseElements = ObjectFinder.Self.GetAllBaseElementsRecursively(entitySave); //string inheritanceErrorMessage = ""; //foreach (var element in baseElements) //{ // foreach (var nos in element.AllNamedObjects.Where(item => item.ExposedInDerived == false)) // { // if (string.IsNullOrEmpty(inheritanceErrorMessage)) // { // inheritanceErrorMessage = "The following Objects have their SetByDerived set to false, so they cannot be properly reset:"; // } // inheritanceErrorMessage += "\n" + nos.ToString(); // } //} } } FactoryCodeGenerator.AddGeneratedPerformanceTypes(); FactoryCodeGenerator.UpdateFactoryClass(entitySave); } #endregion #region Click Broadcast // Vic says: I don't think we need this anymore else if (changedMember == "ClickBroadcast") { if (string.IsNullOrEmpty((string)oldValue) && !entitySave.ImplementsIClickable ) { // Let the user know that this won't do anything unless the entity implements IClickable string message = "The Click Broadcast message will not be broadcasted unless this " + "Entity is made IClickable. Would you like to make it IClickable?"; DialogResult result = MessageBox.Show(message, "Make IClickable?", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { entitySave.ImplementsIClickable = true; } } } #endregion #region ImplementsIWindow else if (changedMember == "ImplementsIWindow") { if (entitySave.ImplementsIWindow && !entitySave.ImplementsIVisible) { MessageBox.Show("IWindows must also be IVisible. Automatically setting Implements IVisible to true"); entitySave.ImplementsIVisible = true; } RegenerateAllContainersForNamedObjectsThatUseCurrentEntity(); } #endregion #region ImplementsIVisible else if (changedMember == "ImplementsIVisible") { ReactToChangedImplementsIVisible(oldValue, entitySave); } #endregion #region ImplementsIClickable else if (changedMember == "ImplementsIClickable") { RegenerateAllContainersForNamedObjectsThatUseCurrentEntity(); } #endregion #region ItemType else if (changedMember == "ItemType") { EntitySave itemTypeEntity = ObjectFinder.Self.GetEntitySave(entitySave.ItemType); if (itemTypeEntity != null) { if (!itemTypeEntity.CreatedByOtherEntities) { MessageBox.Show("The Entity " + entitySave.ItemType + " must be \"Created By Other Entities\" to be used as an Item Type"); entitySave.ItemType = null; } } } #endregion #region ClassName else if (changedMember == "ClassName") { List <NamedObjectSave> allNamedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseElement(EditorLogic.CurrentElement); List <IElement> containers = new List <IElement>(); foreach (NamedObjectSave nos in allNamedObjects) { IElement element = nos.GetContainer(); if (!containers.Contains(element)) { containers.Add(element); } } foreach (IElement element in containers) { CodeGeneratorIElement.GenerateElement(element); } } #endregion }