public override async Task GenerateWrite(
            FileGeneration fg,
            ObjectGeneration objGen,
            TypeGeneration typeGen,
            Accessor writerAccessor,
            Accessor itemAccessor,
            Accessor errorMaskAccessor,
            Accessor translationMaskAccessor,
            Accessor converterAccessor)
        {
            var data = typeGen.GetFieldData();

            using (var args = new ArgsWrapper(fg,
                                              $"{objGen.CommonClass(LoquiInterfaceType.ISetter, CommonGenerics.Class)}.SpecialWrite_{typeGen.Name}_Internal"))
            {
                args.AddPassArg("item");
                args.AddPassArg("writer");
            }
        }
예제 #2
0
        public override async Task GenerateInCommonMixin(ObjectGeneration obj, FileGeneration fg)
        {
            await base.GenerateInCommonMixin(obj, fg);

            if (obj.GetObjectType() != ObjectType.Mod)
            {
                return;
            }
            using (var args = new FunctionWrapper(fg,
                                                  $"public static IReadOnlyCache<T, FormKey> {nameof(IModGetter.GetTopLevelGroupGetter)}<T>"))
            {
                args.Wheres.Add($"where T : {nameof(IMajorRecordCommonGetter)}");
                args.Add($"this {obj.Interface(getter: true)} obj");
            }
            using (new BraceWrapper(fg))
            {
                using (var args = new ArgsWrapper(fg,
                                                  $"return (IReadOnlyCache<T, FormKey>){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup<T>"))
                {
                    args.AddPassArg("obj");
                }
            }
            fg.AppendLine();

            using (var args = new FunctionWrapper(fg,
                                                  "public static ICache<T, FormKey> GetGroup<T>"))
            {
                args.Wheres.Add($"where T : {nameof(IMajorRecordCommon)}");
                args.Add($"this {obj.Interface(getter: false)} obj");
            }
            using (new BraceWrapper(fg))
            {
                using (var args = new ArgsWrapper(fg,
                                                  $"return (ICache<T, FormKey>){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup<T>"))
                {
                    args.AddPassArg("obj");
                }
            }
            fg.AppendLine();

            using (var args = new FunctionWrapper(fg,
                                                  $"public static void WriteToBinaryParallel"))
            {
                args.Add($"this {obj.Interface(getter: true, internalInterface: false)} item");
                args.Add($"Stream stream");
                args.Add($"{nameof(BinaryWriteParameters)}? param = null");
            }
            using (new BraceWrapper(fg))
            {
                using (var args = new ArgsWrapper(fg,
                                                  $"{obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.WriteParallel"))
                {
                    args.AddPassArg("item");
                    args.AddPassArg("stream");
                    args.Add($"param: param ?? {nameof(BinaryWriteParameters)}.{nameof(BinaryWriteParameters.Default)}");
                    args.Add("modKey: item.ModKey");
                }
            }
            fg.AppendLine();

            using (var args = new FunctionWrapper(fg,
                                                  $"public static void WriteToBinaryParallel"))
            {
                args.Add($"this {obj.Interface(getter: true, internalInterface: false)} item");
                args.Add($"string path");
                args.Add($"{nameof(BinaryWriteParameters)}? param = null");
            }
            using (new BraceWrapper(fg))
            {
                fg.AppendLine($"param ??= {nameof(BinaryWriteParameters)}.{nameof(BinaryWriteParameters.Default)};");
                using (var args = new ArgsWrapper(fg,
                                                  $"var modKey = param.{nameof(BinaryWriteParameters.RunMasterMatch)}"))
                {
                    args.Add("mod: item");
                    args.AddPassArg("path");
                }
                if (obj.GetObjectData().UsesStringFiles)
                {
                    fg.AppendLine("bool disposeStrings = param.StringsWriter == null;");
                    fg.AppendLine("param.StringsWriter ??= EnumExt.HasFlag((int)item.ModHeader.Flags, (int)ModHeaderCommonFlag.Localized) ? new StringsWriter(modKey, Path.Combine(Path.GetDirectoryName(path)!, \"Strings\")) : null;");
                }
                fg.AppendLine("using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write))");
                using (new BraceWrapper(fg))
                {
                    using (var args = new ArgsWrapper(fg,
                                                      $"{obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.WriteParallel"))
                    {
                        args.AddPassArg("item");
                        args.AddPassArg("stream");
                        args.Add($"param: param");
                        args.AddPassArg("modKey");
                    }
                }
                if (obj.GetObjectData().UsesStringFiles)
                {
                    fg.AppendLine("if (disposeStrings)");
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine("param.StringsWriter?.Dispose();");
                    }
                }
            }
            fg.AppendLine();
        }
        public override async Task GenerateInCommon(ObjectGeneration obj, FileGeneration fg, MaskTypeSet maskTypes)
        {
            bool getter = maskTypes.Applicable(LoquiInterfaceType.IGetter, CommonGenerics.Class);
            bool setter = maskTypes.Applicable(LoquiInterfaceType.ISetter, CommonGenerics.Class);

            if (!getter && !setter)
            {
                return;
            }
            var accessor = new Accessor("obj");

            if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No)
            {
                return;
            }
            var overrideStr = await obj.FunctionOverride(async c => await MajorRecordModule.HasMajorRecords(c, includeBaseClass : false, includeSelf : true) != Case.No);

            using (var args = new FunctionWrapper(fg,
                                                  $"public{overrideStr}IEnumerable<{nameof(IMajorRecordCommon)}{(getter ? "Getter" : null)}> EnumerateMajorRecords"))
            {
                args.Add($"{obj.Interface(getter: getter, internalInterface: true)} obj");
            }
            using (new BraceWrapper(fg))
            {
                if (setter)
                {
                    fg.AppendLine($"foreach (var item in {obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class)}.Instance.EnumerateMajorRecords(obj))");
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"yield return (item as {nameof(IMajorRecordCommon)})!;");
                    }
                }
                else
                {
                    var fgCount = fg.Count;
                    foreach (var baseClass in obj.BaseClassTrail())
                    {
                        if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No)
                        {
                            fg.AppendLine("foreach (var item in base.EnumerateMajorRecords(obj))");
                            using (new BraceWrapper(fg))
                            {
                                fg.AppendLine("yield return item;");
                            }
                            break;
                        }
                    }
                    foreach (var field in obj.IterateFields())
                    {
                        switch (field)
                        {
                        case LoquiType _:
                        case ContainerType _:
                        case DictType _:
                            break;

                        default:
                            continue;
                        }

                        FileGeneration fieldFg = new FileGeneration();
                        if (field is LoquiType loqui)
                        {
                            var isMajorRecord = loqui.TargetObjectGeneration != null && await loqui.TargetObjectGeneration.IsMajorRecord();

                            if (isMajorRecord ||
                                await MajorRecordModule.HasMajorRecords(loqui, includeBaseClass: true) != Case.No)
                            {
                                var subFg         = new FileGeneration();
                                var fieldAccessor = loqui.Nullable ? $"{loqui.Name}item" : $"{accessor}.{loqui.Name}";
                                await LoquiTypeHandler(subFg, fieldAccessor, loqui, generic : null, checkType : false);

                                if (subFg.Count == 0)
                                {
                                    continue;
                                }
                                if (loqui.Singleton ||
                                    !loqui.Nullable)
                                {
                                    fieldFg.AppendLines(subFg);
                                }
                                else
                                {
                                    fieldFg.AppendLine($"if ({accessor}.{loqui.Name}.TryGet(out var {loqui.Name}item))");
                                    using (new BraceWrapper(fieldFg))
                                    {
                                        fieldFg.AppendLines(subFg);
                                    }
                                }
                            }
                        }
                        else if (field is ContainerType cont)
                        {
                            if (!(cont.SubTypeGeneration is LoquiType contLoqui))
                            {
                                continue;
                            }
                            var isMajorRecord = contLoqui.TargetObjectGeneration != null && await contLoqui.TargetObjectGeneration.IsMajorRecord();

                            if (isMajorRecord ||
                                await MajorRecordModule.HasMajorRecords(contLoqui, includeBaseClass: true) != Case.No)
                            {
                                switch (await MajorRecordModule.HasMajorRecords(contLoqui, includeBaseClass: true))
                                {
                                case Case.Yes:
                                    fieldFg.AppendLine($"foreach (var subItem in {accessor}.{field.Name}{(field.Nullable ? ".EmptyIfNull()" : null)})");
                                    using (new BraceWrapper(fieldFg))
                                    {
                                        await LoquiTypeHandler(fieldFg, $"subItem", contLoqui, generic : null, checkType : false);
                                    }
                                    break;

                                case Case.Maybe:
                                    fieldFg.AppendLine($"foreach (var subItem in {accessor}.{field.Name}{(field.Nullable ? ".EmptyIfNull()" : null)}.WhereCastable<{contLoqui.TypeName(getter: false)}, {(getter ? nameof(IMajorRecordGetterEnumerable) : nameof(IMajorRecordEnumerable))}>())");
                                    using (new BraceWrapper(fieldFg))
                                    {
                                        await LoquiTypeHandler(fieldFg, $"subItem", contLoqui, generic : null, checkType : false);
                                    }
                                    break;

                                case Case.No:
                                default:
                                    break;
                                }
                            }
                        }
                        else if (field is DictType dict)
                        {
                            if (dict.Mode != DictMode.KeyedValue)
                            {
                                continue;
                            }
                            if (!(dict.ValueTypeGen is LoquiType dictLoqui))
                            {
                                continue;
                            }
                            var isMajorRecord = dictLoqui.TargetObjectGeneration != null && await dictLoqui.TargetObjectGeneration.IsMajorRecord();

                            if (isMajorRecord ||
                                await MajorRecordModule.HasMajorRecords(dictLoqui, includeBaseClass: true) != Case.No)
                            {
                                switch (await MajorRecordModule.HasMajorRecords(dictLoqui, includeBaseClass: true))
                                {
                                case Case.Yes:
                                    fieldFg.AppendLine($"foreach (var subItem in {accessor}.{field.Name}.Items)");
                                    using (new BraceWrapper(fieldFg))
                                    {
                                        await LoquiTypeHandler(fieldFg, $"subItem", dictLoqui, generic : null, checkType : false);
                                    }
                                    break;

                                case Case.Maybe:
                                    fieldFg.AppendLine($"foreach (var subItem in {accessor}.{field.Name}.Items.WhereCastable<{dictLoqui.TypeName(getter: false)}, {(getter ? nameof(IMajorRecordGetterEnumerable) : nameof(IMajorRecordEnumerable))}>())");
                                    using (new BraceWrapper(fieldFg))
                                    {
                                        await LoquiTypeHandler(fieldFg, $"subItem", dictLoqui, generic : null, checkType : false);
                                    }
                                    break;

                                case Case.No:
                                default:
                                    break;
                                }
                            }
                        }

                        if (fieldFg.Count > 0)
                        {
                            if (field.Nullable)
                            {
                                fg.AppendLine($"if ({field.NullableAccessor(getter: true, Accessor.FromType(field, accessor.ToString()))})");
                            }
                            using (new BraceWrapper(fg, doIt: field.Nullable))
                            {
                                fg.AppendLines(fieldFg);
                            }
                        }
                    }
                    if (fgCount == fg.Count)
                    {
                        fg.AppendLine("yield break;");
                    }
                }
            }
            fg.AppendLine();

            // Generate base overrides
            foreach (var baseClass in obj.BaseClassTrail())
            {
                if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No)
                {
                    using (var args = new FunctionWrapper(fg,
                                                          $"public override IEnumerable<{nameof(IMajorRecordCommon)}{(getter ? "Getter" : null)}> EnumerateMajorRecords"))
                    {
                        args.Add($"{baseClass.Interface(getter: getter)} obj");
                    }
                    using (new BraceWrapper(fg))
                    {
                        using (var args = new ArgsWrapper(fg,
                                                          "EnumerateMajorRecords"))
                        {
                            args.Add($"({obj.Interface(getter: getter)})obj");
                        }
                    }
                    fg.AppendLine();
                }
            }

            using (var args = new FunctionWrapper(fg,
                                                  $"public{overrideStr}IEnumerable<{nameof(IMajorRecordCommonGetter)}> EnumeratePotentiallyTypedMajorRecords"))
            {
                args.Add($"{obj.Interface(getter: getter, internalInterface: true)} obj");
                args.Add($"Type? type");
                args.Add($"bool throwIfUnknown");
            }
            using (new BraceWrapper(fg))
            {
                fg.AppendLine("if (type == null) return EnumerateMajorRecords(obj);");
                fg.AppendLine("return EnumerateMajorRecords(obj, type, throwIfUnknown);");
            }
            fg.AppendLine();

            using (var args = new FunctionWrapper(fg,
                                                  $"public{overrideStr}IEnumerable<{nameof(IMajorRecordCommonGetter)}> EnumerateMajorRecords"))
            {
                args.Add($"{obj.Interface(getter: getter, internalInterface: true)} obj");
                args.Add($"Type type");
                args.Add($"bool throwIfUnknown");
            }
            using (new BraceWrapper(fg))
            {
                if (setter)
                {
                    fg.AppendLine($"foreach (var item in {obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class)}.Instance.EnumerateMajorRecords(obj, type, throwIfUnknown))");
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine("yield return item;");
                    }
                }
                else
                {
                    var fgCount = fg.Count;
                    foreach (var baseClass in obj.BaseClassTrail())
                    {
                        if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No)
                        {
                            fg.AppendLine("foreach (var item in base.EnumerateMajorRecords<TMajor>(obj))");
                            using (new BraceWrapper(fg))
                            {
                                fg.AppendLine("yield return item;");
                            }
                            break;
                        }
                    }

                    fg.AppendLine("switch (type.Name)");
                    using (new BraceWrapper(fg))
                    {
                        var gameCategory = obj.GetObjectData().GameCategory;
                        fg.AppendLine($"case \"{nameof(IMajorRecordCommon)}\":");
                        fg.AppendLine($"case \"{nameof(IMajorRecord)}\":");
                        fg.AppendLine($"case \"{nameof(MajorRecord)}\":");
                        if (gameCategory != null)
                        {
                            fg.AppendLine($"case \"I{gameCategory}MajorRecord\":");
                            fg.AppendLine($"case \"{gameCategory}MajorRecord\":");
                        }
                        using (new DepthWrapper(fg))
                        {
                            fg.AppendLine($"if (!{obj.RegistrationName}.SetterType.IsAssignableFrom(obj.GetType())) yield break;");
                            fg.AppendLine("foreach (var item in this.EnumerateMajorRecords(obj))");
                            using (new BraceWrapper(fg))
                            {
                                fg.AppendLine("yield return item;");
                            }
                            fg.AppendLine("yield break;");
                        }
                        fg.AppendLine($"case \"{nameof(IMajorRecordGetter)}\":");
                        fg.AppendLine($"case \"{nameof(IMajorRecordCommonGetter)}\":");
                        if (gameCategory != null)
                        {
                            fg.AppendLine($"case \"I{gameCategory}MajorRecordGetter\":");
                        }
                        using (new DepthWrapper(fg))
                        {
                            fg.AppendLine("foreach (var item in this.EnumerateMajorRecords(obj))");
                            using (new BraceWrapper(fg))
                            {
                                fg.AppendLine("yield return item;");
                            }
                            fg.AppendLine("yield break;");
                        }

                        Dictionary <object, FileGeneration> generationDict = new Dictionary <object, FileGeneration>();
                        foreach (var field in obj.IterateFields())
                        {
                            FileGeneration fieldGen;
                            if (field is LoquiType loqui)
                            {
                                if (loqui.TargetObjectGeneration.IsListGroup())
                                {
                                    continue;
                                }
                                var isMajorRecord = loqui.TargetObjectGeneration != null && await loqui.TargetObjectGeneration.IsMajorRecord();

                                if (!isMajorRecord &&
                                    await MajorRecordModule.HasMajorRecords(loqui, includeBaseClass: true) == Case.No)
                                {
                                    continue;
                                }

                                if (loqui.TargetObjectGeneration.GetObjectType() == ObjectType.Group)
                                {
                                    fieldGen = generationDict.GetOrAdd(loqui.GetGroupTarget());
                                }
                                else
                                {
                                    fieldGen = generationDict.GetOrAdd(((object)loqui?.TargetObjectGeneration) ?? loqui);
                                }
                            }
                            else if (field is ContainerType cont)
                            {
                                if (!(cont.SubTypeGeneration is LoquiType contLoqui))
                                {
                                    continue;
                                }
                                if (contLoqui.RefType == LoquiType.LoquiRefType.Generic)
                                {
                                    fieldGen = generationDict.GetOrAdd("default:");
                                }
                                else
                                {
                                    fieldGen = generationDict.GetOrAdd(((object)contLoqui?.TargetObjectGeneration) ?? contLoqui);
                                }
                            }
                            else if (field is DictType dict)
                            {
                                if (dict.Mode != DictMode.KeyedValue)
                                {
                                    continue;
                                }
                                if (!(dict.ValueTypeGen is LoquiType dictLoqui))
                                {
                                    continue;
                                }
                                if (dictLoqui.RefType == LoquiType.LoquiRefType.Generic)
                                {
                                    fieldGen = generationDict.GetOrAdd("default:");
                                }
                                else
                                {
                                    fieldGen = generationDict.GetOrAdd(((object)dictLoqui?.TargetObjectGeneration) ?? dictLoqui);
                                }
                            }
                            else
                            {
                                continue;
                            }
                            await ApplyIterationLines(field, fieldGen, accessor, getter);
                        }

                        bool doAdditionlDeepLogic = obj.Name != "ListGroup";

                        if (doAdditionlDeepLogic)
                        {
                            var deepRecordMapping = await MajorRecordModule.FindDeepRecords(obj);

                            foreach (var deepRec in deepRecordMapping)
                            {
                                FileGeneration deepFg = generationDict.GetOrAdd(deepRec.Key);
                                foreach (var field in deepRec.Value)
                                {
                                    await ApplyIterationLines(field, deepFg, accessor, getter, targetObj : deepRec.Key);
                                }
                            }

                            HashSet <string> blackList = new HashSet <string>();
                            foreach (var kv in generationDict)
                            {
                                switch (kv.Key)
                                {
                                case LoquiType loqui:
                                    if (loqui.RefType == LoquiType.LoquiRefType.Generic)
                                    {
                                        // Handled in default case
                                        continue;
                                    }
                                    else
                                    {
                                        fg.AppendLine($"case \"{loqui.Interface(getter: true)}\":");
                                        fg.AppendLine($"case \"{loqui.Interface(getter: false)}\":");
                                        if (loqui.HasInternalGetInterface)
                                        {
                                            fg.AppendLine($"case \"{loqui.Interface(getter: true, internalInterface: true)}\":");
                                        }
                                        if (loqui.HasInternalSetInterface)
                                        {
                                            fg.AppendLine($"case \"{loqui.Interface(getter: false, internalInterface: true)}\":");
                                        }
                                        if (loqui.RefType == LoquiType.LoquiRefType.Interface)
                                        {
                                            blackList.Add(loqui.SetterInterface);
                                        }
                                    }
                                    break;

                                case ObjectGeneration targetObj:
                                    fg.AppendLine($"case \"{targetObj.ObjectName}\":");
                                    fg.AppendLine($"case \"{targetObj.Interface(getter: true)}\":");
                                    fg.AppendLine($"case \"{targetObj.Interface(getter: false)}\":");
                                    if (targetObj.HasInternalGetInterface)
                                    {
                                        fg.AppendLine($"case \"{targetObj.Interface(getter: true, internalInterface: true)}\":");
                                    }
                                    if (targetObj.HasInternalSetInterface)
                                    {
                                        fg.AppendLine($"case \"{targetObj.Interface(getter: false, internalInterface: true)}\":");
                                    }
                                    break;

                                case string str:
                                    if (str != "default:")
                                    {
                                        throw new NotImplementedException();
                                    }
                                    continue;

                                default:
                                    throw new NotImplementedException();
                                }
                                using (new DepthWrapper(fg))
                                {
                                    fg.AppendLines(kv.Value);
                                    fg.AppendLine("yield break;");
                                }
                            }

                            // Generate for major record marker interfaces
                            if (LinkInterfaceModule.ObjectMappings.TryGetValue(obj.ProtoGen.Protocol, out var interfs))
                            {
                                foreach (var interf in interfs)
                                {
                                    if (blackList.Contains(interf.Key))
                                    {
                                        continue;
                                    }
                                    FileGeneration             subFg         = new FileGeneration();
                                    HashSet <ObjectGeneration> passedObjects = new HashSet <ObjectGeneration>();
                                    HashSet <TypeGeneration>   deepObjects   = new HashSet <TypeGeneration>();
                                    foreach (var subObj in interf.Value)
                                    {
                                        var grup = obj.Fields
                                                   .WhereCastable <TypeGeneration, GroupType>()
                                                   .Where(g => g.GetGroupTarget() == subObj)
                                                   .FirstOrDefault();

                                        if (grup != null)
                                        {
                                            subFg.AppendLine($"foreach (var item in EnumerateMajorRecords({accessor}, typeof({grup.GetGroupTarget().Interface(getter: true)}), throwIfUnknown: throwIfUnknown))");
                                            using (new BraceWrapper(subFg))
                                            {
                                                subFg.AppendLine("yield return item;");
                                            }
                                            passedObjects.Add(grup.GetGroupTarget());
                                        }
                                        else if (deepRecordMapping.TryGetValue(subObj, out var deepRec))
                                        {
                                            foreach (var field in deepRec)
                                            {
                                                deepObjects.Add(field);
                                            }
                                        }
                                    }
                                    foreach (var deepObj in deepObjects)
                                    {
                                        await ApplyIterationLines(deepObj, subFg, accessor, getter, blackList : passedObjects);
                                    }
                                    if (!subFg.Empty)
                                    {
                                        fg.AppendLine($"case \"{interf.Key}\":");
                                        using (new BraceWrapper(fg))
                                        {
                                            fg.AppendLine($"if (!{obj.RegistrationName}.SetterType.IsAssignableFrom(obj.GetType())) yield break;");
                                            fg.AppendLines(subFg);
                                            fg.AppendLine("yield break;");
                                        }
                                        fg.AppendLine($"case \"{interf.Key}Getter\":");
                                        using (new BraceWrapper(fg))
                                        {
                                            fg.AppendLines(subFg);
                                            fg.AppendLine("yield break;");
                                        }
                                    }
                                }
                            }
                        }

                        fg.AppendLine("default:");
                        using (new DepthWrapper(fg))
                        {
                            if (generationDict.TryGetValue("default:", out var gen))
                            {
                                fg.AppendLines(gen);
                                fg.AppendLine("yield break;");
                            }
                            else
                            {
                                fg.AppendLine("if (throwIfUnknown)");
                                using (new BraceWrapper(fg))
                                {
                                    fg.AppendLine("throw new ArgumentException($\"Unknown major record type: {type}\");");
                                }
                                fg.AppendLine($"else");
                                using (new BraceWrapper(fg))
                                {
                                    fg.AppendLine("yield break;");
                                }
                            }
                        }
                    }
                }
            }
            fg.AppendLine();

            // Generate base overrides
            foreach (var baseClass in obj.BaseClassTrail())
            {
                if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No)
                {
                    using (var args = new FunctionWrapper(fg,
                                                          $"public override IEnumerable<TMajor> EnumerateMajorRecords<TMajor>"))
                    {
                        args.Add($"{baseClass.Interface(getter: getter)} obj");
                        args.Wheres.Add($"where TMajor : {nameof(IMajorRecordCommon)}{(getter ? "Getter" : null)}");
                    }
                    using (new BraceWrapper(fg))
                    {
                        using (var args = new ArgsWrapper(fg,
                                                          "EnumerateMajorRecords<TMajor>"))
                        {
                            args.Add($"({obj.Interface(getter: getter)})obj");
                        }
                    }
                    fg.AppendLine();
                }
            }
        }
