public override async Task GenerateInClass(ObjectGeneration obj, FileGeneration fg) { if (obj.GetObjectData().ObjectType != ObjectType.Mod) { return; } var objData = obj.GetObjectData(); // Game release member if (objData.GameReleaseOptions != null) { fg.AppendLine($"public {ReleaseEnumName(obj)} {ReleaseEnumName(obj)} {{ get; }}"); fg.AppendLine($"public override {nameof(GameRelease)} GameRelease => {ReleaseEnumName(obj)}.ToGameRelease();"); } else { fg.AppendLine($"public override {nameof(GameRelease)} GameRelease => {nameof(GameRelease)}.{obj.GetObjectData().GameCategory};"); } // Interfaces fg.AppendLine($"IGroupGetter<T> {nameof(IModGetter)}.{nameof(IModGetter.GetTopLevelGroup)}<T>() => this.{nameof(IModGetter.GetTopLevelGroup)}<T>();"); fg.AppendLine($"IGroupGetter {nameof(IModGetter)}.{nameof(IModGetter.GetTopLevelGroup)}(Type type) => this.{nameof(IModGetter.GetTopLevelGroup)}(type);"); fg.AppendLine($"IGroup<T> {nameof(IMod)}.{nameof(IMod.GetTopLevelGroup)}<T>() => this.{nameof(IMod.GetTopLevelGroup)}<T>();"); fg.AppendLine($"IGroup {nameof(IMod)}.{nameof(IMod.GetTopLevelGroup)}(Type type) => this.{nameof(IMod.GetTopLevelGroup)}(type);"); fg.AppendLine($"void IModGetter.WriteToBinary({nameof(FilePath)} path, {nameof(BinaryWriteParameters)}? param, IFileSystem? fileSystem) => this.WriteToBinary(path, importMask: null, param: param, fileSystem: fileSystem);"); fg.AppendLine($"void IModGetter.WriteToBinaryParallel({nameof(FilePath)} path, {nameof(BinaryWriteParameters)}? param, IFileSystem? fileSystem, {nameof(ParallelWriteParameters)}? parallelWriteParams) => this.WriteToBinaryParallel(path, param, fileSystem: fileSystem, parallelParam: parallelWriteParams);"); fg.AppendLine($"IMask<bool> {nameof(IEqualsMask)}.{nameof(IEqualsMask.GetEqualsMask)}(object rhs, EqualsMaskHelper.Include include = EqualsMaskHelper.Include.OnlyFailures) => {obj.MixInClassName}.GetEqualsMask(this, ({obj.Interface(getter: true, internalInterface: true)})rhs, include);"); // Localization enabled member if (obj.GetObjectData().UsesStringFiles) { fg.AppendLine($"public override bool CanUseLocalization => true;"); fg.AppendLine($"public override bool UsingLocalization"); using (new BraceWrapper(fg)) { fg.AppendLine($"get => this.ModHeader.Flags.HasFlag({obj.GetObjectData().GameCategory}ModHeader.HeaderFlag.Localized);"); fg.AppendLine($"set => this.ModHeader.Flags = this.ModHeader.Flags.SetFlag({obj.GetObjectData().GameCategory}ModHeader.HeaderFlag.Localized, value);"); } } else { fg.AppendLine($"public override bool CanUseLocalization => false;"); fg.AppendLine($"public override bool UsingLocalization"); using (new BraceWrapper(fg)) { fg.AppendLine("get => false;"); fg.AppendLine("set => throw new ArgumentException(\"Tried to set localization flag on unsupported mod type\");"); } } // Master references member fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"IList<MasterReference> IMod.MasterReferences => this.ModHeader.MasterReferences;"); fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"IReadOnlyList<IMasterReferenceGetter> IModGetter.MasterReferences => this.ModHeader.MasterReferences;"); // NextObjectID member fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"uint IMod.NextFormID"); using (new BraceWrapper(fg)) { fg.AppendLine($"get => this.ModHeader.Stats.NextFormID;"); fg.AppendLine($"set => this.ModHeader.Stats.NextFormID = value;"); } fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"uint IModGetter.NextFormID => this.ModHeader.Stats.NextFormID;"); using (var args = new FunctionWrapper(fg, $"public {obj.Name}")) { args.Add($"{nameof(ModKey)} modKey"); if (objData.GameReleaseOptions != null) { args.Add($"{ReleaseEnumName(obj)} release"); } } using (new DepthWrapper(fg)) { fg.AppendLine(": base(modKey)"); } using (new BraceWrapper(fg)) { fg.AppendLine("this.ModHeader.Stats.NextFormID = GetDefaultInitialNextFormID();"); if (objData.GameReleaseOptions != null) { fg.AppendLine($"this.{ReleaseEnumName(obj)} = release;"); } await obj.GenerateInitializer(fg); fg.AppendLine($"CustomCtor();"); } using (var args = new FunctionWrapper(fg, "public void AddRecords")) { args.Add($"{obj.Name} rhsMod"); args.Add($"GroupMask? mask = null"); } using (new BraceWrapper(fg)) { foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } fg.AppendLine($"if (mask?.{field.Name} ?? true)"); using (new BraceWrapper(fg)) { if (loqui.TargetObjectGeneration.Name == $"{obj.ProtoGen.Protocol.Namespace}Group") { fg.AppendLine($"this.{field.Name}.RecordCache.Set(rhsMod.{field.Name}.RecordCache.Items);"); } else { fg.AppendLine($"if (rhsMod.{field.Name}.Records.Count > 0)"); using (new BraceWrapper(fg)) { fg.AppendLine("throw new NotImplementedException(\"Cell additions need implementing\");"); } } } } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, "public override void SyncRecordCount")) { } using (new BraceWrapper(fg)) { fg.AppendLine("this.ModHeader.Stats.NumRecords = GetRecordCount();"); } fg.AppendLine(); using (var args = new FunctionWrapper(fg, "public uint GetRecordCount")) { } using (new BraceWrapper(fg)) { fg.AppendLine("uint count = (uint)this.EnumerateMajorRecords().Count();"); foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } if (loqui.TargetObjectGeneration.Name.EndsWith("ListGroup")) { fg.AppendLine($"count += {field.Name}.Records.Count > 0 ? 1 : default(uint);"); } else { fg.AppendLine($"count += {field.Name}.RecordCache.Count > 0 ? 1 : default(uint);"); } } fg.AppendLine("GetCustomRecordCount((customCount) => count += customCount);"); fg.AppendLine("return count;"); } fg.AppendLine(); fg.AppendLine("partial void GetCustomRecordCount(Action<uint> setter);"); fg.AppendLine(); await base.GenerateInClass(obj, fg); }
public override async Task GenerateInClass(ObjectGeneration obj, FileGeneration fg) { if (obj.GetObjectData().ObjectType != ObjectType.Mod) { return; } var objData = obj.GetObjectData(); // Game release member if (objData.GameReleaseOptions != null) { fg.AppendLine($"public {ReleaseEnumName(obj)} {ReleaseEnumName(obj)} {{ get; }}"); fg.AppendLine($"public override {nameof(GameRelease)} GameRelease => {ReleaseEnumName(obj)}.ToGameRelease();"); } else { fg.AppendLine($"public override {nameof(GameRelease)} GameRelease => {nameof(GameRelease)}.{obj.GetObjectData().GameCategory};"); } // Interfaces fg.AppendLine($"IReadOnlyCache<T, {nameof(FormKey)}> {nameof(IModGetter)}.{nameof(IModGetter.GetTopLevelGroupGetter)}<T>() => this.{nameof(IModGetter.GetTopLevelGroupGetter)}<T>();"); fg.AppendLine($"ICache<T, {nameof(FormKey)}> {nameof(IMod)}.{nameof(IMod.GetGroup)}<T>() => this.GetGroup<T>();"); fg.AppendLine($"void IModGetter.WriteToBinary(string path, {nameof(BinaryWriteParameters)}? param) => this.WriteToBinary(path, importMask: null, param: param);"); fg.AppendLine($"void IModGetter.WriteToBinaryParallel(string path, {nameof(BinaryWriteParameters)}? param) => this.WriteToBinaryParallel(path, param);"); fg.AppendLine($"IMask<bool> {nameof(IEqualsMask)}.{nameof(IEqualsMask.GetEqualsMask)}(object rhs, EqualsMaskHelper.Include include = EqualsMaskHelper.Include.OnlyFailures) => {obj.MixInClassName}.GetEqualsMask(this, ({obj.Interface(getter: true, internalInterface: true)})rhs, include);"); // Localization enabled member if (obj.GetObjectData().UsesStringFiles) { fg.AppendLine($"public override bool CanUseLocalization => true;"); fg.AppendLine($"public override bool UsingLocalization"); using (new BraceWrapper(fg)) { fg.AppendLine($"get => this.ModHeader.Flags.HasFlag({obj.GetObjectData().GameCategory}ModHeader.HeaderFlag.Localized);"); fg.AppendLine($"set => this.ModHeader.Flags.SetFlag({obj.GetObjectData().GameCategory}ModHeader.HeaderFlag.Localized, value);"); } } else { fg.AppendLine($"public override bool CanUseLocalization => false;"); fg.AppendLine($"public override bool UsingLocalization"); using (new BraceWrapper(fg)) { fg.AppendLine("get => false;"); fg.AppendLine("set => throw new ArgumentException(\"Tried to set localization flag on unsupported mod type\");"); } } // Master references member fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"IList<MasterReference> IMod.MasterReferences => this.ModHeader.MasterReferences;"); fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"IReadOnlyList<IMasterReferenceGetter> IModGetter.MasterReferences => this.ModHeader.MasterReferences;"); // NextObjectID member fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"uint IMod.NextFormID"); using (new BraceWrapper(fg)) { fg.AppendLine($"get => this.ModHeader.Stats.NextFormID;"); fg.AppendLine($"set => this.ModHeader.Stats.NextFormID = value;"); } fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"uint IModGetter.NextFormID => this.ModHeader.Stats.NextFormID;"); using (var args = new FunctionWrapper(fg, $"public {obj.Name}")) { args.Add($"{nameof(ModKey)} modKey"); if (objData.GameReleaseOptions != null) { args.Add($"{ReleaseEnumName(obj)} release"); } } using (new DepthWrapper(fg)) { fg.AppendLine(": base(modKey)"); } using (new BraceWrapper(fg)) { fg.AppendLine("this.ModHeader.Stats.NextFormID = GetDefaultInitialNextFormID();"); if (objData.GameReleaseOptions != null) { fg.AppendLine($"this.{ReleaseEnumName(obj)} = release;"); } await obj.GenerateInitializer(fg); fg.AppendLine($"CustomCtor();"); } using (var args = new FunctionWrapper(fg, "public void AddRecords")) { args.Add($"{obj.Name} rhsMod"); args.Add($"GroupMask? mask = null"); } using (new BraceWrapper(fg)) { foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } fg.AppendLine($"if (mask?.{field.Name} ?? true)"); using (new BraceWrapper(fg)) { if (loqui.TargetObjectGeneration.Name == "Group") { fg.AppendLine($"this.{field.Name}.RecordCache.Set(rhsMod.{field.Name}.RecordCache.Items);"); } else { fg.AppendLine($"if (rhsMod.{field.Name}.Records.Count > 0)"); using (new BraceWrapper(fg)) { fg.AppendLine("throw new NotImplementedException(\"Cell additions need implementing\");"); } } } } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public Dictionary<FormKey, {nameof(IMajorRecordCommon)}> CopyInDuplicate")) { args.Add($"{obj.Name} rhs"); args.Add($"GroupMask? mask = null"); } using (new BraceWrapper(fg)) { fg.AppendLine($"var duppedRecords = new List<({nameof(IMajorRecordCommon)} Record, FormKey OriginalFormKey)>();"); foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } var dictGroup = loqui.TargetObjectGeneration.Name == "Group"; fg.AppendLine($"if (mask?.{field.Name} ?? true)"); using (new BraceWrapper(fg)) { fg.AppendLine($"this.{field.Name}.{(dictGroup ? "RecordCache" : "Records")}.{(dictGroup ? "Set" : "AddRange")}("); using (new DepthWrapper(fg)) { fg.AppendLine($"rhs.{field.Name}.Records"); using (new DepthWrapper(fg)) { fg.AppendLine($".Select(i => i.Duplicate(this.GetNextFormKey, duppedRecords))"); fg.AppendLine($".Cast<{loqui.GetGroupTarget().Name}>());"); } } } } fg.AppendLine($"var router = new Dictionary<FormKey, {nameof(IMajorRecordCommon)}>();"); fg.AppendLine($"router.Set(duppedRecords.Select(dup => new KeyValuePair<FormKey, {nameof(IMajorRecordCommon)}>(dup.OriginalFormKey, dup.Record)));"); fg.AppendLine($"var mapping = new Dictionary<FormKey, FormKey>();"); fg.AppendLine($"var package = this.{nameof(ILinkCacheExt.ToImmutableLinkCache)}();"); fg.AppendLine("foreach (var rec in router.Values)"); using (new BraceWrapper(fg)) { fg.AppendLine($"rec.RemapLinks(mapping);"); } fg.AppendLine($"return router;"); } fg.AppendLine(); using (var args = new FunctionWrapper(fg, "public override void SyncRecordCount")) { } using (new BraceWrapper(fg)) { fg.AppendLine("this.ModHeader.Stats.NumRecords = GetRecordCount();"); } fg.AppendLine(); using (var args = new FunctionWrapper(fg, "public uint GetRecordCount")) { } using (new BraceWrapper(fg)) { fg.AppendLine("uint count = (uint)this.EnumerateMajorRecords().Count();"); foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } if (loqui.TargetObjectGeneration.Name == "ListGroup") { fg.AppendLine($"count += {field.Name}.Records.Count > 0 ? 1 : default(uint);"); } else { fg.AppendLine($"count += {field.Name}.RecordCache.Count > 0 ? 1 : default(uint);"); } } fg.AppendLine("GetCustomRecordCount((customCount) => count += customCount);"); fg.AppendLine("return count;"); } fg.AppendLine(); fg.AppendLine("partial void GetCustomRecordCount(Action<uint> setter);"); fg.AppendLine(); await base.GenerateInClass(obj, fg); }
public override async Task GenerateInClass(ObjectGeneration obj, FileGeneration fg) { if (obj.GetObjectData().ObjectType != ObjectType.Mod) { return; } // Gamemode member fg.AppendLine($"public override {nameof(GameMode)} GameMode => {nameof(GameMode)}.{obj.GetObjectData().GameMode};"); // Interfaces fg.AppendLine($"IReadOnlyCache<T, {nameof(FormKey)}> {nameof(IModGetter)}.{nameof(IModGetter.GetGroupGetter)}<T>() => this.GetGroupGetter<T>();"); fg.AppendLine($"ICache<T, {nameof(FormKey)}> {nameof(IMod)}.{nameof(IMod.GetGroup)}<T>() => this.GetGroup<T>();"); fg.AppendLine($"void IModGetter.WriteToBinary(string path, {nameof(BinaryWriteParameters)}? param) => this.WriteToBinary(path, importMask: null, param: param);"); fg.AppendLine($"void IModGetter.WriteToBinaryParallel(string path, {nameof(BinaryWriteParameters)}? param) => this.WriteToBinaryParallel(path, param);"); // Localization enabled member fg.AppendLine($"public override bool CanUseLocalization => {(obj.GetObjectData().UsesStringFiles ? "true" : "false")};"); // Master references member fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"IList<MasterReference> IMod.MasterReferences => this.ModHeader.MasterReferences;"); fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"IReadOnlyList<IMasterReferenceGetter> IModGetter.MasterReferences => this.ModHeader.MasterReferences;"); // NextObjectID member fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"uint IMod.NextObjectID"); using (new BraceWrapper(fg)) { fg.AppendLine($"get => this.ModHeader.Stats.NextObjectID;"); fg.AppendLine($"set => this.ModHeader.Stats.NextObjectID = value;"); } fg.AppendLine($"public {obj.Name}({nameof(ModKey)} modKey)"); using (new DepthWrapper(fg)) { fg.AppendLine(": base(modKey)"); } using (new BraceWrapper(fg)) { fg.AppendLine("this.ModHeader.Stats.NextObjectID = GetDefaultInitialNextObjectID();"); await obj.GenerateInitializer(fg); } using (var args = new FunctionWrapper(fg, "public void AddRecords")) { args.Add($"{obj.Name} rhsMod"); args.Add($"GroupMask? mask = null"); } using (new BraceWrapper(fg)) { foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } fg.AppendLine($"if (mask?.{field.Name} ?? true)"); using (new BraceWrapper(fg)) { if (loqui.TargetObjectGeneration.Name == "Group") { fg.AppendLine($"this.{field.Name}.RecordCache.Set(rhsMod.{field.Name}.RecordCache.Items);"); } else { fg.AppendLine($"if (rhsMod.{field.Name}.Records.Count > 0)"); using (new BraceWrapper(fg)) { fg.AppendLine("throw new NotImplementedException(\"Cell additions need implementing\");"); } } } } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public Dictionary<FormKey, {nameof(IMajorRecordCommon)}> CopyInDuplicate")) { args.Add($"{obj.Name} rhs"); args.Add($"GroupMask? mask = null"); } using (new BraceWrapper(fg)) { fg.AppendLine($"var duppedRecords = new List<({nameof(IMajorRecordCommon)} Record, FormKey OriginalFormKey)>();"); foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } var dictGroup = loqui.TargetObjectGeneration.Name == "Group"; fg.AppendLine($"if (mask?.{field.Name} ?? true)"); using (new BraceWrapper(fg)) { fg.AppendLine($"this.{field.Name}.{(dictGroup ? "RecordCache" : "Records")}.{(dictGroup ? "Set" : "AddRange")}("); using (new DepthWrapper(fg)) { fg.AppendLine($"rhs.{field.Name}.Records"); using (new DepthWrapper(fg)) { fg.AppendLine($".Select(i => i.Duplicate(this.GetNextFormKey, duppedRecords))"); fg.AppendLine($".Cast<{loqui.GetGroupTarget().Name}>());"); } } } } fg.AppendLine($"var router = new Dictionary<FormKey, {nameof(IMajorRecordCommon)}>();"); fg.AppendLine($"router.Set(duppedRecords.Select(dup => new KeyValuePair<FormKey, {nameof(IMajorRecordCommon)}>(dup.OriginalFormKey, dup.Record)));"); fg.AppendLine($"var mapping = new Dictionary<FormKey, FormKey>();"); fg.AppendLine($"var package = this.CreateLinkCache();"); fg.AppendLine("foreach (var rec in router.Values)"); using (new BraceWrapper(fg)) { fg.AppendLine($"rec.RemapLinks(mapping);"); } fg.AppendLine($"return router;"); } fg.AppendLine(); using (var args = new FunctionWrapper(fg, "public override void SyncRecordCount")) { } using (new BraceWrapper(fg)) { fg.AppendLine("this.ModHeader.Stats.NumRecords = GetRecordCount();"); } fg.AppendLine(); using (var args = new FunctionWrapper(fg, "public int GetRecordCount")) { } using (new BraceWrapper(fg)) { fg.AppendLine("int count = this.EnumerateMajorRecords().Count();"); foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } if (loqui.TargetObjectGeneration.Name == "ListGroup") { fg.AppendLine($"count += {field.Name}.Records.Count > 0 ? 1 : 0;"); } else { fg.AppendLine($"count += {field.Name}.RecordCache.Count > 0 ? 1 : 0;"); } } fg.AppendLine("GetCustomRecordCount((customCount) => count += customCount);"); fg.AppendLine("return count;"); } fg.AppendLine(); fg.AppendLine("partial void GetCustomRecordCount(Action<int> setter);"); fg.AppendLine(); await base.GenerateInClass(obj, fg); }