#if ENABLE_PROPERTY_VARIANTS || PACKAGE_DOCS_GENERATION
using System;
using System.Collections.Generic;
using UnityEngine.Localization.SmartFormat;
namespace UnityEngine.Localization.PropertyVariants.TrackedProperties
{
///
/// Interface for accessing a tracked property`s values.
///
/// The property data type.
public interface ITrackedPropertyValue : ITrackedProperty
{
///
/// Attempts to find a value for the provided LocaleIdentifier.
///
/// The LocaleIdentifier to check for.
/// The value found for the LocaleIdentifier.
/// if a value was found and if one was not.
bool GetValue(LocaleIdentifier localeIdentifier, out T foundValue);
///
/// Attempts to find a value for the provided LocaleIdentifier or fallback.
///
/// The LocaleIdentifier to check for.
/// The LocaleIdentifier to fallback to if one could not be found for .
/// The value found for the LocaleIdentifier or fallback.
/// if a value was found and if one was not.
bool GetValue(LocaleIdentifier localeIdentifier, LocaleIdentifier fallback, out T foundValue);
///
/// Assigns a value for the chosen LocaleIdentifier.
///
/// The LocaleIdentifier the variant should be applied to
/// The variant value for the LocaleIdentifier.
void SetValue(LocaleIdentifier localeIdentifier, T value);
}
internal interface ITrackedPropertyRemoveVariant
{
void RemoveVariant(LocaleIdentifier localeIdentifier);
}
///
/// Represents a property for a primitive data type.
///
/// The primitive data type.
[Serializable]
public class TrackedProperty : ITrackedPropertyValue, IStringProperty, ISerializationCallbackReceiver, ITrackedPropertyRemoveVariant
{
[Serializable]
internal class LocaleIdentifierValuePair
{
public LocaleIdentifier localeIdentifier;
public TPrimitive value;
}
[SerializeField] string m_PropertyPath;
[SerializeField] List m_VariantData = new List();
internal Dictionary m_VariantLookup = new Dictionary();
///
/// The property's serialized property path.
///
public string PropertyPath
{
get => m_PropertyPath;
set => m_PropertyPath = value;
}
public bool HasVariant(LocaleIdentifier localeIdentifier) => m_VariantLookup.ContainsKey(localeIdentifier);
public void RemoveVariant(LocaleIdentifier localeIdentifier) => m_VariantLookup.Remove(localeIdentifier);
public bool GetValue(LocaleIdentifier localeIdentifier, out TPrimitive foundValue)
{
if (m_VariantLookup.TryGetValue(localeIdentifier, out var pair))
{
foundValue = pair.value;
return true;
}
foundValue = default;
return false;
}
public bool GetValue(LocaleIdentifier localeIdentifier, LocaleIdentifier fallback, out TPrimitive foundValue)
{
if (m_VariantLookup.TryGetValue(localeIdentifier, out var pair) || m_VariantLookup.TryGetValue(fallback, out pair))
{
foundValue = pair.value;
return true;
}
foundValue = default;
return false;
}
public void SetValue(LocaleIdentifier localeIdentifier, TPrimitive value)
{
if (!m_VariantLookup.TryGetValue(localeIdentifier, out var pair))
{
pair = new LocaleIdentifierValuePair { localeIdentifier = localeIdentifier };
m_VariantLookup[localeIdentifier] = pair;
}
pair.value = value;
}
public string GetValueAsString(LocaleIdentifier localeIdentifier) => GetValue(localeIdentifier, out var foundValue) ? ConvertToString(foundValue) : null;
public string GetValueAsString(LocaleIdentifier localeIdentifier, LocaleIdentifier fallback) => GetValue(localeIdentifier, fallback, out var foundValue) ? ConvertToString(foundValue) : null;
public void SetValueFromString(LocaleIdentifier localeIdentifier, string stringValue)
{
var convertedValue = ConvertFromString(stringValue);
SetValue(localeIdentifier, convertedValue);
}
protected virtual string ConvertToString(TPrimitive value) => Convert.ToString(value);
protected virtual TPrimitive ConvertFromString(string value) => (TPrimitive)Convert.ChangeType(value, typeof(TPrimitive));
public void OnBeforeSerialize()
{
m_VariantData.Clear();
foreach (var pair in m_VariantLookup.Values)
{
m_VariantData.Add(pair);
}
}
public void OnAfterDeserialize()
{
m_VariantLookup.Clear();
foreach (var pair in m_VariantData)
{
m_VariantLookup[pair.localeIdentifier] = pair;
}
}
public override string ToString() => Smart.Format("{GetType().Name}({PropertyPath}) - {1:list:{Key}({Value.value})|, |, }", this, m_VariantLookup);
}
[Serializable] public class ByteTrackedProperty : TrackedProperty {}
[Serializable] public class SByteTrackedProperty : TrackedProperty {}
[Serializable] public class CharTrackedProperty : TrackedProperty {}
[Serializable] public class ShortTrackedProperty : TrackedProperty {}
[Serializable] public class UShortTrackedProperty : TrackedProperty {}
[Serializable] public class IntTrackedProperty : TrackedProperty {}
[Serializable] public class UIntTrackedProperty : TrackedProperty {}
[Serializable] public class LongTrackedProperty : TrackedProperty {}
[Serializable] public class ULongTrackedProperty : TrackedProperty {}
[Serializable] public class FloatTrackedProperty : TrackedProperty {}
[Serializable] public class DoubleTrackedProperty : TrackedProperty {}
[Serializable] public class ArraySizeTrackedProperty : UIntTrackedProperty {}
// Same as Int but we use a custom property drawer which resolves the Enum type in the inspector.
[Serializable] public class EnumTrackedProperty : IntTrackedProperty {}
[Serializable]
public class BoolTrackedProperty : TrackedProperty
{
protected override bool ConvertFromString(string value)
{
// Support bool in the form "0" or "1".
if (int.TryParse(value, out var result))
return (bool)Convert.ChangeType(result, typeof(bool));
// Support bool in the form "false" or "true".
return base.ConvertFromString(value);
}
protected override string ConvertToString(bool value)
{
return value ? "1" : "0";
}
}
[Serializable]
public class StringTrackedProperty : TrackedProperty
{
protected override string ConvertFromString(string value) => value;
protected override string ConvertToString(string value) => value;
}
}
#endif