private static void CreateStructField(MultiStruct010TemplateBase template, MhwMultiStructData.StructData @struct, MhwMultiStructData.Entry entry = null, uint indentation = 0) { var name = @struct.SafeName; string entryText; if (@struct.fixedSizeCount > 1) { entryText = $"{name} {name}_[{@struct.fixedSizeCount}]<optimize=false, name=\"{@struct.name}\">;"; } else if (@struct.Has010Link) { var linkStruct = @struct._010Link.@struct; var linkEntry = @struct._010Link.entry; string countTarget; // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (linkStruct == null || linkStruct.showVertically) { countTarget = linkEntry.SafeName; } else { countTarget = $"{linkStruct.SafeName}_.{linkEntry.SafeName}"; } entryText = $"{name} {name}_[{countTarget}]<optimize=false, name=\"{@struct.name}\">;"; } else { entryText = $"{name} {name}_<name=\"{@struct.name}\">;"; } if (entry?.condition != null) { var condition = entry.condition.Replace("|ref|", "").Replace("_raw", "").Replace("parent.", ""); template.WriteLine(indentation, $"{condition} {{ {entryText} }}"); } else { template.WriteLine(indentation, entryText); } }
private static void InnerLoadData(MultiStructItemTemplateBase template, uint indentation, MhwMultiStructData.StructData @struct, MhwMultiStructData.StructData parent = null) { if (@struct.customSaveLoad) { return; } var name = @struct.SafeName; // Individual LoadData (loop). template.WriteLine(""); // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (parent != null) { template.WriteLine(indentation, $" public static ObservableMhwStructCollection<{name}> LoadData(BinaryReader reader, {parent.SafeName} parent) {{"); } else if (@struct.Has010Link) { var targetName = @[email protected]; template.WriteLine(indentation, $" public static ObservableMhwStructCollection<{name}> LoadData(BinaryReader reader, ObservableMhwStructCollection<{targetName}> lastStruct) {{"); } else { template.WriteLine(indentation, $" public static ObservableMhwStructCollection<{name}> LoadData(BinaryReader reader) {{"); } template.WriteLine(indentation, $" var list = new ObservableMhwStructCollection<{name}>();"); if (@struct.Has010Link) { var linkStruct = @struct._010Link.@struct; var linkEntry = @struct._010Link.entry; if (linkStruct == null) { template.WriteLine(indentation, $" var count = (ulong) parent.{linkEntry.SafeName};"); } else { template.WriteLine(indentation, $" var countTarget = ({linkStruct.SafeName}) lastStruct.Last();"); template.WriteLine(indentation, $" var count = (ulong) countTarget.{linkEntry.SafeName};"); } } else { // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (@struct.customCount) { template.WriteLine(indentation, " ulong count = GetLoadCount(reader, parent);"); } else { template.WriteLine(indentation, $" const ulong count = {@struct.fixedSizeCount}UL;"); } } template.WriteLine(indentation, " for (ulong i = 0; i < count; i++) {"); // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (parent != null) { template.WriteLine(indentation, " list.Add(LoadData(reader, i, parent));"); } else { template.WriteLine(indentation, " list.Add(LoadData(reader, i));"); } template.WriteLine(indentation, " }"); template.WriteLine(indentation, " return list;"); template.WriteLine(indentation, " }"); // Individual LoadData. template.WriteLine(""); // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (parent != null) { template.WriteLine(indentation, $" public static {name} LoadData(BinaryReader reader, ulong i, {parent.SafeName} parent) {{"); } else { template.WriteLine(indentation, $" public static {name} LoadData(BinaryReader reader, ulong i) {{"); } template.WriteLine(indentation, $" var data = new {name}();"); template.WriteLine(indentation, " data.Index = i;"); foreach (var entry in @struct.entries) { var propName = entry.SafeName; var entryName = $"{propName}_raw"; var condition = ""; if (entry.condition != null) { condition = $"{entry.condition} ".Replace("|ref|", "data."); } if (@struct.showVertically) { template.WriteLine(indentation, $" {condition}data.{propName}_offset = reader.BaseStream.Position;"); } if (entry.arrayCount > -1) { template.WriteLine(indentation, $" {condition}data.{entryName} = reader.Read{GetReadType(entry.type)}s({entry.arrayCount});"); } else if (entry.isNullTerminatedString) { template.WriteLine(indentation, $" {condition}data.{entryName} = reader.ReadNullTermString();"); } else if (entry.HasSubStruct) { template.WriteLine(indentation, $" {condition}data.{entryName} = {entry.subStruct.SafeName}.LoadData(reader, data);"); if (!string.IsNullOrEmpty(condition)) { template.WriteLine(indentation, $" else data.{entryName} = new ObservableCollection<{entry.subStruct.SafeName}>();"); } } else { template.WriteLine(indentation, $" {condition}data.{entryName} = reader.Read{GetReadType(entry.type)}();"); } } template.WriteLine(indentation, " return data;"); template.WriteLine(indentation, " }"); }
private static void InnerEnumerateChildren(MultiStructItemTemplateBase template, uint indentation, MhwMultiStructData.StructData @struct, MhwMultiStructData.StructData parent = null) { template.WriteLine(""); template.WriteLine(indentation, " public IEnumerable<F> GetAllEnumerableChildrenOfType<F>() {"); foreach (var entry in @struct.entries) { if (entry.HasSubStruct) { var subStructSafeName = entry.subStruct.SafeName; template.WriteLine(indentation, $" if (typeof({subStructSafeName}).Is(typeof(F)) || typeof({subStructSafeName}).IsGeneric(typeof(F))) {{"); template.WriteLine(indentation, $" foreach (var item in {entry.SafeName}_raw.Cast<F>()) {{"); template.WriteLine(indentation, " yield return item;"); template.WriteLine(indentation, " }"); template.WriteLine(indentation, " }"); } } template.WriteLine(indentation, " }"); }
private static void InnerWriteData(MultiStructItemTemplateBase template, uint indentation, MhwMultiStructData.StructData @struct, MhwMultiStructData.StructData parent) { // Individual WriteData. template.WriteLine(""); // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (parent != null) { template.WriteLine(indentation, $" public void WriteData(BinaryWriter writer, {parent.SafeName} parent) {{"); } else { template.WriteLine(indentation, " public void WriteData(BinaryWriter writer) {"); } // Do first since we need to update counts before writing them. foreach (var entry in @struct.entries) { var propName = entry.SafeName; var entryName = $"{propName}_raw"; if (entry.HasSubStruct) { if (entry.subStruct._010Link != null) { var linkEntry = entry.subStruct._010Link.entry; var typeString = COMPILER.GetTypeOutput(new CodeTypeReference(linkEntry.type)); var condition = ""; if (entry.condition != null) { condition = $"{entry.condition} ".Replace("|ref|", ""); } template.WriteLine(indentation, $" {condition}{linkEntry.SafeName} = ({typeString}) {entryName}.Count;"); } } } foreach (var entry in @struct.entries) { var propName = entry.SafeName; var entryName = $"{propName}_raw"; var condition = ""; if (entry.condition != null) { condition = $"{entry.condition} ".Replace("|ref|", ""); } if (entry.type == typeof(string)) { template.WriteLine(indentation, $" {condition}writer.Write({entryName}.ToNullTermCharArray());"); } else if (entry.HasSubStruct) { template.WriteLine(indentation, $" {condition}foreach (var obj in {entryName}) {{"); template.WriteLine(indentation, " obj.WriteData(writer, this);"); template.WriteLine(indentation, " }"); } else { template.WriteLine(indentation, $" {condition}writer.Write({entryName});"); } } template.WriteLine(indentation, " }"); }
private static void GetCustomView(MultiStructItemTemplateBase template, uint indentation, MhwMultiStructData.StructData @struct) { template.WriteLine(""); template.WriteLine(indentation, " public ObservableCollection<MultiStructItemCustomView> GetCustomView() {"); template.WriteLine(indentation, " return new ObservableCollection<MultiStructItemCustomView> {"); foreach (var entry in @struct.entries) { var propName = entry.SafeName; template.WriteLine(indentation, $" new MultiStructItemCustomView(this, \"{entry.name}\", \"{propName}\", \"{propName}_offset\"),"); } template.WriteLine(indentation, " };"); template.WriteLine(indentation, " }"); }
private static void GenerateInnerClass(MultiStructItemTemplateBase template, MhwMultiStructData.StructData @struct, MhwMultiStructData.StructData parent = null, uint indentation = 0) { var sortIndex = SORT_INDEX_STEP; var name = @struct.SafeName; var interfaces = "MhwStructItem"; var hasChildren = @struct.entries.Any(entry => entry.HasSubStruct); if (@struct.showVertically) { interfaces += ", IHasCustomView<MultiStructItemCustomView>"; } if (parent == null) { interfaces += ", IWriteData"; } else { interfaces += $", IWriteDataInner<{parent.SafeName}>"; } if (hasChildren) { interfaces += ", IHasChildren"; } template.WriteLine(""); template.WriteLine(indentation, $" public partial class {name} : {interfaces} {{"); template.WriteLine(indentation, $" public const ulong FixedSizeCount = {@struct.fixedSizeCount};"); template.WriteLine(indentation, $" public const string GridName = \"{@struct.name}\";"); if (@struct.uniqueIdFormula != null) { template.WriteLine(indentation, $" public override string UniqueId => $\"{@struct.uniqueIdFormula}\";"); } if (@struct.hidden) { template.WriteLine(indentation, $" public const bool IsHidden = {@struct.hidden.ToString().ToLower()};"); } if (@struct.description != null) { template.WriteLine(indentation, $" public const string Description = \"{@struct.description}\";"); } if (@struct.canAddRows) { template.WriteLine(indentation, $" public const bool IsAddingAllowed = {@struct.canAddRows.ToString().ToLower()};"); template.WriteLine(""); template.WriteLine(indentation, " [SortOrder(-1)]"); template.WriteLine(indentation, " [IsReadOnly]"); template.WriteLine(indentation, " [DisplayName(\"X\")]"); template.WriteLine(indentation, " public string Delete => \"X\";"); } foreach (var entry in @struct.entries) { var propName = entry.SafeName; var entryName = $"{propName}_raw"; if (entry.HasSubStruct) { GenerateInnerClass(template, entry.subStruct, @struct, indentation + 1); MakeSubProperty(template, indentation, entry, entryName, propName, sortIndex); } else { MakeMainProperty(template, indentation, entry, entryName, propName, sortIndex); if (entry.dataSourceType != null) { MakeButtonProperty(template, indentation, entry, propName); } if (entry.createPercentField) { MakePercentProperty(template, indentation, propName); } if (@struct.showVertically) { MakeOffsetProperty(template, indentation, entry, propName); } } sortIndex += SORT_INDEX_STEP; } template.WriteLine(""); template.WriteLine(indentation, $" public const int lastSortIndex = {sortIndex};"); if (hasChildren) { InnerEnumerateChildren(template, indentation, @struct, parent); } InnerLoadData(template, indentation, @struct, parent); InnerWriteData(template, indentation, @struct, parent); // GetCustomView (if needed). if (@struct.showVertically) { GetCustomView(template, indentation, @struct); } template.WriteLine(indentation, " }"); }
private static void CreateStruct(MultiStruct010TemplateBase template, MhwMultiStructData.StructData @struct, uint indentation = 0) { var name = @struct.SafeName; var innerIndentation = indentation; var isInnerStruct = indentation > 0; template.WriteLine(""); if ([email protected] || isInnerStruct) { template.WriteLine(indentation, $"// {@struct.name}"); template.WriteLine(indentation, "typedef struct {"); innerIndentation++; } else if (@struct.showVertically) { template.WriteLine(indentation, $"// {@struct.name}"); } foreach (var entry in @struct.entries) { if (entry.HasSubStruct) { CreateStruct(template, entry.subStruct, innerIndentation); template.WriteLine(""); CreateStructField(template, entry.subStruct, entry, innerIndentation); continue; } var propName = entry.SafeName; var typeString = COMPILER.GetTypeOutput(new CodeTypeReference(entry.type)); if (typeString == "byte") { typeString = "ubyte"; } if (typeString == "sbyte") { typeString = "byte"; } if (typeString == "long") { typeString = "uint64"; } if (typeString == "ulong") { typeString = "int64"; } if (entry.arrayCount > -1) { propName += $"[{entry.arrayCount}]<optimize=false, name=\"{entry.name}\">"; } else { propName += $"<name=\"{entry.name} ({typeString})\">"; } if (entry.condition != null) { var condition = entry.condition.Replace("|ref|", "").Replace("_raw", "").Replace("parent.", ""); template.WriteLine(innerIndentation, $"{condition} {{ {typeString} {propName}; }}"); } else { template.WriteLine(innerIndentation, $"{typeString} {propName};"); } } if ([email protected] || isInnerStruct) { template.WriteLine(indentation, $"}} {name};"); if (indentation == 0) { template.WriteLine(""); CreateStructField(template, @struct, indentation: indentation); } } }