aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Common/ReactiveObject.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Common/ReactiveObject.cs')
-rw-r--r--src/Ryujinx.Common/ReactiveObject.cs61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/Ryujinx.Common/ReactiveObject.cs b/src/Ryujinx.Common/ReactiveObject.cs
new file mode 100644
index 00000000..44897f26
--- /dev/null
+++ b/src/Ryujinx.Common/ReactiveObject.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Threading;
+
+namespace Ryujinx.Common
+{
+ public class ReactiveObject<T>
+ {
+ private ReaderWriterLock _readerWriterLock = new ReaderWriterLock();
+ private bool _isInitialized = false;
+ private T _value;
+
+ public event EventHandler<ReactiveEventArgs<T>> Event;
+
+ public T Value
+ {
+ get
+ {
+ _readerWriterLock.AcquireReaderLock(Timeout.Infinite);
+ T value = _value;
+ _readerWriterLock.ReleaseReaderLock();
+
+ return value;
+ }
+ set
+ {
+ _readerWriterLock.AcquireWriterLock(Timeout.Infinite);
+
+ T oldValue = _value;
+
+ bool oldIsInitialized = _isInitialized;
+
+ _isInitialized = true;
+ _value = value;
+
+ _readerWriterLock.ReleaseWriterLock();
+
+ if (!oldIsInitialized || oldValue == null || !oldValue.Equals(_value))
+ {
+ Event?.Invoke(this, new ReactiveEventArgs<T>(oldValue, value));
+ }
+ }
+ }
+
+ public static implicit operator T(ReactiveObject<T> obj)
+ {
+ return obj.Value;
+ }
+ }
+
+ public class ReactiveEventArgs<T>
+ {
+ public T OldValue { get; }
+ public T NewValue { get; }
+
+ public ReactiveEventArgs(T oldValue, T newValue)
+ {
+ OldValue = oldValue;
+ NewValue = newValue;
+ }
+ }
+}