Bug in saving TSet entries in config ini files

It appears that when serializing out a TSet config object member, the syntax emitted does not match the syntax expected on load. This may require a complex struct type as the set element. The emitted ini looks like:

+LoggingTest=(Category="Foo",VerbosityLevel=VeryVerbose)
+LoggingTest=(Category="Bar",VerbosityLevel=VeryVerbose)

but this is not loadable. Adding an extra set of parenthesis around each entry appears to allow it to load without error. Alternatively, collapsing it to a single line like:

LoggingTest=((Category="Foo",VerbosityLevel=VeryVerbose),(Category="BarNone",VerbosityLevel=VeryVerbose))

also appears to work.

[Attachment Removed]

Steps to Reproduce
Using nDisplay Launch as an example, make the following changes in DisplayClusterLaunchEditorProjectSettings.h:

1) Enable the plugin

2) implement a GetTypeHash function in FDisplayClusterLaunchLoggingConstruct

3) add an extra config member to the end of UDisplayClusterLaunchEditorProjectSettings: make it a TSet<FDisplayClusterLaunchLoggingConstruct>

4) Rebuild and open the editor

5) Add some settings to the new settings field

6) Save and exit the editor

7) Reopen the editor

Notice that the log will contain warnings of the form:

ImportText (LoggingTest): Missing opening parenthesis: Category="Foo",VerbosityLevel=VeryVerbose)

[Attachment Removed]

Hello Matt,

I am not able to observe the behaviour reported. Having added a `TSet<Complex>` to a plugin’s settings (Complex is just two ints), opened the settings in the editor’s preferences and made some edits, and I see the following in `Config/EditorPerProjectUserSettings.ini`;

```

[/Script/Plugin.PluginSettings]

MrTest=(A=99,B=999)

MrTest=(A=5,B=0)

MrTest=(A=4,B=0)

MrTest=(A=3,B=0)

```

There are no `+` ini-command prefixes. If I add them manually then these values _do not_ load anymore. The prefixes do appear if I set the settings as default (in ‘DefaultsEditorPerProjectUserSettings.ini’);

```

[/Script/Plugin.PluginSettings]

+MrTest=(A=99,B=998)

+MrTest=(A=6,B=0)

+MrTest=(A=55,B=0)

```

While the above does match your format, they load into the set just fine. Perhaps your .ini structure is ending up thinking its layered on save and not on load?

-Martin.

[Attachment Removed]

Hi Matt. Funny how small the world turns out to be :slight_smile:

It turns out I do get that error message, yes (but not to VS’ debug pane where I was looking). The issue ultimately stems from config save writing out set elements individually, and first trying this on config load;

Obj.cpp;
bool ProcessSetProperty(...) {
  [snip]
  // Try to import the config value as an entire set first
  const TCHAR* SetImportResult =
    SetProperty->ImportText_Direct(*ListString, TempSet, ActiveObject, PortFlags);

`ImportText_Direct()` expects an entire set surrounded by parentheses; `(4,9,3)`. In config’s single-element case, structs look like a set to `ImportText_Direct()` so it consumes the opening `(` and sends `A=5,B=6)` to the `FStructProperty` to parse. This raises the “missing parenthesis” error.

I don’t know what the fix is as `(` is ambiguous (e.g. is `()` an empty set, or a single default/empty struct set element?. `(())` an entire one element set or a ‘struct with a struct member’ element?

A suitable workaround for now might be to gate the above call behind an `if (CastField<FStructProperty>(ElementProp) == nullptr)`.

-Martin.

[Attachment Removed]

The erroneous error log has been address in 58798700 like this;

Obj.cpp / ProcessSetProperty();
 
  FOutputDeviceNull NullOut;
  const TCHAR* SetImportResult =
    SetProperty->ImportText_Direct(*ListString, TempSet, ActiveObject, PortFlags, &NullOut);

-Martin.

[Attachment Removed]

Hey Martin, nice to hear from you!

You’re right, I was mistaken about the failure to load. They do end up loading, but they also still emit the warning about the missing parenthesis. The behavior does seem to depend on whether the UCLASS is marked ‘defaultconfig’ or not.

Are you able to reproduce the warning at all? In your case, it should look like:

ImportText (LoggingTest): Missing opening parenthesis: A=99,B=998)

[Attachment Removed]

Great, thank you!

[Attachment Removed]