public override async Task GenerateWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int?currentPosition, string passedLengthAccessor, DataType dataType) { LoquiType loqui = typeGen as LoquiType; var data = typeGen.GetFieldData(); switch (data.BinaryOverlayFallback) { case BinaryGenerationType.Normal: break; case BinaryGenerationType.NoGeneration: return; case BinaryGenerationType.Custom: await this.Module.CustomLogic.GenerateForCustomFlagWrapperFields( fg, objGen, typeGen, dataAccessor, currentPosition, passedLengthAccessor, dataType); return; default: throw new NotImplementedException(); } string DataAccessor(Accessor accessor, string positionStr, string lenStr) { if (objGen.GetObjectType() == ObjectType.Mod) { return($"{nameof(BinaryOverlay)}.{nameof(BinaryOverlay.LockExtractMemory)}({accessor}, {positionStr}, {lenStr})"); } else { return($"{accessor}.Slice({positionStr})"); } } string recConverter = $"default({nameof(RecordTypeConverter)})"; if (loqui.GetFieldData()?.RecordTypeConverter != null && loqui.GetFieldData().RecordTypeConverter.FromConversions.Count > 0) { recConverter = $"{objGen.RegistrationName}.{loqui.Name}Converter"; } var isRequiredRecord = !loqui.Nullable && data.HasTrigger; if (dataType == null) { if (loqui.GetFieldData()?.HasTrigger ?? false) { if (loqui.TargetObjectGeneration.IsTypelessStruct()) { if (loqui.Singleton || isRequiredRecord) { fg.AppendLine($"private {loqui.Interface(getter: true, internalInterface: true)}? _{typeGen.Name};"); } else if (loqui.Nullable) { fg.AppendLine($"public {loqui.Interface(getter: true, internalInterface: true)}? {typeGen.Name} {{ get; private set; }}"); } } else { var severalSubTypes = data.GenerationTypes .Select(i => i.Value) .WhereCastable <TypeGeneration, LoquiType>() .Where(loqui => !loqui?.TargetObjectGeneration?.Abstract ?? true) .CountGreaterThan(1); if (severalSubTypes) { fg.AppendLine($"private {nameof(RecordType)} _{typeGen.Name}Type;"); } fg.AppendLine($"private {GetLocationObjectString(objGen)}? _{typeGen.Name}Location;"); using (new LineWrapper(fg)) { if (loqui.IsNullable) { fg.Append($"public "); } else { fg.Append($"private "); } fg.Append($"{loqui.Interface(getter: true, internalInterface: true)}{(typeGen.CanBeNullable(getter: true) ? "?" : null)} "); if (!loqui.IsNullable || isRequiredRecord) { fg.Append("_"); } fg.Append($"{typeGen.Name}"); if (!severalSubTypes) { fg.Append($" => _{typeGen.Name}Location.HasValue ? "); fg.Append($"{this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({DataAccessor(dataAccessor, $"_{typeGen.Name}Location!.Value.Min", $"_{typeGen.Name}Location!.Value.Max")}, _package), _package"); if (!recConverter.StartsWith("default(")) { fg.Append($", {recConverter}"); } fg.Append($") "); fg.Append($": default;"); } } if (severalSubTypes) { using (new BraceWrapper(fg)) { fg.AppendLine("get"); using (new BraceWrapper(fg)) { fg.AppendLine($"if (!_{typeGen.Name}Location.HasValue) return default;"); fg.AppendLine($"switch (_{typeGen.Name}Type.TypeInt)"); using (new BraceWrapper(fg)) { foreach (var gen in data.GenerationTypes) { if (!(gen.Value is LoquiType subLoq)) { continue; } if (subLoq?.TargetObjectGeneration?.Abstract ?? false) { continue; } foreach (var trigger in gen.Key) { fg.AppendLine($"case 0x{trigger.TypeInt.ToString("X")}: // {trigger.Type}"); } using (new DepthWrapper(fg)) using (new LineWrapper(fg)) { fg.Append($"return {this.Module.BinaryOverlayClassName(subLoq)}.{subLoq.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({DataAccessor(dataAccessor, $"_{subLoq.Name}Location!.Value.Min", $"_{subLoq.Name}Location!.Value.Max")}, _package), _package"); if (!loqui.Singleton) { fg.Append($", {recConverter}"); } fg.Append($");"); } } fg.AppendLine("default:"); using (new DepthWrapper(fg)) { fg.AppendLine("throw new ArgumentException();"); } } } } } } } else { if (!loqui.Singleton) { fg.AppendLine($"public {loqui.Interface(getter: true, internalInterface: true)} {typeGen.Name} => {this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({dataAccessor}.Slice({passedLengthAccessor ?? "0x0"}), _package), _package, {recConverter});"); } else { fg.AppendLine($"private {loqui.Interface(getter: true, internalInterface: true)} _{typeGen.Name} {{ get; private set; }}"); } } } else { isRequiredRecord = true; DataBinaryTranslationGeneration.GenerateWrapperExtraMembers(fg, dataType, objGen, typeGen, passedLengthAccessor); fg.AppendLine($"private {loqui.Interface(getter: true, internalInterface: true)}? _{typeGen.Name} => _{typeGen.Name}_IsSet ? {this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({DataAccessor(dataAccessor, $"_{typeGen.Name}Location", null)}, _package), _package) : default;"); } if (loqui.Singleton || isRequiredRecord) { fg.AppendLine($"public {loqui.Interface(getter: true, internalInterface: true)} {typeGen.Name} => _{typeGen.Name} ?? new {loqui.DirectTypeName}({(loqui.ThisConstruction ? "this" : null)});"); } }