SerializedBitArray.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. using UnityEngine.Rendering;
  2. using System;
  3. using System.Reflection;
  4. using System.Linq.Expressions;
  5. namespace UnityEditor.Rendering
  6. {
  7. /// <summary>Serialisation of BitArray, Utility class</summary>
  8. public static class SerializedBitArrayUtilities
  9. {
  10. /// <summary>Convert to 8bit</summary>
  11. /// <param name="serializedProperty">The SerializedProperty</param>
  12. /// <returns>A SerializedBitArray8</returns>
  13. public static SerializedBitArray8 ToSerializeBitArray8(this SerializedProperty serializedProperty)
  14. {
  15. if (!IsBitArrayOfCapacity(serializedProperty, 8u))
  16. throw new Exception("Cannot get SerializeBitArray of this Capacity");
  17. return new SerializedBitArray8(serializedProperty);
  18. }
  19. /// <summary>Try convert to 8bit</summary>
  20. /// <param name="serializedProperty">The SerializedProperty</param>
  21. /// <param name="serializedBitArray">Out SerializedBitArray8</param>
  22. /// <returns>True if convertion was a success</returns>
  23. public static bool TryGetSerializeBitArray8(this SerializedProperty serializedProperty, out SerializedBitArray8 serializedBitArray)
  24. {
  25. serializedBitArray = null;
  26. if (!IsBitArrayOfCapacity(serializedProperty, 8u))
  27. return false;
  28. serializedBitArray = new SerializedBitArray8(serializedProperty);
  29. return true;
  30. }
  31. /// <summary>Convert to 16bit</summary>
  32. /// <param name="serializedProperty">The SerializedProperty</param>
  33. /// <returns>A SerializedBitArray16</returns>
  34. public static SerializedBitArray16 ToSerializeBitArray16(this SerializedProperty serializedProperty)
  35. {
  36. if (!IsBitArrayOfCapacity(serializedProperty, 16u))
  37. throw new Exception("Cannot get SerializeBitArray of this Capacity");
  38. return new SerializedBitArray16(serializedProperty);
  39. }
  40. /// <summary>Try convert to 16bit</summary>
  41. /// <param name="serializedProperty">The SerializedProperty</param>
  42. /// <param name="serializedBitArray">Out SerializedBitArray16</param>
  43. /// <returns>True if convertion was a success</returns>
  44. public static bool TryGetSerializeBitArray16(this SerializedProperty serializedProperty, out SerializedBitArray16 serializedBitArray)
  45. {
  46. serializedBitArray = null;
  47. if (!IsBitArrayOfCapacity(serializedProperty, 16u))
  48. return false;
  49. serializedBitArray = new SerializedBitArray16(serializedProperty);
  50. return true;
  51. }
  52. /// <summary>Convert to 32bit</summary>
  53. /// <param name="serializedProperty">The SerializedProperty</param>
  54. /// <returns>A SerializedBitArray32</returns>
  55. public static SerializedBitArray32 ToSerializeBitArray32(this SerializedProperty serializedProperty)
  56. {
  57. if (!IsBitArrayOfCapacity(serializedProperty, 32u))
  58. throw new Exception("Cannot get SerializeBitArray of this Capacity");
  59. return new SerializedBitArray32(serializedProperty);
  60. }
  61. /// <summary>Try convert to 32bit</summary>
  62. /// <param name="serializedProperty">The SerializedProperty</param>
  63. /// <param name="serializedBitArray">Out SerializedBitArray32</param>
  64. /// <returns>True if convertion was a success</returns>
  65. public static bool TryGetSerializeBitArray32(this SerializedProperty serializedProperty, out SerializedBitArray32 serializedBitArray)
  66. {
  67. serializedBitArray = null;
  68. if (!IsBitArrayOfCapacity(serializedProperty, 32u))
  69. return false;
  70. serializedBitArray = new SerializedBitArray32(serializedProperty);
  71. return true;
  72. }
  73. /// <summary>Convert to 64bit</summary>
  74. /// <param name="serializedProperty">The SerializedProperty</param>
  75. /// <returns>A SerializedBitArray64</returns>
  76. public static SerializedBitArray64 ToSerializeBitArray64(this SerializedProperty serializedProperty)
  77. {
  78. if (!IsBitArrayOfCapacity(serializedProperty, 64u))
  79. throw new Exception("Cannot get SerializeBitArray of this Capacity");
  80. return new SerializedBitArray64(serializedProperty);
  81. }
  82. /// <summary>Try convert to 64bit</summary>
  83. /// <param name="serializedProperty">The SerializedProperty</param>
  84. /// <param name="serializedBitArray">Out SerializedBitArray64</param>
  85. /// <returns>True if convertion was a success</returns>
  86. public static bool TryGetSerializeBitArray64(this SerializedProperty serializedProperty, out SerializedBitArray64 serializedBitArray)
  87. {
  88. serializedBitArray = null;
  89. if (!IsBitArrayOfCapacity(serializedProperty, 64u))
  90. return false;
  91. serializedBitArray = new SerializedBitArray64(serializedProperty);
  92. return true;
  93. }
  94. /// <summary>Convert to 128bit</summary>
  95. /// <param name="serializedProperty">The SerializedProperty</param>
  96. /// <returns>A SerializedBitArray128</returns>
  97. public static SerializedBitArray128 ToSerializeBitArray128(this SerializedProperty serializedProperty)
  98. {
  99. if (!IsBitArrayOfCapacity(serializedProperty, 128u))
  100. throw new Exception("Cannot get SerializeBitArray of this Capacity");
  101. return new SerializedBitArray128(serializedProperty);
  102. }
  103. /// <summary>Try convert to 128bit</summary>
  104. /// <param name="serializedProperty">The SerializedProperty</param>
  105. /// <param name="serializedBitArray">Out SerializedBitArray128</param>
  106. /// <returns>True if convertion was a success</returns>
  107. public static bool TryGetSerializeBitArray128(this SerializedProperty serializedProperty, out SerializedBitArray128 serializedBitArray)
  108. {
  109. serializedBitArray = null;
  110. if (!IsBitArrayOfCapacity(serializedProperty, 128u))
  111. return false;
  112. serializedBitArray = new SerializedBitArray128(serializedProperty);
  113. return true;
  114. }
  115. /// <summary>Convert to 256bit</summary>
  116. /// <param name="serializedProperty">The SerializedProperty</param>
  117. /// <returns>A SerializedBitArray256</returns>
  118. public static SerializedBitArray256 ToSerializeBitArray256(this SerializedProperty serializedProperty)
  119. {
  120. if (!IsBitArrayOfCapacity(serializedProperty, 256u))
  121. throw new Exception("Cannot get SerializeBitArray of this Capacity");
  122. return new SerializedBitArray256(serializedProperty);
  123. }
  124. /// <summary>Try convert to 256bit</summary>
  125. /// <param name="serializedProperty">The SerializedProperty</param>
  126. /// <param name="serializedBitArray">Out SerializedBitArray256</param>
  127. /// <returns>True if convertion was a success</returns>
  128. public static bool TryGetSerializeBitArray256(this SerializedProperty serializedProperty, out SerializedBitArray256 serializedBitArray)
  129. {
  130. serializedBitArray = null;
  131. if (!IsBitArrayOfCapacity(serializedProperty, 256u))
  132. return false;
  133. serializedBitArray = new SerializedBitArray256(serializedProperty);
  134. return true;
  135. }
  136. static bool IsBitArrayOfCapacity(SerializedProperty serializedProperty, uint capacity)
  137. {
  138. const string baseTypeName = "BitArray";
  139. string type = serializedProperty.type;
  140. uint serializedCapacity;
  141. return type.StartsWith(baseTypeName)
  142. && uint.TryParse(type.Substring(baseTypeName.Length), out serializedCapacity)
  143. && capacity == serializedCapacity;
  144. }
  145. }
  146. /// <summary>interface to handle generic SerializedBitArray</summary>
  147. public interface ISerializedBitArray
  148. {
  149. /// <summary>Capacity of the bitarray</summary>
  150. uint capacity { get; }
  151. /// <summary>Get the bit at given index</summary>
  152. /// <param name="bitIndex">The index</param>
  153. /// <returns>Bit value</returns>
  154. bool GetBitAt(uint bitIndex);
  155. /// <summary>Set the bit at given index</summary>
  156. /// <param name="bitIndex">The index</param>
  157. /// <param name="value">The value</param>
  158. void SetBitAt(uint bitIndex, bool value);
  159. /// <summary>Does the bit at given index have multiple different values?</summary>
  160. /// <param name="bitIndex">The index</param>
  161. /// <returns>True: Multiple different value</returns>
  162. bool HasBitMultipleDifferentValue(uint bitIndex);
  163. }
  164. /// <summary>Abstract base classe of all SerializedBitArray</summary>
  165. public abstract class SerializedBitArray : ISerializedBitArray
  166. {
  167. // Note: this should be exposed at the same time as issue with type other than Int32 is fixed on C++ side
  168. /// <summary>Set the bit at given index</summary>
  169. protected static Action<SerializedProperty, int, bool> SetBitAtIndexForAllTargetsImmediate;
  170. /// <summary>Has multiple differente value bitwise</summary>
  171. protected static Func<SerializedProperty, int> HasMultipleDifferentValuesBitwise;
  172. static SerializedBitArray()
  173. {
  174. var type = typeof(SerializedProperty);
  175. var setBitAtIndexForAllTargetsImmediateMethodInfo = type.GetMethod("SetBitAtIndexForAllTargetsImmediate", BindingFlags.Instance | BindingFlags.NonPublic);
  176. var hasMultipleDifferentValuesBitwisePropertyInfo = type.GetProperty("hasMultipleDifferentValuesBitwise", BindingFlags.Instance | BindingFlags.NonPublic);
  177. var serializedPropertyParameter = Expression.Parameter(typeof(SerializedProperty), "property");
  178. var indexParameter = Expression.Parameter(typeof(int), "index");
  179. var valueParameter = Expression.Parameter(typeof(bool), "value");
  180. var hasMultipleDifferentValuesBitwiseProperty = Expression.Property(serializedPropertyParameter, hasMultipleDifferentValuesBitwisePropertyInfo);
  181. var setBitAtIndexForAllTargetsImmediateCall = Expression.Call(serializedPropertyParameter, setBitAtIndexForAllTargetsImmediateMethodInfo, indexParameter, valueParameter);
  182. var setBitAtIndexForAllTargetsImmediateLambda = Expression.Lambda<Action<SerializedProperty, int, bool>>(setBitAtIndexForAllTargetsImmediateCall, serializedPropertyParameter, indexParameter, valueParameter);
  183. var hasMultipleDifferentValuesBitwiseLambda = Expression.Lambda<Func<SerializedProperty, int>>(hasMultipleDifferentValuesBitwiseProperty, serializedPropertyParameter);
  184. SetBitAtIndexForAllTargetsImmediate = setBitAtIndexForAllTargetsImmediateLambda.Compile();
  185. HasMultipleDifferentValuesBitwise = hasMultipleDifferentValuesBitwiseLambda.Compile();
  186. }
  187. /// <summary>The underlying serialized property</summary>
  188. protected SerializedProperty m_SerializedProperty;
  189. SerializedProperty[] m_SerializedProperties;
  190. /// <summary>Capacity of the bitarray</summary>
  191. public uint capacity { get; }
  192. internal SerializedBitArray(SerializedProperty serializedProperty, uint capacity)
  193. {
  194. this.capacity = capacity;
  195. m_SerializedProperty = serializedProperty;
  196. }
  197. /// <summary>Initialisation of dedicated SerializedPropertiws</summary>
  198. /// <returns>Arrays of SerializedProperty</returns>
  199. protected SerializedProperty[] GetOrInitializeSerializedProperties()
  200. {
  201. if (m_SerializedProperties == null)
  202. {
  203. UnityEngine.Object[] targets = m_SerializedProperty.serializedObject.targetObjects;
  204. int size = targets.Length;
  205. if (size == 1)
  206. m_SerializedProperties = new[] { m_SerializedProperty };
  207. else
  208. {
  209. string propertyPath = m_SerializedProperty.propertyPath;
  210. m_SerializedProperties = new SerializedProperty[size];
  211. for (int i = 0; i < size; ++i)
  212. {
  213. m_SerializedProperties[i] = new SerializedObject(targets[i]).FindProperty(propertyPath);
  214. }
  215. }
  216. }
  217. return m_SerializedProperties;
  218. }
  219. /// <summary>Does the bit at given index have multiple different values?</summary>
  220. /// <param name="bitIndex">The index</param>
  221. /// <returns>True: Multiple different value</returns>
  222. public bool HasBitMultipleDifferentValue(uint bitIndex)
  223. {
  224. if (bitIndex >= capacity)
  225. throw new IndexOutOfRangeException("Index out of bound in BitArray" + capacity);
  226. return HasBitMultipleDifferentValue_Internal(bitIndex);
  227. }
  228. /// <summary>Say if the properties have differente values</summary>
  229. /// <param name="bitIndex">The index</param>
  230. /// <returns>True: properties have different value</returns>
  231. abstract protected bool HasBitMultipleDifferentValue_Internal(uint bitIndex);
  232. /// <summary>
  233. /// Safety: serializedProperty must match its path
  234. /// </summary>
  235. /// <param name="propertyPath">serializedProperty must match its path</param>
  236. /// <param name="serializedProperty">serializedProperty must match its path</param>
  237. /// <param name="bitIndex"></param>
  238. /// <returns></returns>
  239. unsafe protected bool HasBitMultipleDifferentValue_For64Bits(string propertyPath, SerializedProperty serializedProperty, uint bitIndex)
  240. {
  241. if (!serializedProperty.hasMultipleDifferentValues)
  242. return false;
  243. var serializedProperties = GetOrInitializeSerializedProperties();
  244. int length = serializedProperties.Length;
  245. ulong mask = 1uL << (int)bitIndex;
  246. bool value = ((ulong)m_SerializedProperties[0].FindPropertyRelative(propertyPath).longValue & mask) != 0uL;
  247. for (int i = 1; i < length; ++i)
  248. {
  249. if ((((ulong)m_SerializedProperties[i].FindPropertyRelative(propertyPath).longValue & mask) != 0uL) ^ value)
  250. return true;
  251. }
  252. return false;
  253. }
  254. /// <summary>Get the bit at given index</summary>
  255. /// <param name="bitIndex">The index</param>
  256. /// <returns>Bit value</returns>
  257. public bool GetBitAt(uint bitIndex)
  258. {
  259. if (bitIndex >= capacity)
  260. throw new IndexOutOfRangeException("Index out of bound in BitArray" + capacity);
  261. return GetBitAt_Internal(bitIndex);
  262. }
  263. /// <summary>Get the value at index</summary>
  264. /// <param name="bitIndex">The index</param>
  265. /// <returns>Value at the index</returns>
  266. abstract protected bool GetBitAt_Internal(uint bitIndex);
  267. /// <summary>Set the bit at given index</summary>
  268. /// <param name="bitIndex">The index</param>
  269. /// <param name="value">The value</param>
  270. public void SetBitAt(uint bitIndex, bool value)
  271. {
  272. if (bitIndex >= capacity)
  273. throw new IndexOutOfRangeException("Index out of bound in BitArray" + capacity);
  274. SetBitAt_Internal(bitIndex, value);
  275. }
  276. /// <summary>Set the bit at given index</summary>
  277. /// <param name="bitIndex">The index</param>
  278. /// <param name="value">The value</param>
  279. abstract protected void SetBitAt_Internal(uint bitIndex, bool value);
  280. /// <summary>Sync again every serializedProperty</summary>
  281. protected void ResyncSerialization()
  282. {
  283. foreach (var property in m_SerializedProperties)
  284. property.serializedObject.ApplyModifiedProperties();
  285. Update();
  286. }
  287. /// <summary>Sync the reflected value with target value change</summary>
  288. public void Update()
  289. {
  290. foreach (var property in m_SerializedProperties)
  291. property.serializedObject.Update();
  292. m_SerializedProperty.serializedObject.Update();
  293. }
  294. }
  295. /// <summary>SerializedBitArray spetialized for 8bit capacity</summary>
  296. public sealed class SerializedBitArray8 : SerializedBitArray
  297. {
  298. SerializedProperty m_Data;
  299. /// <summary>Constructor</summary>
  300. /// <param name="serializedProperty">The SerializedProperty</param>
  301. public SerializedBitArray8(SerializedProperty serializedProperty) : base(serializedProperty, 8u)
  302. => m_Data = m_SerializedProperty.FindPropertyRelative("data");
  303. /// <summary>Say if the properties have differente values</summary>
  304. /// <param name="bitIndex">The index</param>
  305. /// <returns>True: properties have different value</returns>
  306. protected override bool HasBitMultipleDifferentValue_Internal(uint bitIndex)
  307. => (HasMultipleDifferentValuesBitwise(m_Data) & (1 << (int)bitIndex)) != 0;
  308. /// <summary>Get the value at index</summary>
  309. /// <param name="bitIndex">The index</param>
  310. /// <returns>Value at the index</returns>
  311. protected override bool GetBitAt_Internal(uint bitIndex)
  312. => BitArrayUtilities.Get8(bitIndex, (byte)m_Data.intValue);
  313. /// <summary>Set the bit at given index</summary>
  314. /// <param name="bitIndex">The index</param>
  315. /// <param name="value">The value</param>
  316. protected override void SetBitAt_Internal(uint bitIndex, bool value)
  317. {
  318. foreach (var property in GetOrInitializeSerializedProperties())
  319. {
  320. byte versionedData = (byte)property.FindPropertyRelative("data").intValue;
  321. BitArrayUtilities.Set8(bitIndex, ref versionedData, value);
  322. property.FindPropertyRelative("data").intValue = versionedData;
  323. }
  324. ResyncSerialization();
  325. }
  326. }
  327. /// <summary>SerializedBitArray spetialized for 16bit capacity</summary>
  328. public sealed class SerializedBitArray16 : SerializedBitArray
  329. {
  330. SerializedProperty m_Data;
  331. /// <summary>Constructor</summary>
  332. /// <param name="serializedProperty">The SerializedProperty</param>
  333. public SerializedBitArray16(SerializedProperty serializedProperty) : base(serializedProperty, 16u)
  334. => m_Data = m_SerializedProperty.FindPropertyRelative("data");
  335. /// <summary>Say if the properties have differente values</summary>
  336. /// <param name="bitIndex">The index</param>
  337. /// <returns>True: properties have different value</returns>
  338. protected override bool HasBitMultipleDifferentValue_Internal(uint bitIndex)
  339. => (HasMultipleDifferentValuesBitwise(m_Data) & (1 << (int)bitIndex)) != 0;
  340. /// <summary>Get the value at index</summary>
  341. /// <param name="bitIndex">The index</param>
  342. /// <returns>Value at the index</returns>
  343. protected override bool GetBitAt_Internal(uint bitIndex)
  344. => BitArrayUtilities.Get16(bitIndex, (ushort)m_Data.intValue);
  345. /// <summary>Set the bit at given index</summary>
  346. /// <param name="bitIndex">The index</param>
  347. /// <param name="value">The value</param>
  348. protected override void SetBitAt_Internal(uint bitIndex, bool value)
  349. {
  350. foreach (var property in GetOrInitializeSerializedProperties())
  351. {
  352. ushort versionedData = (ushort)property.FindPropertyRelative("data").intValue;
  353. BitArrayUtilities.Set16(bitIndex, ref versionedData, value);
  354. property.FindPropertyRelative("data").intValue = versionedData;
  355. }
  356. ResyncSerialization();
  357. }
  358. }
  359. /// <summary>SerializedBitArray spetialized for 32bit capacity</summary>
  360. public sealed class SerializedBitArray32 : SerializedBitArray
  361. {
  362. SerializedProperty m_Data;
  363. /// <summary>Constructor</summary>
  364. /// <param name="serializedProperty">The SerializedProperty</param>
  365. public SerializedBitArray32(SerializedProperty serializedProperty) : base(serializedProperty, 32u)
  366. => m_Data = m_SerializedProperty.FindPropertyRelative("data");
  367. /// <summary>Say if the properties have differente values</summary>
  368. /// <param name="bitIndex">The index</param>
  369. /// <returns>True: properties have different value</returns>
  370. protected override bool HasBitMultipleDifferentValue_Internal(uint bitIndex)
  371. => (HasMultipleDifferentValuesBitwise(m_Data) & (1 << (int)bitIndex)) != 0;
  372. /// <summary>Get the value at index</summary>
  373. /// <param name="bitIndex">The index</param>
  374. /// <returns>Value at the index</returns>
  375. protected override bool GetBitAt_Internal(uint bitIndex)
  376. => BitArrayUtilities.Get32(bitIndex, (uint)m_Data.intValue);
  377. /// <summary>Set the bit at given index</summary>
  378. /// <param name="bitIndex">The index</param>
  379. /// <param name="value">The value</param>
  380. protected override void SetBitAt_Internal(uint bitIndex, bool value)
  381. {
  382. foreach (var property in GetOrInitializeSerializedProperties())
  383. {
  384. int versionedData = property.FindPropertyRelative("data").intValue;
  385. uint trueData;
  386. unsafe
  387. {
  388. trueData = *(uint*)(&versionedData);
  389. }
  390. BitArrayUtilities.Set32(bitIndex, ref trueData, value);
  391. unsafe
  392. {
  393. versionedData = *(int*)(&trueData);
  394. }
  395. property.FindPropertyRelative("data").intValue = versionedData;
  396. }
  397. ResyncSerialization();
  398. }
  399. }
  400. /// <summary>SerializedBitArray spetialized for 64bit capacity</summary>
  401. public sealed class SerializedBitArray64 : SerializedBitArray
  402. {
  403. SerializedProperty m_Data;
  404. /// <summary>Constructor</summary>
  405. /// <param name="serializedProperty">The SerializedProperty</param>
  406. public SerializedBitArray64(SerializedProperty serializedProperty) : base(serializedProperty, 64u)
  407. => m_Data = m_SerializedProperty.FindPropertyRelative("data");
  408. /// <summary>Say if the properties have differente values</summary>
  409. /// <param name="bitIndex">The index</param>
  410. /// <returns>True: properties have different value</returns>
  411. protected override bool HasBitMultipleDifferentValue_Internal(uint bitIndex)
  412. => HasBitMultipleDifferentValue_For64Bits("data", m_Data, bitIndex);
  413. /// <summary>Get the value at index</summary>
  414. /// <param name="bitIndex">The index</param>
  415. /// <returns>Value at the index</returns>
  416. protected override bool GetBitAt_Internal(uint bitIndex)
  417. => BitArrayUtilities.Get64(bitIndex, (ulong)m_Data.longValue);
  418. /// <summary>Set the bit at given index</summary>
  419. /// <param name="bitIndex">The index</param>
  420. /// <param name="value">The value</param>
  421. protected override void SetBitAt_Internal(uint bitIndex, bool value)
  422. {
  423. foreach (var property in GetOrInitializeSerializedProperties())
  424. {
  425. long versionedData = property.FindPropertyRelative("data").longValue;
  426. ulong trueData;
  427. unsafe
  428. {
  429. trueData = *(ulong*)(&versionedData);
  430. }
  431. BitArrayUtilities.Set64(bitIndex, ref trueData, value);
  432. unsafe
  433. {
  434. versionedData = *(long*)(&trueData);
  435. }
  436. property.FindPropertyRelative("data").longValue = versionedData;
  437. }
  438. ResyncSerialization();
  439. }
  440. }
  441. /// <summary>SerializedBitArray spetialized for 128bit capacity</summary>
  442. public sealed class SerializedBitArray128 : SerializedBitArray
  443. {
  444. SerializedProperty m_Data1;
  445. SerializedProperty m_Data2;
  446. /// <summary>Constructor</summary>
  447. /// <param name="serializedProperty">The SerializedProperty</param>
  448. public SerializedBitArray128(SerializedProperty serializedProperty) : base(serializedProperty, 128u)
  449. {
  450. m_Data1 = m_SerializedProperty.FindPropertyRelative("data1");
  451. m_Data2 = m_SerializedProperty.FindPropertyRelative("data2");
  452. }
  453. /// <summary>Say if the properties have differente values</summary>
  454. /// <param name="bitIndex">The index</param>
  455. /// <returns>True: properties have different value</returns>
  456. protected override bool HasBitMultipleDifferentValue_Internal(uint bitIndex)
  457. => bitIndex < 64u
  458. ? HasBitMultipleDifferentValue_For64Bits("data1", m_Data1, bitIndex)
  459. : HasBitMultipleDifferentValue_For64Bits("data2", m_Data2, bitIndex - 64u);
  460. /// <summary>Get the value at index</summary>
  461. /// <param name="bitIndex">The index</param>
  462. /// <returns>Value at the index</returns>
  463. protected override bool GetBitAt_Internal(uint bitIndex)
  464. => BitArrayUtilities.Get128(
  465. bitIndex,
  466. (ulong)m_SerializedProperty.FindPropertyRelative("data1").longValue,
  467. (ulong)m_SerializedProperty.FindPropertyRelative("data2").longValue);
  468. /// <summary>Set the bit at given index</summary>
  469. /// <param name="bitIndex">The index</param>
  470. /// <param name="value">The value</param>
  471. protected override void SetBitAt_Internal(uint bitIndex, bool value)
  472. {
  473. foreach (var property in GetOrInitializeSerializedProperties())
  474. {
  475. long versionedData1 = property.FindPropertyRelative("data1").longValue;
  476. long versionedData2 = property.FindPropertyRelative("data2").longValue;
  477. ulong trueData1;
  478. ulong trueData2;
  479. unsafe
  480. {
  481. trueData1 = *(ulong*)(&versionedData1);
  482. trueData2 = *(ulong*)(&versionedData2);
  483. }
  484. BitArrayUtilities.Set128(bitIndex, ref trueData1, ref trueData2, value);
  485. unsafe
  486. {
  487. versionedData1 = *(long*)(&trueData1);
  488. versionedData2 = *(long*)(&trueData2);
  489. }
  490. property.FindPropertyRelative("data1").longValue = versionedData1;
  491. property.FindPropertyRelative("data2").longValue = versionedData2;
  492. }
  493. ResyncSerialization();
  494. }
  495. }
  496. /// <summary>SerializedBitArray spetialized for 256bit capacity</summary>
  497. public sealed class SerializedBitArray256 : SerializedBitArray
  498. {
  499. SerializedProperty m_Data1;
  500. SerializedProperty m_Data2;
  501. SerializedProperty m_Data3;
  502. SerializedProperty m_Data4;
  503. /// <summary>Constructor</summary>
  504. /// <param name="serializedProperty">The SerializedProperty</param>
  505. public SerializedBitArray256(SerializedProperty serializedProperty) : base(serializedProperty, 128u)
  506. {
  507. m_Data1 = m_SerializedProperty.FindPropertyRelative("data1");
  508. m_Data2 = m_SerializedProperty.FindPropertyRelative("data2");
  509. m_Data3 = m_SerializedProperty.FindPropertyRelative("data3");
  510. m_Data4 = m_SerializedProperty.FindPropertyRelative("data4");
  511. }
  512. /// <summary>Say if the properties have differente values</summary>
  513. /// <param name="bitIndex">The index</param>
  514. /// <returns>True: properties have different value</returns>
  515. protected override bool HasBitMultipleDifferentValue_Internal(uint bitIndex)
  516. => bitIndex < 128u
  517. ? bitIndex < 64u
  518. ? HasBitMultipleDifferentValue_For64Bits("data1", m_Data1, bitIndex)
  519. : HasBitMultipleDifferentValue_For64Bits("data2", m_Data2, bitIndex - 64u)
  520. : bitIndex < 192u
  521. ? HasBitMultipleDifferentValue_For64Bits("data3", m_Data3, bitIndex - 128u)
  522. : HasBitMultipleDifferentValue_For64Bits("data4", m_Data4, bitIndex - 192u);
  523. /// <summary>Get the value at index</summary>
  524. /// <param name="bitIndex">The index</param>
  525. /// <returns>Value at the index</returns>
  526. protected override bool GetBitAt_Internal(uint bitIndex)
  527. => BitArrayUtilities.Get256(
  528. bitIndex,
  529. (ulong)m_SerializedProperty.FindPropertyRelative("data1").longValue,
  530. (ulong)m_SerializedProperty.FindPropertyRelative("data2").longValue,
  531. (ulong)m_SerializedProperty.FindPropertyRelative("data3").longValue,
  532. (ulong)m_SerializedProperty.FindPropertyRelative("data4").longValue);
  533. /// <summary>Set the bit at given index</summary>
  534. /// <param name="bitIndex">The index</param>
  535. /// <param name="value">The value</param>
  536. protected override void SetBitAt_Internal(uint bitIndex, bool value)
  537. {
  538. foreach (var property in GetOrInitializeSerializedProperties())
  539. {
  540. long versionedData1 = property.FindPropertyRelative("data1").longValue;
  541. long versionedData2 = property.FindPropertyRelative("data2").longValue;
  542. long versionedData3 = property.FindPropertyRelative("data3").longValue;
  543. long versionedData4 = property.FindPropertyRelative("data4").longValue;
  544. ulong trueData1;
  545. ulong trueData2;
  546. ulong trueData3;
  547. ulong trueData4;
  548. unsafe
  549. {
  550. trueData1 = *(ulong*)(&versionedData1);
  551. trueData2 = *(ulong*)(&versionedData2);
  552. trueData3 = *(ulong*)(&versionedData3);
  553. trueData4 = *(ulong*)(&versionedData4);
  554. }
  555. BitArrayUtilities.Set256(bitIndex, ref trueData1, ref trueData2, ref trueData3, ref trueData4, value);
  556. unsafe
  557. {
  558. versionedData1 = *(long*)(&trueData1);
  559. versionedData2 = *(long*)(&trueData2);
  560. versionedData3 = *(long*)(&trueData3);
  561. versionedData4 = *(long*)(&trueData4);
  562. }
  563. property.FindPropertyRelative("data1").longValue = versionedData1;
  564. property.FindPropertyRelative("data2").longValue = versionedData2;
  565. property.FindPropertyRelative("data3").longValue = versionedData3;
  566. property.FindPropertyRelative("data4").longValue = versionedData4;
  567. }
  568. ResyncSerialization();
  569. }
  570. }
  571. }