-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReactiveProperty.cs
102 lines (90 loc) · 2.8 KB
/
ReactiveProperty.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// ********************************************************************
//
// Copyright (c) RimuruDev
// Contact information:
// Email: rimuru.dev@gmail.com
// GitHub: https://github.com/RimuruDev
// LinkedIn: https://www.linkedin.com/in/rimuru/
//
// ********************************************************************
// ReSharper disable CheckNamespace
using System;
using UnityEngine;
namespace RimuruDev
{
[Serializable]
[HelpURL("https://github.com/RimuruDev/Unity-ReactiveProperty-Helper.git")]
public class ReactiveProperty<T>
{
[SerializeField] private T value;
[NonSerialized] private Action<T> onChanged;
public ReactiveProperty(T initialValue = default)
{
value = initialValue;
}
public event Action<T> OnChanged
{
add
{
onChanged += value;
value?.Invoke(this.value);
}
remove => onChanged -= value;
}
public T Value
{
get => value;
set
{
this.value = value;
onChanged?.Invoke(value);
}
}
public void OnNext(T nextValue)
{
Value = nextValue;
}
/// <summary>
/// Подписка на изменения с поддержкой IDisposable.
/// <example>
/// <code>
/// Пример:
/// 1:
/// private readonly List-IDisposable> subscriptions = new();
///
/// 2:
/// subscriptions.Add(UserName.Subscribe(value => Origin.UserName = value));
///
/// 3:
/// foreach (var subscription in subscriptions)
/// subscription.Dispose();
/// </code>
/// </example>
/// </summary>
/// <param name="callback">Метод обратного вызова.</param>
/// <returns>Объект IDisposable для отписки.</returns>
public IDisposable Subscribe(Action<T> callback)
{
OnChanged += callback;
// NOTE: Возвращаем объект, который при Dispose выполнит отписку.
return new DisposableAction(() => OnChanged -= callback);
}
private class DisposableAction : IDisposable
{
private readonly Action disposeAction;
private bool isDisposed;
public DisposableAction(Action disposeAction)
{
this.disposeAction = disposeAction;
}
public void Dispose()
{
if (!isDisposed)
{
disposeAction?.Invoke();
isDisposed = true;
}
}
}
}
}