I’ve been working on an alternative to UE4’s data table system but when converting a CSV string containing a array or map, the string conversion can get messed up if it contains comma’s anywhere else except between the elements. So I looked at how UE4’s data tables handle it and found that it uses the ImportText function on f and u properties. The problem is I can’t get it to populate the TMap property I use it on.
Photo of what strings I’ve tried passing into it and how I formatted them.
Test 1 In the first test I tried to apply the same method I used for the string test which resulted in the fall back else statement being triggered
//Test struct
USTRUCT(Blueprintable)
struct FMyStruct
{
GENERATED_BODY()
public:
UPROPERTY()
FString StrValue;
UPROPERTY()
TMap<FString, FString> MapValue;
};
void UMyTestFunctionLibrary::MyTMapTest(FString TMapString)
{
FMyStruct MyStruct;
//Loop through properties
for (TFieldIterator<FProperty> It(MyStruct.StaticStruct()); It; ++It)
{
//String value assignment set test
if (It->GetName() == "StrValue")
{
FStrProperty* Str = Cast<FStrProperty>(*It);
if (Str)
{
Str->ImportText(TEXT("BB"), Str->ContainerPtrToValuePtr<void*>(&MyStruct), EPropertyPortFlags::PPF_None, nullptr);
}
}
//Map value assignment set test
else if (It->GetName() == "MapValue")
{
FMapProperty* Str = Cast<FMapProperty>(*It);
if (Str)
{
Str->ImportText(*TMapString, Str->ContainerPtrToValuePtr<void*>(&MyStruct), EPropertyPortFlags::PPF_Delimited, nullptr);
}
}
}
//Test string contents
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, MyStruct.StrValue);
//Test map contents
if (MyStruct.MapValue.Contains("Key"))
{
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, MyStruct.MapValue["Key"]);
}
//Else fall back
else
{
TArray<FString> Arr;
MyStruct.MapValue.GetKeys(Arr);
for (FString& K: Arr)
{
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, K);
}
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("Fin"));
}
}
Test 2 In the second example I tried copying how its done in FDataTableImporterCSV ReadTable() function, which also resulted in the fall back being triggered when attempting to access
//Test struct
USTRUCT(Blueprintable)
struct FMyStruct
{
GENERATED_BODY()
public:
UPROPERTY()
FString StrValue;
UPROPERTY()
TMap<FString, FString> MapValue;
};
void UMyTestFunctionLibrary::MyTMapTest(FString TMapString) {
FMyStruct MyStruct;
//Loop through properties
for (TFieldIterator<FProperty> It(MyStruct.StaticStruct()); It; ++It)
{
//Assign string property test
if (It->GetName() == "StrValue")
{
FStrProperty* Str = Cast<FStrProperty>(*It);
if (Str)
{
Str->ImportText(TEXT("BB"), Str->ContainerPtrToValuePtr<void*>(&MyStruct), EPropertyPortFlags::PPF_None, nullptr);
}
}
//Assign map property test
else if (It->GetName() == "MapValue")
{
UScriptStruct* Var = MyStruct.StaticStruct();
uint8* RowData = (uint8*)FMemory::Malloc(Var->GetStructureSize());
Var->InitializeStruct(RowData);
DataTableUtils::AssignStringToProperty(TMapString, *It, RowData);
}
}
//Test string contents
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, MyStruct.StrValue);
//Test map contents
if (MyStruct.MapValue.Contains("Key"))
{
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, MyStruct.MapValue["Key"]);
}
//Fall back test
else
{
TArray<FString> Arr;
MyStruct.MapValue.GetKeys(Arr);
for (FString& K: Arr)
{
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, K);
}
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("Fin"));
}
}