Prefs.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. using System;
  2. using UnityEngine;
  3. namespace ET.PackageManager.Editor
  4. {
  5. /// 用于本地小数据量记录的playerPre的包装,用于方便把单个设置项直接当做变量使用
  6. /// 使用这个,可以避免读取时每次都调用PlayerPrefs
  7. /// 另外集成了以groupKey(比如userid)来分组数据
  8. public struct Prefs<T>
  9. {
  10. private T m_value;
  11. private string m_key;
  12. private string m_valueKey;
  13. private RwFlag m_rwFlag;
  14. private int m_groupKeyVer;
  15. private IGroupKey m_groupKey;
  16. private IPrefsAccessor m_accessor;
  17. private T m_defValue;
  18. public Prefs(string key, IGroupKey groupKey, T defValue, IPrefsAccessor accessor)
  19. {
  20. m_defValue = defValue;
  21. m_value = defValue;
  22. m_groupKey = groupKey;
  23. m_accessor = accessor;
  24. m_groupKeyVer = int.MinValue;
  25. m_rwFlag = RwFlag.None;
  26. m_valueKey = key;
  27. m_key = key;
  28. UpdateKey();
  29. }
  30. private void UpdateKey(bool notWrite = false)
  31. {
  32. if (m_groupKey == null)
  33. {
  34. return;
  35. }
  36. var curVer = m_groupKey.Version;
  37. if (curVer != m_groupKeyVer)
  38. {
  39. m_groupKeyVer = curVer;
  40. var oldKey = m_key;
  41. m_key = StrUtil.Concat(m_groupKey.Key, "|", m_valueKey);
  42. if (m_rwFlag.Has(RwFlag.Write))
  43. {
  44. if (oldKey != m_key)
  45. {
  46. //如果之前已经有写入,则需要删除旧的,写入新的
  47. PlayerPrefs.DeleteKey(oldKey);
  48. if (!notWrite)
  49. {
  50. m_accessor.Set(m_key, m_value);
  51. }
  52. }
  53. }
  54. //清除读取标记
  55. m_rwFlag.UnmarkSelf(RwFlag.Read);
  56. }
  57. }
  58. public T Value
  59. {
  60. get
  61. {
  62. UpdateKey();
  63. //如果即没有读过,也没有写过
  64. if (!m_rwFlag.Overlaps(RwFlag.Full))
  65. {
  66. if (m_accessor.HasKey(m_key))
  67. {
  68. m_value = m_accessor.Get(m_key);
  69. }
  70. else if (m_groupKey != null && m_accessor.HasKey(m_valueKey))
  71. {
  72. //第一次时,如果定向的值拿不到,就去尝试拿全局的值
  73. m_value = m_accessor.Get(m_valueKey);
  74. }
  75. else
  76. {
  77. m_value = m_defValue;
  78. }
  79. m_rwFlag.MarkSelf(RwFlag.Read);
  80. }
  81. return m_value;
  82. }
  83. set
  84. {
  85. UpdateKey();
  86. if (m_rwFlag.Overlaps(RwFlag.Full) && value.Equals(m_value))
  87. {
  88. return;
  89. }
  90. m_value = value;
  91. m_rwFlag |= RwFlag.Write;
  92. m_accessor.Set(m_key, value);
  93. }
  94. }
  95. public void Delete()
  96. {
  97. UpdateKey(true);
  98. m_groupKeyVer = int.MinValue;
  99. m_value = default;
  100. m_rwFlag.MarkSelf(RwFlag.Write);
  101. PlayerPrefs.DeleteKey(m_key);
  102. }
  103. public interface IPrefsAccessor
  104. {
  105. bool HasKey(string key);
  106. T Get(string key);
  107. void Set(string key, T value);
  108. }
  109. }
  110. public struct IntPrefs
  111. {
  112. private Prefs<int> m_value;
  113. public int Value
  114. {
  115. get => m_value.Value;
  116. set => m_value.Value = value;
  117. }
  118. public IntPrefs(string key, IGroupKey groupKey = null, int defValue = 0)
  119. {
  120. m_value = new Prefs<int>(key, groupKey, defValue, IntAccessor.Inst);
  121. }
  122. public void Delete()
  123. {
  124. m_value.Delete();
  125. }
  126. public static implicit operator int(IntPrefs value)
  127. {
  128. return value.Value;
  129. }
  130. }
  131. public struct FloatPrefs
  132. {
  133. private Prefs<float> m_value;
  134. public float Value
  135. {
  136. get => m_value.Value;
  137. set => m_value.Value = value;
  138. }
  139. public FloatPrefs(string key, IGroupKey groupKey = null, float defValue = 0f)
  140. {
  141. m_value = new Prefs<float>(key, groupKey, defValue, FloatAccessor.Inst);
  142. }
  143. public void Delete()
  144. {
  145. m_value.Delete();
  146. }
  147. public static implicit operator float(FloatPrefs value)
  148. {
  149. return value.Value;
  150. }
  151. }
  152. public struct StringPrefs
  153. {
  154. private Prefs<string> m_value;
  155. public string Value
  156. {
  157. get => m_value.Value;
  158. set => m_value.Value = value;
  159. }
  160. public StringPrefs(string key, IGroupKey groupKey = null, string defValue = null)
  161. {
  162. m_value = new Prefs<string>(key, groupKey, defValue, StrAccessor.Inst);
  163. }
  164. public void Delete()
  165. {
  166. m_value.Delete();
  167. }
  168. public static implicit operator string(StringPrefs value)
  169. {
  170. return value.Value;
  171. }
  172. }
  173. public struct BoolPrefs
  174. {
  175. private Prefs<int> m_value;
  176. public bool Value
  177. {
  178. get => m_value.Value == 1;
  179. set => m_value.Value = value ? 1 : 0;
  180. }
  181. public BoolPrefs(string key, IGroupKey groupKey = null, bool defValue = false)
  182. {
  183. m_value = new Prefs<int>(key, groupKey, defValue ? 1 : 0, IntAccessor.Inst);
  184. }
  185. public void Delete()
  186. {
  187. m_value.Delete();
  188. }
  189. public static implicit operator bool(BoolPrefs value)
  190. {
  191. return value.Value;
  192. }
  193. }
  194. public struct ArrPrefs<T> where T : IComparable
  195. {
  196. private Prefs<string> m_value;
  197. public ArrPrefs(string key, IGroupKey groupKey = null)
  198. {
  199. m_value = new Prefs<string>(key, groupKey, "", StrAccessor.Inst);
  200. }
  201. public T[] Get()
  202. {
  203. string value = m_value.Value;
  204. if (string.IsNullOrEmpty(value))
  205. {
  206. return Array.Empty<T>();
  207. }
  208. return StrConv.ToArr<T>(value, StrConv.ArrSplitLv1);
  209. }
  210. public void Set(T[] value)
  211. {
  212. if (value == null || value.Length < 1)
  213. {
  214. m_value.Delete();
  215. return;
  216. }
  217. var sb = SbPool.Get();
  218. sb.Append(value[0].ToString());
  219. for (int i = 1; i < value.Length; i++)
  220. {
  221. sb.Append(StrConv.ChrArrSplitLv1).Append(value[i].ToString());
  222. }
  223. m_value.Value = SbPool.PutAndToStr(sb);
  224. }
  225. public void Delete()
  226. {
  227. m_value.Delete();
  228. }
  229. }
  230. public struct EnumPrefs<T> where T : Enum
  231. {
  232. private Prefs<int> m_value;
  233. public T Value
  234. {
  235. get => (T)Enum.ToObject(typeof(T), m_value.Value);
  236. set => m_value.Value = Convert.ToInt32(value);
  237. }
  238. public EnumPrefs(string key, IGroupKey groupKey = null, T defValue = default)
  239. {
  240. m_value = new Prefs<int>(key, groupKey, Convert.ToInt32(defValue), IntAccessor.Inst);
  241. }
  242. public void Delete()
  243. {
  244. m_value.Delete();
  245. }
  246. public static implicit operator T(EnumPrefs<T> value)
  247. {
  248. return value.Value;
  249. }
  250. }
  251. public class IntAccessor : Prefs<int>.IPrefsAccessor
  252. {
  253. public static readonly IntAccessor Inst = new IntAccessor();
  254. public bool HasKey(string key)
  255. {
  256. return PlayerPrefs.HasKey(key);
  257. }
  258. public int Get(string key)
  259. {
  260. return PlayerPrefs.GetInt(key);
  261. }
  262. public void Set(string key, int value)
  263. {
  264. PlayerPrefs.SetInt(key, value);
  265. }
  266. }
  267. public class FloatAccessor : Prefs<float>.IPrefsAccessor
  268. {
  269. public static readonly FloatAccessor Inst = new FloatAccessor();
  270. public bool HasKey(string key)
  271. {
  272. return PlayerPrefs.HasKey(key);
  273. }
  274. public float Get(string key)
  275. {
  276. return PlayerPrefs.GetFloat(key);
  277. }
  278. public void Set(string key, float value)
  279. {
  280. PlayerPrefs.SetFloat(key, value);
  281. }
  282. }
  283. public class StrAccessor : Prefs<string>.IPrefsAccessor
  284. {
  285. public static readonly StrAccessor Inst = new StrAccessor();
  286. public bool HasKey(string key)
  287. {
  288. return PlayerPrefs.HasKey(key);
  289. }
  290. public string Get(string key)
  291. {
  292. return PlayerPrefs.GetString(key);
  293. }
  294. public void Set(string key, string value)
  295. {
  296. PlayerPrefs.SetString(key, value);
  297. }
  298. }
  299. /// <summary>
  300. /// 分组KEY
  301. /// </summary>
  302. public interface IGroupKey
  303. {
  304. int Version { get; }
  305. string Key { get; }
  306. }
  307. [Flags]
  308. public enum RwFlag
  309. {
  310. None = 0,
  311. Write = 1,
  312. Read = 1 << 1,
  313. Full = Write | Read
  314. }
  315. public static class RwFlagExt
  316. {
  317. public static RwFlag Mark(this RwFlag owner, RwFlag flags)
  318. {
  319. return owner | flags;
  320. }
  321. public static RwFlag Unmark(this RwFlag owner, RwFlag flags)
  322. {
  323. return owner & (~flags);
  324. }
  325. public static void MarkSelf(this ref RwFlag owner, RwFlag flags)
  326. {
  327. owner |= flags;
  328. }
  329. public static void UnmarkSelf(this ref RwFlag owner, RwFlag flags)
  330. {
  331. owner &= (~flags);
  332. }
  333. public static bool Has(this RwFlag owner, RwFlag flags)
  334. {
  335. return (owner & flags) == flags;
  336. }
  337. public static bool Overlaps(this RwFlag owner, RwFlag flags)
  338. {
  339. return (owner & flags) != 0;
  340. }
  341. }
  342. }