1 // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
2 
3 namespace System.Reactive
4 {
5     internal class NopObserver<T> : IObserver<T>
6     {
7         public static readonly IObserver<T> Instance = new NopObserver<T>();
8 
OnCompleted()9         public void OnCompleted()
10         {
11         }
12 
OnError(Exception error)13         public void OnError(Exception error)
14         {
15         }
16 
OnNext(T value)17         public void OnNext(T value)
18         {
19         }
20     }
21 
22     internal class DoneObserver<T> : IObserver<T>
23     {
24         public static readonly IObserver<T> Completed = new DoneObserver<T>();
25 
26         public Exception Exception { get; set; }
27 
OnCompleted()28         public void OnCompleted()
29         {
30         }
31 
OnError(Exception error)32         public void OnError(Exception error)
33         {
34         }
35 
OnNext(T value)36         public void OnNext(T value)
37         {
38         }
39     }
40 
41     internal class DisposedObserver<T> : IObserver<T>
42     {
43         public static readonly IObserver<T> Instance = new DisposedObserver<T>();
44 
OnCompleted()45         public void OnCompleted()
46         {
47             throw new ObjectDisposedException("");
48         }
49 
OnError(Exception error)50         public void OnError(Exception error)
51         {
52             throw new ObjectDisposedException("");
53         }
54 
OnNext(T value)55         public void OnNext(T value)
56         {
57             throw new ObjectDisposedException("");
58         }
59     }
60 
61     internal class Observer<T> : IObserver<T>
62     {
63         private readonly ImmutableList<IObserver<T>> _observers;
64 
Observer(ImmutableList<IObserver<T>> observers)65         public Observer(ImmutableList<IObserver<T>> observers)
66         {
67             _observers = observers;
68         }
69 
OnCompleted()70         public void OnCompleted()
71         {
72             foreach (var observer in _observers.Data)
73                 observer.OnCompleted();
74         }
75 
OnError(Exception error)76         public void OnError(Exception error)
77         {
78             foreach (var observer in _observers.Data)
79                 observer.OnError(error);
80         }
81 
OnNext(T value)82         public void OnNext(T value)
83         {
84             foreach (var observer in _observers.Data)
85                 observer.OnNext(value);
86         }
87 
Add(IObserver<T> observer)88         internal IObserver<T> Add(IObserver<T> observer)
89         {
90             return new Observer<T>(_observers.Add(observer));
91         }
92 
Remove(IObserver<T> observer)93         internal IObserver<T> Remove(IObserver<T> observer)
94         {
95             var i = Array.IndexOf(_observers.Data, observer);
96             if (i < 0)
97                 return this;
98 
99             if (_observers.Data.Length == 2)
100             {
101                 return _observers.Data[1 - i];
102             }
103             else
104             {
105                 return new Observer<T>(_observers.Remove(observer));
106             }
107         }
108     }
109 }
110