Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using in Unreal Engine - handling custom types conversion #495

Closed
danielkcz opened this issue Mar 11, 2017 · 12 comments
Closed

Using in Unreal Engine - handling custom types conversion #495

danielkcz opened this issue Mar 11, 2017 · 12 comments

Comments

@danielkcz
Copy link

danielkcz commented Mar 11, 2017

Hi. I come from a JavaScript world where working with JSON is total breeze. We are currently working on a game using Unreal Engine 4 and we need to develop custom save system using JSON format so it can be read using Javascript somewhere else.

I kinda like approach of this library as its syntax is similar to what I am used to from JS. Sadly me as total rookie to C++ I am struggling with this a lot. I would like to make some arbitrary conversions from Unreal types to ones supported by this library.

For example here is a header file for FString type. Somewhere else I've found what I need to do for conversion to std::string so I've tried to add following

namespace nlohmann {
	template <typename T>
	struct adl_serializer<FString> {
		static void to_json(json& j, const FString value) {
			j = TCHAR_TO_UTF8(*value)
		}
	};
}

However this is failing compilation with this error. I am totally clueless what that means. Can you please help?

error C3211: 'nlohmann::adl_serializer<FString,void>': explicit specialization is using partial specialization syntax, use template <> instead
note: see declaration of 'nlohmann::adl_serializer<FString,void>'

@nlohmann
Copy link
Owner

I haven't tried it, but it should be sufficient to define a to_json function in the namespace of FString. In the header, I did not find a namespace, so it should be sufficient to define

void to_json(json& j, const person& p) {
    j = TCHAR_TO_UTF8(*value);
}

(I just copied the j = TCHAR_TO_UTF8(*value); from your example).

Then you should be able to execute for an FString object f: json j = f;.

@theodelrieu
Copy link
Contributor

What you need to do is to remove the typename T and it will work:

template <>
struct adl_serializer<FString> { ... };

@danielkcz
Copy link
Author

@nlohmann I don't understand how that could work. How it can know to use global to_json function for FString?

@theodelrieu Tried that and now I am getting...

error C2908: explicit specialization; 'nlohmann::adl_serializer<T,void>' has already been instantiated
with
[
T=FString
]
error C2766: explicit specialization; 'nlohmann::adl_serializer<T,void>' has already been defined
with
[
T=FString
]

@theodelrieu
Copy link
Contributor

For types that belong to you, the free function is the best approach usually, however for those which are not in your namespaces that' s not really intended.

I think that error means that you should put this piece of code at the very top of your file, because adl_serializer is instantiated when you do this:

my_type mt;
// adl_serializer<my_type> gets instantiated here
json j = mt; 

If you don't put your specialization before , you get that error message.

@danielkcz
Copy link
Author

danielkcz commented Mar 11, 2017

Ok, looks like that this actually works...

void to_json(json& j, const FString& value) {
	j = TCHAR_TO_UTF8(*value);
}

However when I am trying to dump that JSON now, I am getting bunch of japanese characters :)

LogTemp:Warning: JSON ≻敫≹∺祍敔瑳索촀췍췍췍췍췍췍췍Ꭰ띂Ȳ

json result;
FString test = TEXT("MyTest");
result["key"] = test;

UE_LOG(LogTemp, Warning, TEXT("JSON %s"), result.dump().c_str());

I am not entirely sure I got that conversion to std::string right. Here is a source of the information: https://wiki.unrealengine.com/String_Conversions:_FString_to_FName,_FString_to_Int32,_Float_to_FString

Also I had to use c_str() on the dump result as the UE_LOG macro does not recognize string_t. That last argument of UE_LOG is VarArgs

@theodelrieu
Copy link
Contributor

theodelrieu commented Mar 11, 2017

Since FString is defined in the global namespaces, this is much more easier indeed.

Edit: about the conversion , I never used unreal, I don't think I can be of any help here...

@nlohmann
Copy link
Owner

@FredyC I am also not an expert. To make sure, you could change the function to

void to_json(json& j, const FString& value) {
    j = std::string(TCHAR_TO_UTF8(*value));
}

and then try:

json result;
FString test = TEXT("MyTest");
result["key"] = test;

std::cout << result << std::endl;

The first change makes the conversion to a std::string explicit. The second string asks for a serialization without relying on the behavior of the UE_LOG function.

@danielkcz
Copy link
Author

Well first change did not help and sadly it's not possible to use std::cout as there is no way to read output from it. The whole thing is executed from within Unreal Editor and there is no access to regular output.

Anyway, I will try to figure that out on side of UE. Thanks for help!

@nlohmann
Copy link
Owner

You're welcome. I shall close this issue. But it would be great if you could share your further experience with the library and UE.

@rrafis
Copy link

rrafis commented Jan 17, 2019

Ok, looks like that this actually works...

void to_json(json& j, const FString& value) {
	j = TCHAR_TO_UTF8(*value);
}

However when I am trying to dump that JSON now, I am getting bunch of japanese characters :)

LogTemp:Warning: JSON ≻敫≹∺祍敔瑳索촀췍췍췍췍췍췍췍Ꭰ띂Ȳ

@FredyC, have you found any solution with this?

@danielkcz
Copy link
Author

@rrafis Sorry, I don't remember really, I've left Unreal Engine world shortly after this issue.

@kigbariom
Copy link

Ok, looks like that this actually works...

void to_json(json& j, const FString& value) {
	j = TCHAR_TO_UTF8(*value);
}

However when I am trying to dump that JSON now, I am getting bunch of japanese characters :)

LogTemp:Warning: JSON ≻敫≹∺祍敔瑳索촀췍췍췍췍췍췍췍Ꭰ띂Ȳ

@FredyC, have you found any solution with this?

UE_LOG_UTF8 will fix that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants