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.

97 lines
2.8KB

  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 || _comp.Equals(_value, value) == false)
  38. {
  39. if (_paused == false)
  40. _subscriber(_senderID, value);
  41. //all the subscribers relies on the actual value not being changed yet, as the second parameter
  42. //is the new value
  43. _value = value;
  44. }
  45. }
  46. get => _value;
  47. }
  48. public void PauseNotify()
  49. {
  50. _paused = true;
  51. }
  52. public void ResumeNotify()
  53. {
  54. _paused = false;
  55. }
  56. public void ForceValue(in T value)
  57. {
  58. if (_paused == false)
  59. _subscriber(_senderID, value);
  60. _value = value;
  61. }
  62. public void SetValueWithoutNotify(in T value)
  63. {
  64. _value = value;
  65. }
  66. public void StopNotify()
  67. {
  68. _subscriber = null;
  69. _paused = true;
  70. }
  71. readonly ReactiveType _notifyOnChange;
  72. readonly EntityReference _senderID;
  73. bool _paused;
  74. Action<EntityReference, T> _subscriber;
  75. T _value;
  76. static readonly EqualityComparer<T> _comp = EqualityComparer<T>.Default;
  77. }
  78. public enum ReactiveType
  79. {
  80. ReactOnSet,
  81. ReactOnChange
  82. }
  83. }