From 9b3e663c39e614bd3b45c3d889f6268e859ea1fe Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Thu, 21 Apr 2022 20:56:28 +0300 Subject: [PATCH] Customize player preferences (#128) * allowing the user to supply a custom preferences source, since PlayerPrefs require running in the main thread * using C# random generator so it will be accessible to other threads --- Mixpanel/Controller.cs | 7 +-- Mixpanel/IPreferences.cs | 15 ++++++ Mixpanel/IPreferences.cs.meta | 11 +++++ Mixpanel/PlayerPreferences.cs | 52 ++++++++++++++++++++ Mixpanel/PlayerPreferences.cs.meta | 11 +++++ Mixpanel/Storage.cs | 76 +++++++++++++++++------------- 6 files changed, 136 insertions(+), 36 deletions(-) create mode 100644 Mixpanel/IPreferences.cs create mode 100644 Mixpanel/IPreferences.cs.meta create mode 100644 Mixpanel/PlayerPreferences.cs create mode 100644 Mixpanel/PlayerPreferences.cs.meta diff --git a/Mixpanel/Controller.cs b/Mixpanel/Controller.cs index 1da3822..bd0232a 100644 --- a/Mixpanel/Controller.cs +++ b/Mixpanel/Controller.cs @@ -351,17 +351,18 @@ internal static class Metadata { private static Int32 _eventCounter = 0, _peopleCounter = 0, _sessionStartEpoch; private static String _sessionID; + private static System.Random _random = new System.Random(Guid.NewGuid().GetHashCode()); internal static void InitSession() { _eventCounter = 0; _peopleCounter = 0; - _sessionID = Convert.ToString(UnityEngine.Random.Range(0, Int32.MaxValue), 16); + _sessionID = Convert.ToString(_random.Next(0, Int32.MaxValue), 16); _sessionStartEpoch = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; } internal static Value GetEventMetadata() { Value eventMetadata = new Value { - {"$mp_event_id", Convert.ToString(UnityEngine.Random.Range(0, Int32.MaxValue), 16)}, + {"$mp_event_id", Convert.ToString(_random.Next(0, Int32.MaxValue), 16)}, {"$mp_session_id", _sessionID}, {"$mp_session_seq_id", _eventCounter}, {"$mp_session_start_sec", _sessionStartEpoch} @@ -373,7 +374,7 @@ internal static Value GetEventMetadata() { internal static Value GetPeopleMetadata() { Value peopleMetadata = new Value { - {"$mp_event_id", Convert.ToString(UnityEngine.Random.Range(0, Int32.MaxValue), 16)}, + {"$mp_event_id", Convert.ToString(_random.Next(0, Int32.MaxValue), 16)}, {"$mp_session_id", _sessionID}, {"$mp_session_seq_id", _peopleCounter}, {"$mp_session_start_sec", _sessionStartEpoch} diff --git a/Mixpanel/IPreferences.cs b/Mixpanel/IPreferences.cs new file mode 100644 index 0000000..01b1b8c --- /dev/null +++ b/Mixpanel/IPreferences.cs @@ -0,0 +1,15 @@ + +namespace mixpanel +{ + public interface IPreferences + { + void DeleteKey(string key); + int GetInt(string key); + int GetInt(string key, int defaultValue); + string GetString(string key); + string GetString(string key, string defaultValue); + bool HasKey(string key); + void SetInt(string key, int value); + void SetString(string key, string value); + } +} \ No newline at end of file diff --git a/Mixpanel/IPreferences.cs.meta b/Mixpanel/IPreferences.cs.meta new file mode 100644 index 0000000..384e8ae --- /dev/null +++ b/Mixpanel/IPreferences.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1230616897949d949b682225a1e4d192 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Mixpanel/PlayerPreferences.cs b/Mixpanel/PlayerPreferences.cs new file mode 100644 index 0000000..2fcd502 --- /dev/null +++ b/Mixpanel/PlayerPreferences.cs @@ -0,0 +1,52 @@ +using UnityEngine; + +namespace mixpanel +{ + public class PlayerPreferences : IPreferences + { + public void DeleteKey(string key) + { + PlayerPrefs.DeleteKey(key); + } + + public float GetFloat(string key) + { + return PlayerPrefs.GetFloat(key); + } + + public int GetInt(string key) + { + return PlayerPrefs.GetInt(key); + } + + public int GetInt(string key, int defaultValue) + { + return PlayerPrefs.GetInt(key, defaultValue); + } + + public string GetString(string key) + { + return PlayerPrefs.GetString(key); + } + + public string GetString(string key, string defaultValue) + { + return PlayerPrefs.GetString(key, defaultValue); + } + + public bool HasKey(string key) + { + return PlayerPrefs.HasKey(key); + } + + public void SetInt(string key, int value) + { + PlayerPrefs.SetInt(key, value); + } + + public void SetString(string key, string value) + { + PlayerPrefs.SetString(key, value); + } + } +} \ No newline at end of file diff --git a/Mixpanel/PlayerPreferences.cs.meta b/Mixpanel/PlayerPreferences.cs.meta new file mode 100644 index 0000000..69854f2 --- /dev/null +++ b/Mixpanel/PlayerPreferences.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: edcd1ac2d0e7eba498446cd39dc68546 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Mixpanel/Storage.cs b/Mixpanel/Storage.cs index 8747928..d5df590 100644 --- a/Mixpanel/Storage.cs +++ b/Mixpanel/Storage.cs @@ -16,14 +16,24 @@ namespace mixpanel { public static class MixpanelStorage { + #region Preferences + private static IPreferences PreferencesSource = new PlayerPreferences(); + + public static void SetPreferencesSource(IPreferences preferences) + { + PreferencesSource = preferences; + } + + #endregion + #region HasMigratedFrom1To2 private const string HasMigratedFrom1To2Name = "Mixpanel.HasMigratedFrom1To2"; internal static bool HasMigratedFrom1To2 { - get => Convert.ToBoolean(PlayerPrefs.GetInt(HasMigratedFrom1To2Name, 0)); - set => PlayerPrefs.SetInt(HasMigratedFrom1To2Name, Convert.ToInt32(value)); + get => Convert.ToBoolean(PreferencesSource.GetInt(HasMigratedFrom1To2Name, 0)); + set => PreferencesSource.SetInt(HasMigratedFrom1To2Name, Convert.ToInt32(value)); } #endregion @@ -34,8 +44,8 @@ internal static bool HasMigratedFrom1To2 internal static bool HasIntegratedLibrary { - get => Convert.ToBoolean(PlayerPrefs.GetInt(HasIntegratedLibraryName, 0)); - set => PlayerPrefs.SetInt(HasIntegratedLibraryName, Convert.ToInt32(value)); + get => Convert.ToBoolean(PreferencesSource.GetInt(HasIntegratedLibraryName, 0)); + set => PreferencesSource.SetInt(HasIntegratedLibraryName, Convert.ToInt32(value)); } #endregion @@ -51,9 +61,9 @@ public static string DistinctId get { if (!string.IsNullOrEmpty(_distinctId)) return _distinctId; - if (PlayerPrefs.HasKey(DistinctIdName)) + if (PreferencesSource.HasKey(DistinctIdName)) { - _distinctId = PlayerPrefs.GetString(DistinctIdName); + _distinctId = PreferencesSource.GetString(DistinctIdName); } // Generate a Unique ID for this client if still null or empty // https://devblogs.microsoft.com/oldnewthing/?p=21823 @@ -63,7 +73,7 @@ public static string DistinctId set { _distinctId = value; - PlayerPrefs.SetString(DistinctIdName, _distinctId); + PreferencesSource.SetString(DistinctIdName, _distinctId); } } @@ -84,18 +94,18 @@ internal static void EnqueueTrackingData(Value data, FlushType flushType) int peopleId = PeopleAutoIncrementingID(); String trackingKey = (flushType == FlushType.EVENTS)? "Event" + eventId.ToString() : "People" + peopleId.ToString(); data["id"] = trackingKey; - PlayerPrefs.SetString(trackingKey, JsonUtility.ToJson(data)); + PreferencesSource.SetString(trackingKey, JsonUtility.ToJson(data)); IncreaseTrackingDataID(flushType); } internal static int EventAutoIncrementingID() { - return PlayerPrefs.HasKey("EventAutoIncrementingID") ? PlayerPrefs.GetInt("EventAutoIncrementingID") : 0; + return PreferencesSource.HasKey("EventAutoIncrementingID") ? PreferencesSource.GetInt("EventAutoIncrementingID") : 0; } internal static int PeopleAutoIncrementingID() { - return PlayerPrefs.HasKey("PeopleAutoIncrementingID") ? PlayerPrefs.GetInt("PeopleAutoIncrementingID") : 0; + return PreferencesSource.HasKey("PeopleAutoIncrementingID") ? PreferencesSource.GetInt("PeopleAutoIncrementingID") : 0; } private static void IncreaseTrackingDataID(FlushType flushType) @@ -103,7 +113,7 @@ private static void IncreaseTrackingDataID(FlushType flushType) int id = (flushType == FlushType.EVENTS)? EventAutoIncrementingID() : PeopleAutoIncrementingID(); id += 1; String trackingIdKey = (flushType == FlushType.EVENTS)? "EventAutoIncrementingID" : "PeopleAutoIncrementingID"; - PlayerPrefs.SetInt(trackingIdKey, id); + PreferencesSource.SetInt(trackingIdKey, id); } internal static Value DequeueBatchTrackingData(FlushType flushType, int batchSize) @@ -113,13 +123,13 @@ internal static Value DequeueBatchTrackingData(FlushType flushType, int batchSiz int maxIndex = (flushType == FlushType.EVENTS) ? EventAutoIncrementingID() - 1 : PeopleAutoIncrementingID() - 1; while (batch.Count < batchSize && dataIndex <= maxIndex) { String trackingKey = (flushType == FlushType.EVENTS) ? "Event" + dataIndex.ToString() : "People" + dataIndex.ToString(); - if (PlayerPrefs.HasKey(trackingKey)) { + if (PreferencesSource.HasKey(trackingKey)) { try { - batch.Add(JsonUtility.FromJson(PlayerPrefs.GetString(trackingKey))); + batch.Add(JsonUtility.FromJson(PreferencesSource.GetString(trackingKey))); } catch (Exception e) { Mixpanel.LogError($"There was an error processing '{trackingKey}' from the internal object pool: " + e); - PlayerPrefs.DeleteKey(trackingKey); + PreferencesSource.DeleteKey(trackingKey); } } dataIndex++; @@ -135,8 +145,8 @@ internal static void DeleteBatchTrackingData(FlushType flushType, int batchSize) int maxIndex = (flushType == FlushType.EVENTS) ? EventAutoIncrementingID() - 1 : PeopleAutoIncrementingID() - 1; while (deletedCount < batchSize && dataIndex <= maxIndex) { String trackingKey = (flushType == FlushType.EVENTS) ? "Event" + dataIndex.ToString() : "People" + dataIndex.ToString(); - if (PlayerPrefs.HasKey(trackingKey)) { - PlayerPrefs.DeleteKey(trackingKey); + if (PreferencesSource.HasKey(trackingKey)) { + PreferencesSource.DeleteKey(trackingKey); deletedCount++; } dataIndex++; @@ -146,8 +156,8 @@ internal static void DeleteBatchTrackingData(FlushType flushType, int batchSize) internal static void DeleteBatchTrackingData(Value batch) { foreach(Value data in batch) { String id = data["id"]; - if (id != null && PlayerPrefs.HasKey(id)) { - PlayerPrefs.DeleteKey(id); + if (id != null && PreferencesSource.HasKey(id)) { + PreferencesSource.DeleteKey(id); } } } @@ -169,14 +179,14 @@ public static bool IsTracking { get { - if (!PlayerPrefs.HasKey(IsTrackingName)) IsTracking = true; - else _isTracking = PlayerPrefs.GetInt(IsTrackingName) == 1; + if (!PreferencesSource.HasKey(IsTrackingName)) IsTracking = true; + else _isTracking = PreferencesSource.GetInt(IsTrackingName) == 1; return _isTracking; } set { _isTracking = value; - PlayerPrefs.SetInt(IsTrackingName, _isTracking ? 1 : 0); + PreferencesSource.SetInt(IsTrackingName, _isTracking ? 1 : 0); } } @@ -193,14 +203,14 @@ internal static string PushDeviceTokenString get { if (!string.IsNullOrEmpty(_pushDeviceTokenString)) return _pushDeviceTokenString; - if (!PlayerPrefs.HasKey(PushDeviceTokenName)) PushDeviceTokenString = ""; - else _pushDeviceTokenString = PlayerPrefs.GetString(PushDeviceTokenName); + if (!PreferencesSource.HasKey(PushDeviceTokenName)) PushDeviceTokenString = ""; + else _pushDeviceTokenString = PreferencesSource.GetString(PushDeviceTokenName); return _pushDeviceTokenString; } set { _pushDeviceTokenString = value; - PlayerPrefs.SetString(PushDeviceTokenName, _pushDeviceTokenString); + PreferencesSource.SetString(PushDeviceTokenName, _pushDeviceTokenString); } } @@ -223,18 +233,18 @@ internal static Value OnceProperties get { if (_onceProperties != null) return _onceProperties; - if (!PlayerPrefs.HasKey(OncePropertiesName)) OnceProperties = new Value(); + if (!PreferencesSource.HasKey(OncePropertiesName)) OnceProperties = new Value(); else { _onceProperties = new Value(); - JsonUtility.FromJsonOverwrite(PlayerPrefs.GetString(OncePropertiesName), _onceProperties); + JsonUtility.FromJsonOverwrite(PreferencesSource.GetString(OncePropertiesName), _onceProperties); } return _onceProperties; } set { _onceProperties = value; - PlayerPrefs.SetString(OncePropertiesName, JsonUtility.ToJson(_onceProperties)); + PreferencesSource.SetString(OncePropertiesName, JsonUtility.ToJson(_onceProperties)); } } @@ -258,18 +268,18 @@ internal static Value SuperProperties get { if (_superProperties != null) return _superProperties; - if (!PlayerPrefs.HasKey(SuperPropertiesName)) SuperProperties = new Value(); + if (!PreferencesSource.HasKey(SuperPropertiesName)) SuperProperties = new Value(); else { _superProperties = new Value(); - JsonUtility.FromJsonOverwrite(PlayerPrefs.GetString(SuperPropertiesName), _superProperties); + JsonUtility.FromJsonOverwrite(PreferencesSource.GetString(SuperPropertiesName), _superProperties); } return _superProperties; } set { _superProperties = value; - PlayerPrefs.SetString(SuperPropertiesName, JsonUtility.ToJson(_superProperties)); + PreferencesSource.SetString(SuperPropertiesName, JsonUtility.ToJson(_superProperties)); } } @@ -293,18 +303,18 @@ internal static Value TimedEvents get { if (_timedEvents != null) return _timedEvents; - if (!PlayerPrefs.HasKey(TimedEventsName)) TimedEvents = new Value(); + if (!PreferencesSource.HasKey(TimedEventsName)) TimedEvents = new Value(); else { _timedEvents = new Value(); - JsonUtility.FromJsonOverwrite(PlayerPrefs.GetString(TimedEventsName), _timedEvents); + JsonUtility.FromJsonOverwrite(PreferencesSource.GetString(TimedEventsName), _timedEvents); } return _timedEvents; } set { _timedEvents = value; - PlayerPrefs.SetString(TimedEventsName, JsonUtility.ToJson(_timedEvents)); + PreferencesSource.SetString(TimedEventsName, JsonUtility.ToJson(_timedEvents)); } }