ReactiveObject.cs 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. using System;
  2. using System.Threading;
  3. namespace Ryujinx.Common
  4. {
  5. public class ReactiveObject<T>
  6. {
  7. private readonly ReaderWriterLockSlim _readerWriterLock = new();
  8. private bool _isInitialized;
  9. private T _value;
  10. public event EventHandler<ReactiveEventArgs<T>> Event;
  11. public T Value
  12. {
  13. get
  14. {
  15. _readerWriterLock.EnterReadLock();
  16. T value = _value;
  17. _readerWriterLock.ExitReadLock();
  18. return value;
  19. }
  20. set
  21. {
  22. _readerWriterLock.EnterWriteLock();
  23. T oldValue = _value;
  24. bool oldIsInitialized = _isInitialized;
  25. _isInitialized = true;
  26. _value = value;
  27. _readerWriterLock.ExitWriteLock();
  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>(T oldValue, T newValue)
  40. {
  41. public T OldValue { get; } = oldValue;
  42. public T NewValue { get; } = newValue;
  43. }
  44. }