예제 #4
0
        public override async Task GenerateInCommonMixin(ObjectGeneration obj, FileGeneration fg)
        {
            await base.GenerateInCommonMixin(obj, fg);

            var    objData = obj.GetObjectData();
            string gameReleaseStr;

            if (objData.GameReleaseOptions == null)
            {
                gameReleaseStr = $"{nameof(GameRelease)}.{obj.GetObjectData().GameCategory}";
            }
            else
            {
                gameReleaseStr = $"item.GameRelease";
            }

            if (obj.GetObjectType() != ObjectType.Mod)
            {
                return;
            }
            using (var args = new FunctionWrapper(fg,
                                                  $"public static IGroupGetter<T> {nameof(IModGetter.GetTopLevelGroup)}<T>"))
            {
                args.Wheres.Add($"where T : {nameof(IMajorRecordGetter)}");
                args.Add($"this {obj.Interface(getter: true)} obj");
            }
            using (new BraceWrapper(fg))
            {
                using (var args = new ArgsWrapper(fg,
                                                  $"return (IGroupGetter<T>){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup"))
                {
                    args.AddPassArg("obj");
                    args.Add("type: typeof(T)");
                }
            }
            fg.AppendLine();

            using (var args = new FunctionWrapper(fg,
                                                  $"public static IGroupGetter {nameof(IModGetter.GetTopLevelGroup)}"))
            {
                args.Add($"this {obj.Interface(getter: true)} obj");
                args.Add("Type type");
            }
            using (new BraceWrapper(fg))
            {
                using (var args = new ArgsWrapper(fg,
                                                  $"return (IGroupGetter){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup"))
                {
                    args.AddPassArg("obj");
                    args.AddPassArg("type");
                }
            }
            fg.AppendLine();

            using (var args = new FunctionWrapper(fg,
                                                  $"public static IGroup<T> {nameof(IMod.GetTopLevelGroup)}<T>"))
            {
                args.Wheres.Add($"where T : {nameof(IMajorRecord)}");
                args.Add($"this {obj.Interface(getter: false)} obj");
            }
            using (new BraceWrapper(fg))
            {
                using (var args = new ArgsWrapper(fg,
                                                  $"return (IGroup<T>){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup"))
                {
                    args.AddPassArg("obj");
                    args.Add("type: typeof(T)");
                }
            }
            fg.AppendLine();

            using (var args = new FunctionWrapper(fg,
                                                  $"public static IGroup {nameof(IModGetter.GetTopLevelGroup)}"))
            {
                args.Add($"this {obj.Interface(getter: false)} obj");
                args.Add("Type type");
            }
            using (new BraceWrapper(fg))
            {
                using (var args = new ArgsWrapper(fg,
                                                  $"return (IGroup){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup"))
                {
                    args.AddPassArg("obj");
                    args.AddPassArg("type");
                }
            }
            fg.AppendLine();

            using (var args = new FunctionWrapper(fg,
                                                  $"public static void WriteToBinaryParallel"))
            {
                args.Add($"this {obj.Interface(getter: true, internalInterface: false)} item");
                args.Add($"Stream stream");
                args.Add($"{nameof(BinaryWriteParameters)}? param = null");
                args.Add($"{nameof(ParallelWriteParameters)}? parallelParam = null");
            }
            using (new BraceWrapper(fg))
            {
                using (var args = new ArgsWrapper(fg,
                                                  $"{obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.WriteParallel"))
                {
                    args.AddPassArg("item");
                    args.AddPassArg("stream");
                    args.Add($"parallelParam: parallelParam ?? {nameof(ParallelWriteParameters)}.{nameof(ParallelWriteParameters.Default)}");
                    args.Add($"param: param ?? {nameof(BinaryWriteParameters)}.{nameof(BinaryWriteParameters.Default)}");
                    args.Add("modKey: item.ModKey");
                }
            }
            fg.AppendLine();

            using (var args = new FunctionWrapper(fg,
                                                  $"public static void WriteToBinaryParallel"))
            {
                args.Add($"this {obj.Interface(getter: true, internalInterface: false)} item");
                args.Add($"string path");
                args.Add($"{nameof(BinaryWriteParameters)}? param = null");
                args.Add($"{nameof(ParallelWriteParameters)}? parallelParam = null");
                args.Add($"{nameof(IFileSystem)}? fileSystem = null");
            }
            using (new BraceWrapper(fg))
            {
                fg.AppendLine($"param ??= {nameof(BinaryWriteParameters)}.{nameof(BinaryWriteParameters.Default)};");
                fg.AppendLine($"parallelParam ??= {nameof(ParallelWriteParameters)}.{nameof(ParallelWriteParameters.Default)};");
                using (var args = new ArgsWrapper(fg,
                                                  $"var modKey = param.{nameof(BinaryWriteParameters.RunMasterMatch)}"))
                {
                    args.Add("mod: item");
                    args.AddPassArg("path");
                }
                if (obj.GetObjectData().UsesStringFiles)
                {
                    fg.AppendLine($"param.StringsWriter ??= EnumExt.HasFlag((int)item.ModHeader.Flags, (int)ModHeaderCommonFlag.Localized) ? new StringsWriter({gameReleaseStr}, modKey, Path.Combine(Path.GetDirectoryName(path)!, \"Strings\"), {nameof(MutagenEncodingProvider)}.{nameof(MutagenEncodingProvider.Instance)}) : null;");
                    fg.AppendLine("bool disposeStrings = param.StringsWriter != null;");
                }
                fg.AppendLine("using (var stream = fileSystem.GetOrDefault().FileStream.Create(path, FileMode.Create, FileAccess.Write))");
                using (new BraceWrapper(fg))
                {
                    using (var args = new ArgsWrapper(fg,
                                                      $"{obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.WriteParallel"))
                    {
                        args.AddPassArg("item");
                        args.AddPassArg("stream");
                        args.AddPassArg("parallelParam");
                        args.Add($"param: param");
                        args.AddPassArg("modKey");
                    }
                }
                if (obj.GetObjectData().UsesStringFiles)
                {
                    fg.AppendLine("if (disposeStrings)");
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine("param.StringsWriter?.Dispose();");
                    }
                }
            }
            fg.AppendLine();
        }