using System; using System.Threading; using UnityEngine; namespace RudderSdk.Unity { public sealed class PlayerPrefsUnityKeyValueStore : IUnityKeyValueStore { private readonly SynchronizationContext _unityContext; private readonly int _mainThreadId; public PlayerPrefsUnityKeyValueStore() { _unityContext = SynchronizationContext.Current; _mainThreadId = Thread.CurrentThread.ManagedThreadId; } public string GetString(string key) { return RunOnMainThread(() => { var value = PlayerPrefs.GetString(key, string.Empty); return string.IsNullOrEmpty(value) ? null : value; }); } public void SetString(string key, string value) { RunOnMainThread(() => PlayerPrefs.SetString(key, value)); } public void DeleteKey(string key) { RunOnMainThread(() => PlayerPrefs.DeleteKey(key)); } public void Save() { RunOnMainThread(PlayerPrefs.Save); } private void RunOnMainThread(Action action) { RunOnMainThread(() => { action(); return true; }); } private T RunOnMainThread(Func action) { if (Thread.CurrentThread.ManagedThreadId == _mainThreadId || _unityContext == null) return action(); T result = default; Exception captured = null; using (var completed = new ManualResetEventSlim(false)) { _unityContext.Post(_ => { try { result = action(); } catch (Exception ex) { captured = ex; } finally { completed.Set(); } }, null); completed.Wait(); } if (captured != null) throw captured; return result; } } }