From aa54a1034aeaa0ea5a6ab5e7ce06a3b3f68b3dd8 Mon Sep 17 00:00:00 2001 From: Sun Serega Date: Thu, 28 Mar 2024 11:56:42 +0100 Subject: [PATCH] cleanup TODO's --- Packing/Template/LowLvl/BinUtils.pas | 4 +- Packing/Template/LowLvl/Essentials.pas | 2 - Packing/Template/LowLvl/NamedItemHelpers.pas | 7 +- Packing/Template/LowLvl/ParData.pas | 6 +- Utils/TypeMagic.pas | 68 ++++++++++++++++++++ 5 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 Utils/TypeMagic.pas diff --git a/Packing/Template/LowLvl/BinUtils.pas b/Packing/Template/LowLvl/BinUtils.pas index 5104ca15..28fe835a 100644 --- a/Packing/Template/LowLvl/BinUtils.pas +++ b/Packing/Template/LowLvl/BinUtils.pas @@ -3,6 +3,7 @@ {$savepcu false} //TODO #3057 uses System; +uses '..\..\..\Utils\TypeMagic'; type BinReader = System.IO.BinaryReader; @@ -51,8 +52,7 @@ function ReadEnum(self: BinReader): T; extensionmethod; if typeof(T).GetEnumUnderlyingType <> typeof(Int32) then raise new NotSupportedException; {$endif DEBUG} - //TODO #3056: as object - Result := T(self.ReadInt32() as object); + Result := ConvertTo&.FromUnchecked(self.ReadInt32()); end; end. \ No newline at end of file diff --git a/Packing/Template/LowLvl/Essentials.pas b/Packing/Template/LowLvl/Essentials.pas index 6317b55a..fece54b2 100644 --- a/Packing/Template/LowLvl/Essentials.pas +++ b/Packing/Template/LowLvl/Essentials.pas @@ -1,7 +1,5 @@ unit Essentials; -{$savepcu false} //TODO #3058 - interface uses System; diff --git a/Packing/Template/LowLvl/NamedItemHelpers.pas b/Packing/Template/LowLvl/NamedItemHelpers.pas index b9cf567d..2bd2ccf9 100644 --- a/Packing/Template/LowLvl/NamedItemHelpers.pas +++ b/Packing/Template/LowLvl/NamedItemHelpers.pas @@ -50,11 +50,8 @@ Otp($'WARNING: {kvp.Key} referenced itself'); end; - foreach var kvp in all_unused_reports do - kvp.Value(); - //TODO #3061: Заменить предыдущий цикл -// foreach var rep in all_unused_reports.Values do -// rep.Invoke(); + foreach var rep in all_unused_reports.values do + rep.Invoke(); all_unused_reports := nil; end; diff --git a/Packing/Template/LowLvl/ParData.pas b/Packing/Template/LowLvl/ParData.pas index f1af5cbe..822ccba0 100644 --- a/Packing/Template/LowLvl/ParData.pas +++ b/Packing/Template/LowLvl/ParData.pas @@ -27,8 +27,7 @@ interface private static inst := new ParArrSizeNotArray; public static property Instance: ParArrSizeNotArray read inst; - //TODO #3063: use Instance - static constructor := DefineLoader(PASK_NotArray, br->inst); + static constructor := DefineLoader(PASK_NotArray, br->Instance); end; @@ -39,8 +38,7 @@ interface private static inst := new ParArrSizeArbitrary; public static property Instance: ParArrSizeArbitrary read inst; - //TODO #3063: use Instance - static constructor := DefineLoader(PASK_Arbitrary, br->inst); + static constructor := DefineLoader(PASK_Arbitrary, br->Instance); end; diff --git a/Utils/TypeMagic.pas b/Utils/TypeMagic.pas new file mode 100644 index 00000000..fc72491a --- /dev/null +++ b/Utils/TypeMagic.pas @@ -0,0 +1,68 @@ +unit TypeMagic; + +interface + +type + + {$region Convert} + + ConvertTo = sealed class + + private constructor := raise new System.InvalidOperationException; + + public static function FromChecked(o: T2): T; + public static function FromUnchecked(o: T2): T; + public static function From(o: T2; checked: boolean := true) := + if checked then FromChecked(o) else FromUnchecked(o); + + end; + + {$endregion Convert} + +implementation + +uses System.Linq.Expressions; + +{$region Convert} + +type ConvertCache = sealed class + + private constructor := raise new System.InvalidOperationException; + + public static checked, unchecked: T2->T1; + private static function MakeFunc(conv: (Expression,System.Type)->Expression): T2->T1; + begin + try + var p := Expression.Parameter(typeof(T2)); + var c := conv(p, typeof(T1)); + var l := Expression.Lambda&>(c, p); + Result := l.Compile(); + except + on e: Exception do + begin + Result := o-> + begin + Result := default(T1); + raise new System.InvalidCastException($'Failed to make [{TypeToTypeName(typeof(T2))}]=>[{TypeToTypeName(typeof(T1))}] conversion', e); + end; + exit; + end; + end; + + end; + static constructor; + begin + checked := MakeFunc(Expression.ConvertChecked); + unchecked := MakeFunc(Expression.Convert); + end; + +end; + +static function ConvertTo.FromChecked(o: T2) := + ConvertCache&.checked(o); +static function ConvertTo.FromUnchecked(o: T2) := + ConvertCache&.unchecked(o); + +{$endregion Convert} + +end. \ No newline at end of file