Add LocalizedString
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Localization.h"
|
||||
#include "CultureInfo.h"
|
||||
#include "LocalizedString.h"
|
||||
#include "LocalizationSettings.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Config/GameSettings.h"
|
||||
@@ -46,6 +47,72 @@ void LocalizationSettings::Deserialize(DeserializeStream& stream, ISerializeModi
|
||||
DESERIALIZE(LocalizedStringTables);
|
||||
}
|
||||
|
||||
LocalizedString::LocalizedString(const LocalizedString& other)
|
||||
: Id(other.Id)
|
||||
, Value(other.Value)
|
||||
{
|
||||
}
|
||||
|
||||
LocalizedString::LocalizedString(LocalizedString&& other) noexcept
|
||||
: Id(MoveTemp(other.Id))
|
||||
, Value(MoveTemp(other.Value))
|
||||
{
|
||||
}
|
||||
|
||||
LocalizedString::LocalizedString(const StringView& value)
|
||||
: Value(value)
|
||||
{
|
||||
}
|
||||
|
||||
LocalizedString::LocalizedString(String&& value) noexcept
|
||||
: Value(MoveTemp(value))
|
||||
{
|
||||
}
|
||||
|
||||
LocalizedString& LocalizedString::operator=(const LocalizedString& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
Id = other.Id;
|
||||
Value = other.Value;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
LocalizedString& LocalizedString::operator=(LocalizedString&& other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
Id = MoveTemp(other.Id);
|
||||
Value = MoveTemp(other.Value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
LocalizedString& LocalizedString::operator=(const StringView& value)
|
||||
{
|
||||
Id.Clear();
|
||||
Value = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LocalizedString& LocalizedString::operator=(String&& value) noexcept
|
||||
{
|
||||
Id.Clear();
|
||||
Value = MoveTemp(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String LocalizedString::ToString() const
|
||||
{
|
||||
return Localization::GetString(Id, Value);
|
||||
}
|
||||
|
||||
String LocalizedString::ToStringPlural(int32 n) const
|
||||
{
|
||||
return Localization::GetPluralString(Id, n, Value);
|
||||
}
|
||||
|
||||
void LocalizationService::OnLocalizationChanged()
|
||||
{
|
||||
PROFILE_CPU();
|
||||
|
||||
103
Source/Engine/Localization/LocalizedString.cs
Normal file
103
Source/Engine/Localization/LocalizedString.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
partial class LocalizedString : IEquatable<LocalizedString>, IEquatable<string>, IComparable, IComparable<LocalizedString>, IComparable<string>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LocalizedString"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
public LocalizedString(string value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the localized plural string for the current language by using string id lookup.
|
||||
/// </summary>
|
||||
/// <param name="n">The value count for plural message selection.</param>
|
||||
/// <returns>The localized text.</returns>
|
||||
public string ToStringPlural(int n)
|
||||
{
|
||||
return string.IsNullOrEmpty(Value) ? Localization.GetPluralString(Id, n) : Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicit converter of <see cref="LocalizedString"/> into <see cref="string"/>.
|
||||
/// </summary>
|
||||
/// <param name="str">The localized string.</param>
|
||||
/// <returns>The string.</returns>
|
||||
public static implicit operator string(LocalizedString str)
|
||||
{
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicit converter of <see cref="string"/> into <see cref="LocalizedString"/>.
|
||||
/// </summary>
|
||||
/// <param name="str">The string.</param>
|
||||
/// <returns>The localized string.</returns>
|
||||
public static implicit operator LocalizedString(string str)
|
||||
{
|
||||
return new LocalizedString(str);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
if (obj is string asString)
|
||||
return CompareTo(asString);
|
||||
if (obj is LocalizedString asLocalizedString)
|
||||
return CompareTo(asLocalizedString);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(LocalizedString other)
|
||||
{
|
||||
return Id == other.Id && Value == other.Value;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(string other)
|
||||
{
|
||||
return Value == other || Localization.GetString(Id) == other;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int CompareTo(LocalizedString other)
|
||||
{
|
||||
return string.Compare(ToString(), ToString(), StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int CompareTo(string other)
|
||||
{
|
||||
return string.Compare(ToString(), other, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return ReferenceEquals(this, obj) || obj is LocalizedString other && Equals(other);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return ((Id != null ? Id.GetHashCode() : 0) * 397) ^ (Value != null ? Value.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return string.IsNullOrEmpty(Value) ? Localization.GetString(Id) : Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
114
Source/Engine/Localization/LocalizedString.h
Normal file
114
Source/Engine/Localization/LocalizedString.h
Normal file
@@ -0,0 +1,114 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/Types/String.h"
|
||||
#include "Engine/Serialization/SerializationFwd.h"
|
||||
|
||||
/// <summary>
|
||||
/// The string container that supports using localized text.
|
||||
/// </summary>
|
||||
API_CLASS(Sealed) class FLAXENGINE_API LocalizedString
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(LocalizedString);
|
||||
public:
|
||||
/// <summary>
|
||||
/// The localized string identifier. Used to lookup text value for a current language (via <see cref="Localization::GetString"/>).
|
||||
/// </summary>
|
||||
API_FIELD() String Id;
|
||||
|
||||
/// <summary>
|
||||
/// The overriden string value to use. If empty, the localized string will be used.
|
||||
/// </summary>
|
||||
API_FIELD() String Value;
|
||||
|
||||
public:
|
||||
LocalizedString() = default;
|
||||
LocalizedString(const LocalizedString& other);
|
||||
LocalizedString(LocalizedString&& other) noexcept;
|
||||
LocalizedString(const StringView& value);
|
||||
LocalizedString(String&& value) noexcept;
|
||||
|
||||
LocalizedString& operator=(const LocalizedString& other);
|
||||
LocalizedString& operator=(LocalizedString&& other) noexcept;
|
||||
LocalizedString& operator=(const StringView& value);
|
||||
LocalizedString& operator=(String&& value) noexcept;
|
||||
|
||||
friend bool operator==(const LocalizedString& a, const LocalizedString& b)
|
||||
{
|
||||
return a.Id == b.Id && a.Value == b.Value;
|
||||
}
|
||||
|
||||
friend bool operator!=(const LocalizedString& a, const LocalizedString& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
friend bool operator==(const LocalizedString& a, const StringView& b)
|
||||
{
|
||||
return a.Value == b || a.ToString() == b;
|
||||
}
|
||||
|
||||
friend bool operator!=(const LocalizedString& a, const StringView& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
public:
|
||||
String ToString() const;
|
||||
String ToStringPlural(int32 n) const;
|
||||
};
|
||||
|
||||
inline uint32 GetHash(const LocalizedString& key)
|
||||
{
|
||||
return GetHash(key.ToString());
|
||||
}
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
inline bool ShouldSerialize(const LocalizedString& v, const void* otherObj)
|
||||
{
|
||||
return !otherObj || v != *(LocalizedString*)otherObj;
|
||||
}
|
||||
|
||||
inline void Serialize(ISerializable::SerializeStream& stream, const LocalizedString& v, const void* otherObj)
|
||||
{
|
||||
if (v.Id.IsEmpty())
|
||||
{
|
||||
stream.String(v.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream.StartObject();
|
||||
stream.JKEY("Id");
|
||||
stream.String(v.Id);
|
||||
stream.JKEY("Value");
|
||||
stream.String(v.Value);
|
||||
stream.EndObject();
|
||||
}
|
||||
}
|
||||
|
||||
inline void Deserialize(ISerializable::DeserializeStream& stream, LocalizedString& v, ISerializeModifier* modifier)
|
||||
{
|
||||
if (stream.IsString())
|
||||
{
|
||||
v.Id = String::Empty;
|
||||
v.Value = stream.GetText();
|
||||
}
|
||||
else if (stream.IsObject())
|
||||
{
|
||||
auto e = SERIALIZE_FIND_MEMBER(stream, "Id");
|
||||
if (e != stream.MemberEnd())
|
||||
v.Id = e->value.GetString();
|
||||
e = SERIALIZE_FIND_MEMBER(stream, "Value");
|
||||
if (e != stream.MemberEnd())
|
||||
v.Value = e->value.GetString();
|
||||
}
|
||||
else
|
||||
{
|
||||
v = LocalizedString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_DEFAULT_FORMATTING_VIA_TO_STRING(LocalizedString);
|
||||
@@ -219,6 +219,75 @@ namespace FlaxEngine.Json
|
||||
public override bool CanWriteDiff => true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize LocalizedString as inlined text is not using localization (Id member is empty).
|
||||
/// </summary>
|
||||
/// <seealso cref="Newtonsoft.Json.JsonConverter" />
|
||||
internal class LocalizedStringConverter : JsonConverter
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
|
||||
{
|
||||
var str = (LocalizedString)value;
|
||||
if (string.IsNullOrEmpty(str.Id))
|
||||
{
|
||||
writer.WriteValue(str.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
writer.WritePropertyName("Id");
|
||||
writer.WriteValue(str.Id);
|
||||
writer.WritePropertyName("Value");
|
||||
writer.WriteValue(str.Value);
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
|
||||
{
|
||||
var str = existingValue as LocalizedString ?? new LocalizedString();
|
||||
if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
str.Id = null;
|
||||
str.Value = (string)reader.Value;
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.StartObject)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.PropertyName:
|
||||
{
|
||||
var propertyName = (string)reader.Value;
|
||||
switch (propertyName)
|
||||
{
|
||||
case "Id":
|
||||
str.Id = reader.ReadAsString();
|
||||
break;
|
||||
case "Value":
|
||||
str.Value = reader.ReadAsString();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case JsonToken.Comment: break;
|
||||
default: return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof(LocalizedString);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Serialize Guid values using `N` format
|
||||
|
||||
@@ -83,6 +83,7 @@ namespace FlaxEngine.Json
|
||||
settings.Converters.Add(new SoftObjectReferenceConverter());
|
||||
settings.Converters.Add(new MarginConverter());
|
||||
settings.Converters.Add(new VersionConverter());
|
||||
settings.Converters.Add(new LocalizedStringConverter());
|
||||
//settings.Converters.Add(new GuidConverter());
|
||||
return settings;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user