using System; using System.Collections.Generic; using Unity.Services.Analytics.Internal; namespace Unity.Services.Analytics { /// /// The Event class is a write-only container designed for you to safely and efficiently pass event data /// into the Analytics SDK for batching and upload to the back-end. /// /// Each of the Standard events can be recorded using the sub-classes provided. Custom events can be recorded /// either by creating specific sub-classes of Event or using the more generic CustomEvent class provided. /// /// For more information about creating and recording Custom events, see the documentation page: /// https://docs.unity.com/ugs/en-us/manual/analytics/manual/record-custom-events /// public abstract class Event { private protected readonly Dictionary m_Strings; private protected readonly Dictionary m_Integers; private protected readonly Dictionary m_Booleans; private protected readonly Dictionary m_Floats; internal readonly string Name; internal readonly bool StandardEvent; internal readonly int EventVersion; protected Event(string name) { Name = name; m_Strings = new Dictionary(StringComparer.Ordinal); m_Integers = new Dictionary(StringComparer.Ordinal); m_Booleans = new Dictionary(StringComparer.Ordinal); m_Floats = new Dictionary(StringComparer.Ordinal); } internal Event(string name, bool standardEvent, int eventVersion) : this(name) { StandardEvent = standardEvent; EventVersion = eventVersion; } /// /// Sets a string value for the given parameter name. /// /// The name of this parameter, as defined in the event schema. /// The value to store for this parameter. protected void SetParameter(string name, string value) { m_Strings[name] = value; } /// /// Sets a Boolean value for the given parameter name. /// /// The name of this parameter, as defined in the event schema. /// The value to store for this parameter. protected void SetParameter(string name, bool value) { m_Booleans[name] = value; } /// /// Sets an integer value for the given parameter name. /// /// The name of this parameter, as defined in the event schema. /// The value to store for this parameter. protected void SetParameter(string name, int value) { SetParameter(name, (long)value); } /// /// Sets an integer value for the given parameter name. /// /// The name of this parameter, as defined in the event schema. /// The value to store for this parameter. protected void SetParameter(string name, long value) { m_Integers[name] = value; } /// /// Sets a float value for the given parameter name. /// /// The name of this parameter, as defined in the event schema. /// The value to store for this parameter. protected void SetParameter(string name, float value) { SetParameter(name, (double)value); } /// /// Sets a float value for the given parameter name. /// /// The name of this parameter, as defined in the event schema. /// The value to store for this parameter. protected void SetParameter(string name, double value) { m_Floats[name] = value; } internal virtual void Serialize(IBuffer buffer) { foreach (KeyValuePair kvp in m_Strings) { buffer.PushString(kvp.Key, kvp.Value); } foreach (KeyValuePair kvp in m_Integers) { buffer.PushInt64(kvp.Key, kvp.Value); } foreach (KeyValuePair kvp in m_Floats) { buffer.PushDouble(kvp.Key, kvp.Value); } foreach (KeyValuePair kvp in m_Booleans) { buffer.PushBool(kvp.Key, kvp.Value); } } /// /// Note that failing validation will not prevent event serialisation or upload. /// This method is intended to produce warning logs to assist in implementation /// and debugging. Events will still be validated properly by the server on reaching it. /// public virtual void Validate() { } /// /// Use this when implementing the Validate method to determine if a required parameter /// has been set or not. /// /// The name of the parameter /// True if the parameter has been set, otherwise false protected bool ParameterHasBeenSet(string name) { return m_Strings.ContainsKey(name) || m_Integers.ContainsKey(name) || m_Floats.ContainsKey(name) || m_Booleans.ContainsKey(name); } /// /// Clears all parameters and values so that the instance can be reused. /// public virtual void Reset() { m_Strings.Clear(); m_Integers.Clear(); m_Booleans.Clear(); m_Floats.Clear(); } internal static string[] BakeEnum2String(bool toUpper = false) where T : Enum { // Pre-bake the string versions of the enums so we don't reallocate them every // time somebody sets one. // We're using this slightly complicated cooker rather than simply hand-rolling // the values so that we won't accidentally forget to update a list if we extend // or change the underlying enum. Array values = Enum.GetValues(typeof(T)); string[] result = new string[values.Length]; for (int i = 0; i < values.Length; i++) { if (toUpper) { result[i] = values.GetValue(i).ToString().ToUpperInvariant(); } else { result[i] = values.GetValue(i).ToString(); } } return result; } } }