ONLINE_JSON_SERIALIZE_SERIALIZABLE not working as expected

In the Engine\Source\Runtime\Online\OnlineSubsystem\Public\OnlineJsonSerializer.h file there are multiple #define statements. This one is not working as expected when trying to read the object:

#define ONLINE_JSON_SERIALIZE_SERIALIZABLE(JsonName, JsonValue) \
		JsonValue.Serialize(Serializer)

So I have taken the liberty of modifying it (and renaming it) to the following that works for both reading and writing these serializable JSON Objects:

#define ONLINE_JSON_SERIALIZE_OBJECT(JsonName, JsonSerializableObject) \
	/* Process the JsonName field differently because it is an object, no other macro seems to work */ \
	if (Serializer.IsLoading()) \
	{ \
		/* Read in the value from the JsonName field */ \
		if (Serializer.GetObject()->HasTypedField<EJson::Object>(JsonName)) \
		{ \
			TSharedPtr<FJsonObject> JsonObj = Serializer.GetObject()->GetObjectField(JsonName); \
			if (JsonObj.IsValid()) \
			{ \
				JsonSerializableObject.FromJson(JsonObj); \
			} \
		} \
	} \
	else \
	{ \
		/* Write the value to the JsonName field */ \
		Serializer.StartObject(JsonName); \
		JsonSerializableObject.Serialize(Serializer); \
		Serializer.EndObject(); \
	}

Would it be possible to get this included into the base engine source code as I think it is a very handy feature to have.

For instance I have two FOnlineJsonSerializable objects and one is contained within the other. This now allows me to do simple things like the following:

struct FJsonServerSettings : public FOnlineJsonSerializable
{
...
	BEGIN_ONLINE_JSON_SERIALIZER
	ONLINE_JSON_SERIALIZE("name", ServerName);
	ONLINE_JSON_SERIALIZE("ver", ServerVersion);
	ONLINE_JSON_SERIALIZE("motd", ServerMessageOfTheDay);
	ONLINE_JSON_SERIALIZE("players", PlayersOnline);
	END_ONLINE_JSON_SERIALIZER
};
class FJsonInternetSession : public FOnlineJsonSerializable
{
...
	/** Settings for this server's registration */
	FJsonServerSettings ServerSettings;

	// FJsonSerializable
	BEGIN_ONLINE_JSON_SERIALIZER
	ONLINE_JSON_SERIALIZE("ip", ServerIP);
	ONLINE_JSON_SERIALIZE("port", ServerPort);
	ONLINE_JSON_SERIALIZE("name", ServerName);
	ONLINE_JSON_SERIALIZE_OBJECT("settings", ServerSettings);
	END_ONLINE_JSON_SERIALIZER
};

Note that the ServerSettings object can now be read and written to from within this class as if it were a member of this JsonObject.

Hi ,

If you have a source code change that you would like to be considered for inclusion in the Engine, have you considered submitting a pull request on GitHub?

I was never sure how to do that, seems fairly easy. I’ll have to do that as I think this feature is very handy. I’ll have to also consider doing that from now on to fix and resolve some of the bugs I find in the engine rather than reporting them here. Thanks !
github creating a pull request

When you create a Pull Request, make sure to base it off of the Master branch whenever possible (create your own branch from the Master branch). If you have any problems submitting a Pull Request I can certainly enter a feature request for the change, but we do encourage you to send in a Pull Request any time you want to provide a fix/new feature in the Engine’s source code.

OK , thanks for clarifying that. I wasn’t sure if I should pull from master or release because I mainly use release for debugging purposes.

Pull added #741: link text

In order for this to work on both reads and writes, the inner object needs to be called with the _FLAT version of BEGIN_ONLINE_JSON_SERIALIZER otherwise the Serializer will try to create two objects and crash.

struct FJsonServerSettings : public FOnlineJsonSerializable
{
    ...
    BEGIN_ONLINE_JSON_SERIALIZER_FLAT
    ONLINE_JSON_SERIALIZE("name", ServerName);
    ONLINE_JSON_SERIALIZE("ver", ServerVersion);
    ONLINE_JSON_SERIALIZE("motd", ServerMessageOfTheDay);
    ONLINE_JSON_SERIALIZE("players", PlayersOnline);
    END_ONLINE_JSON_SERIALIZER_FLAT
};

class FJsonInternetSession : public FOnlineJsonSerializable
{
    ...
    /** Settings for this server's registration */
    FJsonServerSettings ServerSettings;
    // FJsonSerializable
    BEGIN_ONLINE_JSON_SERIALIZER
    ONLINE_JSON_SERIALIZE("ip", ServerIP);
    ONLINE_JSON_SERIALIZE("port", ServerPort);
    ONLINE_JSON_SERIALIZE("name", ServerName);
    ONLINE_JSON_SERIALIZE_OBJECT_SERIALIZABLE("settings", ServerSettings);
    END_ONLINE_JSON_SERIALIZER
};

This was added to the engine source as commit 19277f2