Dreamine.Hybrid 1.0.3
Dreamine.Hybrid 프로젝트의 API와 구성 요소를 제공합니다.
로딩중...
검색중...
일치하는것 없음
HybridStateStore.cs
이 파일의 문서화 페이지로 가기
2using System;
3using System.Threading;
4
6{
23 public sealed class HybridStateStore<TState> : IHybridStateStore<TState>
24 {
33 private readonly object _syncRoot = new();
42 private TState _state;
43
60 public HybridStateStore(TState initialState)
61 {
62 _state = initialState;
63 }
64
73 public event EventHandler<HybridStateChangedEventArgs<TState>>? StateChanged;
74
107 public IDisposable Subscribe(EventHandler<HybridStateChangedEventArgs<TState>> handler)
108 {
109 if (handler is null)
110 {
111 throw new ArgumentNullException(nameof(handler));
112 }
113
114 StateChanged += handler;
115 return new StateSubscription(this, handler);
116 }
117
126 public TState State
127 {
128 get
129 {
130 lock (_syncRoot)
131 {
132 return _state;
133 }
134 }
135 }
136
153 public void SetState(TState state)
154 {
155 TState snapshot;
156
157 lock (_syncRoot)
158 {
159 _state = state;
160 // Capture the snapshot inside the lock so the event argument always
161 // reflects the stored value at the time of assignment, even when
162 // concurrent SetState calls race. Subscribers receive the state that
163 // was actually committed, not a stale caller-held reference.
164 snapshot = _state;
165 }
166
167 OnStateChanged(snapshot);
168 }
169
194 public void Update(Func<TState, TState> updater)
195 {
196 if (updater is null)
197 {
198 throw new ArgumentNullException(nameof(updater));
199 }
200
201 TState snapshot;
202
203 lock (_syncRoot)
204 {
205 snapshot = updater(_state);
206 _state = snapshot;
207 }
208
209 OnStateChanged(snapshot);
210 }
211
228 private void OnStateChanged(TState state)
229 {
230 StateChanged?.Invoke(this, new HybridStateChangedEventArgs<TState>(state));
231 }
232
241 private sealed class StateSubscription : IDisposable
242 {
260 private EventHandler<HybridStateChangedEventArgs<TState>>? _handler;
261
288 EventHandler<HybridStateChangedEventArgs<TState>> handler)
289 {
290 _store = store;
291 _handler = handler;
292 }
293
302 public void Dispose()
303 {
304 // Interlocked.Exchange ensures the handler is cleared and unsubscribed
305 // exactly once even when Dispose is called concurrently.
306 var handler = Interlocked.Exchange(ref _handler, null);
307 if (handler is null)
308 {
309 return;
310 }
311
312 _store.StateChanged -= handler;
313 }
314 }
315 }
316}
void Update(Func< TState, TState > updater)
IDisposable Subscribe(EventHandler< HybridStateChangedEventArgs< TState > > handler)
EventHandler< HybridStateChangedEventArgs< TState > >? StateChanged
readonly HybridStateStore< TState > _store
StateSubscription(HybridStateStore< TState > store, EventHandler< HybridStateChangedEventArgs< TState > > handler)
EventHandler< HybridStateChangedEventArgs< TState > >? _handler