5#include "CoreMinimal.h"
6#include "UObject/NoExportTypes.h"
10template <
typename ArrayType>
14 static bool IsEqual(
const TArray<ArrayType>& ThisArray,
const TArray<ArrayType>& OtherArray,
15 const FString& PropertyName, FString& OutError,
const bool bIsPrimitive,
16 std::function<FString(
const ArrayType&)> GetArrayTypeAsString,
17 std::function<
bool(
const ArrayType& FirstValue,
const ArrayType& SecondValue, FString& ComparisonErrorMessage)> AreValuesEqual)
20 auto AreValuesEqualWithoutMessage = [&AreValuesEqual](
const ArrayType& FirstValue,
const ArrayType& SecondValue) ->
bool
22 FString DiscardMessage;
23 return AreValuesEqual(FirstValue, SecondValue, DiscardMessage);
26 if (FDlgHelper::IsArrayEqual<ArrayType>(ThisArray, OtherArray, AreValuesEqualWithoutMessage) ==
false)
29 if (ThisArray.Num() != OtherArray.Num())
31 OutError += FString::Printf(
32 TEXT(
"\tThis.%s.Num (%d) != Other.%s.Num (%d)\n"),
33 *PropertyName, ThisArray.Num(), *PropertyName, OtherArray.Num());
37 for (int32 Index = 0; Index < ThisArray.Num() && Index < OtherArray.Num(); Index++)
40 FString ComparisonErrorMessage;
41 if (!AreValuesEqual(ThisArray[Index], OtherArray[Index], ComparisonErrorMessage))
45 OutError += FString::Printf(TEXT(
"\tThis.%s[%d] (%d) != Other.%s[%d] (%d)\n"),
46 *PropertyName, Index, *GetArrayTypeAsString(ThisArray[Index]), *PropertyName, Index, *GetArrayTypeAsString(OtherArray[Index]));
50 OutError += FString::Printf(TEXT(
"\tThis.%s[%d] != Other.%s[%d] |message = %s|\n"),
51 *PropertyName, Index, *PropertyName, Index, *ComparisonErrorMessage);
62template <
typename ArrayType>
66 static bool IsEqual(
const TArray<ArrayType>& ThisArray,
const TArray<ArrayType>& OtherArray,
67 const FString& PropertyName, FString& OutError,
68 std::function<FString(
const ArrayType&)> GetArrayTypeAsString)
71 [](
const ArrayType& FirstValue,
const ArrayType& SecondValue, FString& ComparisonErrorMessage) ->
bool
73 return FirstValue == SecondValue;
83 static bool IsEqual(
const TArray<float>& ThisArray,
const TArray<float>& OtherArray,
84 const FString& PropertyName, FString& OutError,
85 std::function<FString(
const float&)> GetArrayTypeAsString)
88 [](
const float& FirstValue,
const float& SecondValue, FString& ComparisonErrorMessage) ->
bool
90 return FMath::IsNearlyEqual(FirstValue, SecondValue, KINDA_SMALL_NUMBER);
97template <
typename SetType>
101 static bool IsEqual(
const TSet<SetType>& ThisSet,
const TSet<SetType>& OtherSet,
102 const FString& PropertyName, FString& OutError,
103 std::function<FString(
const SetType&)> GetSetTypeAsString)
105 bool bIsEqual =
true;
106 if (FDlgHelper::IsSetEqual<SetType>(ThisSet, OtherSet) ==
false)
109 if (ThisSet.Num() != OtherSet.Num())
111 OutError += FString::Printf(
112 TEXT(
"\tThis.%s.Num (%d) != Other.%s.Num (%d)\n"),
113 *PropertyName, ThisSet.Num(), *PropertyName, OtherSet.Num());
117 const TSet<SetType> NotInOther = ThisSet.Difference(OtherSet);
118 OutError += FString::Printf(
119 TEXT(
"\tNotInOther = This.%s - Other.%s is of length = %d\n"),
120 *PropertyName, *PropertyName, NotInOther.Num());
122 FString NotInOtherString;
123 for (
const SetType& ValueInOther : NotInOther)
125 NotInOtherString += FString::Printf(TEXT(
"%s,"), *GetSetTypeAsString(ValueInOther));
127 OutError += FString::Printf(TEXT(
"\tNotInOther = {%s}\n"), *NotInOtherString);
134template <
typename KeyType,
typename ValueType>
138 static bool IsEqual(
const TMap<KeyType, ValueType>& ThisMap,
const TMap<KeyType, ValueType>& OtherMap,
139 const FString& PropertyName, FString& OutError,
const bool bIsValuePrimitive,
140 std::function<FString(
const KeyType&)> GetKeyTypeAsString,
141 std::function<FString(
const ValueType&)> GetValueTypeAsString,
142 std::function<
bool(
const ValueType& FirstValue,
const ValueType& SecondValue, FString& ComparisonErrorMessage)> AreValuesEqual)
144 bool bIsEqual =
true;
145 auto AreValuesEqualWithoutMessage = [&AreValuesEqual](
const ValueType& FirstValue,
const ValueType& SecondValue) ->
bool
147 FString DiscardMessage;
148 return AreValuesEqual(FirstValue, SecondValue, DiscardMessage);
151 if (FDlgHelper::IsMapEqual<KeyType, ValueType>(ThisMap, OtherMap, AreValuesEqualWithoutMessage) ==
false)
154 if (ThisMap.Num() != OtherMap.Num())
156 OutError += FString::Printf(
157 TEXT(
"\tThis.%s.Num (%d) != Other.%s.Num (%d)\n"),
158 *PropertyName, ThisMap.Num(), *PropertyName, OtherMap.Num());
162 int32 NumKeysNotInOther = 0;
163 FString KeysNotInOtherString;
164 FString ValuesThatDifferString;
165 const bool OtherMapIsEmpty = OtherMap.Num() == 0;
166 for (
const auto& ThisElem : ThisMap)
168 const ValueType* OtherMapValue = OtherMap.Find(ThisElem.Key);
169 if (OtherMapValue !=
nullptr)
171 FString ComparisonErrorMessage;
172 if (!AreValuesEqual(ThisElem.Value, *OtherMapValue, ComparisonErrorMessage))
174 if (bIsValuePrimitive)
176 ValuesThatDifferString += FString::Printf(
177 TEXT(
"\tThis.%s[key] (%s) != Other.%s[key] (%s). Key = (%s)\n"),
178 *PropertyName, *GetValueTypeAsString(ThisElem.Value),
179 *PropertyName, *GetValueTypeAsString(*OtherMapValue),
180 *GetKeyTypeAsString(ThisElem.Key));
184 ValuesThatDifferString += FString::Printf(
185 TEXT(
"\tThis.%s[key] (%s) != Other.%s[key] (%s). Key = (%s). |Message = %s|\n"),
186 *PropertyName, *GetValueTypeAsString(ThisElem.Value),
187 *PropertyName, *GetValueTypeAsString(*OtherMapValue),
188 *GetKeyTypeAsString(ThisElem.Key), *ComparisonErrorMessage);
194 KeysNotInOtherString += FString::Printf(TEXT(
"%s,"), *GetKeyTypeAsString(ThisElem.Key));
202 OutError += FString::Printf(TEXT(
"\tOther.%s IS EMPTY\n"), *PropertyName);
206 FString OtherStringKeys;
207 for (
const auto& OtherElem : OtherMap)
209 OtherStringKeys += FString::Printf(TEXT(
"%s,"), *GetKeyTypeAsString(OtherElem.Key));
211 OutError += FString::Printf(TEXT(
"\tOther.%s KEYS (Num = %d) = {%s}\n"),
212 *PropertyName, OtherMap.Num(), *OtherStringKeys);
215 OutError += FString::Printf(TEXT(
"\tKeys that ONLY exist in This.%s (Num = %d) = {%s}\n"),
216 *PropertyName, NumKeysNotInOther, *KeysNotInOtherString);
217 OutError += FString::Printf(TEXT(
"\tValues that differ:\n%s\n"), *ValuesThatDifferString);
226template <
typename KeyType,
typename ValueType>
230 static bool IsEqual(
const TMap<KeyType, ValueType>& ThisMap,
const TMap<KeyType, ValueType>& OtherMap,
231 const FString& PropertyName, FString& OutError,
232 std::function<FString(
const KeyType&)> GetKeyTypeAsString,
233 std::function<FString(
const ValueType&)> GetValueTypeAsString)
236 [](
const ValueType& FirstMapValue,
const ValueType& SecondMapValue, FString& ComparisonErrorMessage) ->
bool
238 return FirstMapValue == SecondMapValue;
244template <
typename KeyType>
248 static bool IsEqual(
const TMap<KeyType, float>& ThisMap,
const TMap<KeyType, float>& OtherMap,
249 const FString& PropertyName, FString& OutError,
250 std::function<FString(
const KeyType&)> GetKeyTypeAsString,
251 std::function<FString(
const float&)> GetValueTypeAsString)
254 [](
const float& FirstMapValue,
const float& SecondMapValue, FString& ComparisonErrorMessage) ->
bool
256 return FMath::IsNearlyEqual(FirstMapValue, SecondMapValue, KINDA_SMALL_NUMBER);
269 template <
typename ValueType>
272 for (
const auto& Elem : ThisMap)
275 check((
void*)(*Elem.Key) !=
nullptr);
276 Elem.Key.CheckInvariants();
280 template <
typename SetType>
281 static bool IsSetEqual(
const TSet<SetType>& ThisSet,
const TSet<SetType>& OtherSet,
282 const FString& PropertyName, FString& OutError, std::function<FString(
const SetType&)> GetSetTypeAsString)
287 template <
typename KeyType,
typename ValueType>
288 static bool IsPrimitiveMapEqual(
const TMap<KeyType, ValueType>& ThisMap,
const TMap<KeyType, ValueType>& OtherMap,
289 const FString& PropertyName, FString& OutError,
290 std::function<FString(
const KeyType&)> GetKeyTypeAsString,
291 std::function<FString(
const ValueType&)> GetValueTypeAsString)
296 template <
typename KeyType,
typename ValueType>
298 const FString& PropertyName, FString& OutError,
299 std::function<FString(
const KeyType&)> GetKeyTypeAsString,
300 std::function<FString(
const ValueType&)> GetValueTypeAsString)
303 [](
const ValueType& FirstMapValue,
const ValueType& SecondMapValue, FString& ComparisonErrorMessage) ->
bool
305 return FirstMapValue.IsEqual(SecondMapValue, ComparisonErrorMessage);
309 template <
typename KeyType,
typename ValueType>
311 const FString& PropertyName, FString& OutError,
312 std::function<FString(
const KeyType&)> GetKeyTypeAsString)
315 [](
const auto*
Object) -> FString
319 [](
const auto* FirstMapValue,
const auto* SecondMapValue, FString& ComparisonErrorMessage) ->
bool
321 if (FirstMapValue ==
nullptr)
323 ComparisonErrorMessage = TEXT(
"FirstMapValue is nullptr");
324 return SecondMapValue ==
nullptr;
326 return FirstMapValue->IsEqual(SecondMapValue, ComparisonErrorMessage);
330 template <
typename ArrayType>
332 const FString& PropertyName, FString& OutError, std::function<FString(
const ArrayType&)> GetArrayTypeAsString)
337 template <
typename ArrayType>
339 const FString& PropertyName, FString& OutError)
342 [](
const ArrayType& Value) -> FString
344 return TEXT(
"IsComplexArrayEqual SHOULD NOT SEE THIS");
346 [](
const ArrayType& FirstValue,
const ArrayType& SecondValue, FString& ComparisonErrorMessage) ->
bool
348 return FirstValue.IsEqual(SecondValue, ComparisonErrorMessage);
352 template <
typename ArrayType>
354 const FString& PropertyName, FString& OutError)
357 [](
const auto* Value) -> FString
359 return Value ? Value->ToString() :
"";
361 [](
const auto* FirstValue,
const auto* SecondValue, FString& ComparisonErrorMessage) ->
bool
363 if (FirstValue ==
nullptr)
365 ComparisonErrorMessage = TEXT(
"FirstValue is nullptr");
366 return SecondValue ==
nullptr;
368 return FirstValue->IsEqual(SecondValue, ComparisonErrorMessage);
374 static std::function<FString(
const FName&)>
NameToString;
static FString GetFullNameFromObject(const UObject *Object)
static bool IsEqual(const TArray< ArrayType > &ThisArray, const TArray< ArrayType > &OtherArray, const FString &PropertyName, FString &OutError, const bool bIsPrimitive, std::function< FString(const ArrayType &)> GetArrayTypeAsString, std::function< bool(const ArrayType &FirstValue, const ArrayType &SecondValue, FString &ComparisonErrorMessage)> AreValuesEqual)
static bool IsEqual(const TArray< float > &ThisArray, const TArray< float > &OtherArray, const FString &PropertyName, FString &OutError, std::function< FString(const float &)> GetArrayTypeAsString)
static bool IsEqual(const TArray< ArrayType > &ThisArray, const TArray< ArrayType > &OtherArray, const FString &PropertyName, FString &OutError, std::function< FString(const ArrayType &)> GetArrayTypeAsString)
static bool IsEqual(const TMap< KeyType, float > &ThisMap, const TMap< KeyType, float > &OtherMap, const FString &PropertyName, FString &OutError, std::function< FString(const KeyType &)> GetKeyTypeAsString, std::function< FString(const float &)> GetValueTypeAsString)
static bool IsEqual(const TMap< KeyType, ValueType > &ThisMap, const TMap< KeyType, ValueType > &OtherMap, const FString &PropertyName, FString &OutError, std::function< FString(const KeyType &)> GetKeyTypeAsString, std::function< FString(const ValueType &)> GetValueTypeAsString)
static bool IsEqual(const TMap< KeyType, ValueType > &ThisMap, const TMap< KeyType, ValueType > &OtherMap, const FString &PropertyName, FString &OutError, const bool bIsValuePrimitive, std::function< FString(const KeyType &)> GetKeyTypeAsString, std::function< FString(const ValueType &)> GetValueTypeAsString, std::function< bool(const ValueType &FirstValue, const ValueType &SecondValue, FString &ComparisonErrorMessage)> AreValuesEqual)
static bool IsEqual(const TSet< SetType > &ThisSet, const TSet< SetType > &OtherSet, const FString &PropertyName, FString &OutError, std::function< FString(const SetType &)> GetSetTypeAsString)
static std::function< FString(const FName &) NameToString)
static std::function< FString(const int32 &) Int32ToString)
static bool IsComplexArrayEqual(const TArray< ArrayType > &ThisArray, const TArray< ArrayType > &OtherArray, const FString &PropertyName, FString &OutError)
static std::function< FString(const FVector &) VectorToString)
static bool IsPrimitiveMapEqual(const TMap< KeyType, ValueType > &ThisMap, const TMap< KeyType, ValueType > &OtherMap, const FString &PropertyName, FString &OutError, std::function< FString(const KeyType &)> GetKeyTypeAsString, std::function< FString(const ValueType &)> GetValueTypeAsString)
static bool IsComplexPointersMapEqual(const TMap< KeyType, ValueType * > &ThisMap, const TMap< KeyType, ValueType * > &OtherMap, const FString &PropertyName, FString &OutError, std::function< FString(const KeyType &)> GetKeyTypeAsString)
static std::function< FString(const float &) FloatToString)
static bool IsComplexPointerArrayEqual(const TArray< ArrayType * > &ThisArray, const TArray< ArrayType * > &OtherArray, const FString &PropertyName, FString &OutError)
static std::function< FString(const FString &) StringToString)
static bool IsPrimitiveArrayEqual(const TArray< ArrayType > &ThisArray, const TArray< ArrayType > &OtherArray, const FString &PropertyName, FString &OutError, std::function< FString(const ArrayType &)> GetArrayTypeAsString)
static bool IsComplexMapValueEqual(const TMap< KeyType, ValueType > &ThisMap, const TMap< KeyType, ValueType > &OtherMap, const FString &PropertyName, FString &OutError, std::function< FString(const KeyType &)> GetKeyTypeAsString, std::function< FString(const ValueType &)> GetValueTypeAsString)
static std::function< FString(const FColor &) ColorToString)
static bool IsSetEqual(const TSet< SetType > &ThisSet, const TSet< SetType > &OtherSet, const FString &PropertyName, FString &OutError, std::function< FString(const SetType &)> GetSetTypeAsString)
static void CheckMapStringKeyInvariants(const TMap< FString, ValueType > &ThisMap)
static std::function< FString(const int64 &) Int64ToString)