Created
May 28, 2022 19:21
-
-
Save julesx/2ca4a68cb5304dc9fc30cab1cc3d1033 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CrazyTag : ICrazyTag | |
{ | |
protected readonly List<Subscription> observables = new List<Subscription>(); | |
protected readonly List<IObserver<ICrazyTag>> observers = new List<IObserver<ICrazyTag>>(); | |
bool disposedValue = false; | |
protected CrazyTag() { } | |
IDisposable IObservable<ICrazyTag>.Subscribe(IObserver<ICrazyTag> observer) | |
{ | |
if (!observers.Contains(observer)) | |
{ | |
observers.Add(observer); | |
observer.OnNext(this); //--> or not...maybe you'd set some InitialSubscription state | |
//--> to help the observer distinguish initial notification from changes | |
} | |
return new Subscription(this, observer, observers); | |
} | |
public bool SubscribeToTag(ICrazyTag tag) | |
{ | |
if (observables.Any(subscription => subscription.Tag == tag)) return false; //--> could throw here | |
observables.Add((Subscription)tag.Subscribe(this)); | |
return true; | |
} | |
public void ClearSubscriptions() | |
{ | |
while (observables.Count > 0) | |
{ | |
var sub = observables[0]; | |
observables.RemoveAt(0); | |
((IDisposable)sub).Dispose(); | |
} | |
} | |
public bool UnsubscribeFromTag(ICrazyTag tag) | |
{ | |
observables.RemoveAll(subscription => subscription.Tag == tag); | |
return true; | |
} | |
protected void Notify() => observers.ForEach(observer => observer.OnNext(this)); | |
public virtual void OnNext(ICrazyTag value) { } | |
public virtual void OnError(Exception error) { } | |
public virtual void OnCompleted() { } | |
public Type TagType => GetType(); | |
protected virtual void Dispose(bool disposing) | |
{ | |
if (!disposedValue) | |
{ | |
if (disposing) | |
{ | |
while (observables.Count > 0) | |
{ | |
var sub = observables[0]; | |
observables.RemoveAt(0); | |
((IDisposable)sub).Dispose(); | |
} | |
} | |
disposedValue = true; | |
} | |
} | |
public void Dispose() | |
{ | |
Dispose(true); | |
} | |
protected sealed class Subscription : IDisposable | |
{ | |
readonly WeakReference<CrazyTag> tag; | |
readonly List<IObserver<ICrazyTag>> observers; | |
readonly IObserver<ICrazyTag> observer; | |
internal Subscription(CrazyTag tag, IObserver<ICrazyTag> observer, List<IObserver<ICrazyTag>> observers) | |
{ | |
this.tag = new WeakReference<CrazyTag>(tag); | |
this.observers = observers; | |
this.observer = observer; | |
} | |
void IDisposable.Dispose() | |
{ | |
if (observers.Contains(observer)) observers.Remove(observer); | |
} | |
public CrazyTag Tag | |
{ | |
get | |
{ | |
if (tag.TryGetTarget(out CrazyTag target)) | |
{ | |
return target; | |
} | |
return null; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment