Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ReactiveValue.cs 2.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Svelto.ECS
  4. {
  5. /// <summary>
  6. /// Reasons why unfortunately this cannot be a struct:
  7. /// the user must remember to create interface with ref getters
  8. /// ref getters cannot have set, while we sometimes use set to initialise values
  9. /// the struct will be valid even if it has not ever been initialised
  10. ///
  11. /// 1 and 3 are possibly solvable, but 2 is a problem
  12. /// </summary>
  13. /// <typeparam name="T"></typeparam>{
  14. public class ReactiveValue<T>
  15. {
  16. public ReactiveValue
  17. (EntityReference senderID, Action<EntityReference, T> callback, T initialValue = default
  18. , bool notifyImmediately = false, ReactiveType notifyOnChange = ReactiveType.ReactOnChange)
  19. {
  20. _subscriber = callback;
  21. if (notifyImmediately)
  22. _subscriber(_senderID, initialValue);
  23. _senderID = senderID;
  24. _value = initialValue;
  25. _notifyOnChange = notifyOnChange;
  26. }
  27. public ReactiveValue(EntityReference senderID, Action<EntityReference, T> callback, ReactiveType notifyOnChange)
  28. {
  29. _subscriber = callback;
  30. _notifyOnChange = notifyOnChange;
  31. _senderID = senderID;
  32. }
  33. public T value
  34. {
  35. set
  36. {
  37. if (_notifyOnChange == ReactiveType.ReactOnSet ||
  38. EqualityComparer<T>.Default.Equals(_value) == false)
  39. {
  40. if (_paused == false)
  41. _subscriber(_senderID, value);
  42. //all the subscribers relies on the actual value not being changed yet, as the second parameter
  43. //is the new value
  44. _value = value;
  45. }
  46. }
  47. get => _value;
  48. }
  49. public void PauseNotify()
  50. {
  51. _paused = true;
  52. }
  53. public void ResumeNotify()
  54. {
  55. _paused = false;
  56. }
  57. public void ForceValue(in T value)
  58. {
  59. if (_paused == false)
  60. _subscriber(_senderID, value);
  61. _value = value;
  62. }
  63. public void SetValueWithoutNotify(in T value)
  64. {
  65. _value = value;
  66. }
  67. public void StopNotify()
  68. {
  69. _subscriber = null;
  70. _paused = true;
  71. }
  72. readonly ReactiveType _notifyOnChange;
  73. readonly EntityReference _senderID;
  74. bool _paused;
  75. Action<EntityReference, T> _subscriber;
  76. T _value;
  77. }
  78. public enum ReactiveType
  79. {
  80. ReactOnSet,
  81. ReactOnChange
  82. }
  83. }