ReactiveObject.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. using System;
  2. using System.Threading;
  3. namespace Ryujinx.Common
  4. {
  5. public class ReactiveObject<T>
  6. {
  7. private ReaderWriterLock _readerWriterLock = new ReaderWriterLock();
  8. private bool _isInitialized = false;
  9. private T _value;
  10. public event EventHandler<ReactiveEventArgs<T>> Event;
  11. public T Value
  12. {
  13. get
  14. {
  15. _readerWriterLock.AcquireReaderLock(Timeout.Infinite);
  16. T value = _value;
  17. _readerWriterLock.ReleaseReaderLock();
  18. return value;
  19. }
  20. set
  21. {
  22. _readerWriterLock.AcquireWriterLock(Timeout.Infinite);
  23. T oldValue = _value;
  24. bool oldIsInitialized = _isInitialized;
  25. _isInitialized = true;
  26. _value = value;
  27. _readerWriterLock.ReleaseWriterLock();
  28. if (!oldIsInitialized || oldValue == null || !oldValue.Equals(_value))
  29. {
  30. Event?.Invoke(this, new ReactiveEventArgs<T>(oldValue, value));
  31. }
  32. }
  33. }
  34. public static implicit operator T(ReactiveObject<T> obj)
  35. {
  36. return obj.Value;
  37. }
  38. }
  39. public class ReactiveEventArgs<T>
  40. {
  41. public T OldValue { get; }
  42. public T NewValue { get; }
  43. public ReactiveEventArgs(T oldValue, T newValue)
  44. {
  45. OldValue = oldValue;
  46. NewValue = newValue;
  47. }
  48. }
  49. }