Example #1
0
        public IDisposable Subscribe(IObserver <T> observer)
        {
            if (observer == null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            IObserver <T> original;
            IObserver <T> nextState;

            do
            {
                original = _current;
                if (original == FastSubjectHelpers <T> .DisposedSubjectMarker)
                {
                    throw new ObjectDisposedException("");
                }
                if (original == FastSubjectHelpers <T> .CompletedSubjectMarker)
                {
                    observer.OnCompleted();
                    return(Disposable.Empty);
                }
                if (original is FastSubjectHelpers <T> .ExceptionedSubject)
                {
                    observer.OnError(((FastSubjectHelpers <T> .ExceptionedSubject)original).Error);
                    return(Disposable.Empty);
                }
                if (original == FastSubjectHelpers <T> .EmptySubjectMarker)
                {
                    nextState = observer;
                }
                else if (original is FastSubjectHelpers <T> .MultiSubject)
                {
                    var originalArray = ((FastSubjectHelpers <T> .MultiSubject)original).Array;
                    var originalCount = originalArray.Length;
                    var newArray      = new IObserver <T> [originalCount + 1];
                    Array.Copy(originalArray, newArray, originalCount);
                    newArray[originalCount] = observer;
                    nextState = new FastSubjectHelpers <T> .MultiSubject(newArray);
                }
                else
                {
                    nextState = new FastSubjectHelpers <T> .MultiSubject(new[] { original, observer });
                }
            } while (Interlocked.CompareExchange(ref _current, nextState, original) != original);
            return(new FastSubjectHelpers <T> .Subscription(this, observer));
        }
Example #2
0
        public void Unsubscribe(IObserver <T> observer)
        {
            IObserver <T> original;
            IObserver <T> nextState;

            do
            {
                original = _current;
                if (original is IStoppedSubjectMarker)
                {
                    return;
                }
                if (original is FastSubjectHelpers <T> .MultiSubject)
                {
                    var originalArray = ((FastSubjectHelpers <T> .MultiSubject)original).Array;
                    var indexOf       = Array.IndexOf(originalArray, observer);
                    if (indexOf < 0)
                    {
                        return;
                    }
                    if (originalArray.Length == 2)
                    {
                        nextState = originalArray[1 - indexOf];
                    }
                    else
                    {
                        var newArray = new IObserver <T> [originalArray.Length - 1];
                        Array.Copy(originalArray, newArray, indexOf);
                        Array.Copy(originalArray, indexOf + 1, newArray, indexOf, newArray.Length - indexOf);
                        nextState = new FastSubjectHelpers <T> .MultiSubject(newArray);
                    }
                }
                else
                {
                    if (original != observer)
                    {
                        return;
                    }
                    nextState = FastSubjectHelpers <T> .EmptySubjectMarker;
                }
            } while (Interlocked.CompareExchange(ref _current, nextState, original) != original);
        }
Example #3
0
        public void OnNext(T value)
        {
            IObserver <T> original;
            IObserver <T> nextState;

            do
            {
                original = _current;
                if (original is FastSubjectHelpers <T> .SingleSubjectWithValue)
                {
                    nextState = new FastSubjectHelpers <T> .SingleSubjectWithValue(
                        ((FastSubjectHelpers <T> .SingleSubjectWithValue)original).Observer, value);
                }
                else if (original is FastSubjectHelpers <T> .EmptySubjectWithValue || original == FastSubjectHelpers <T> .EmptySubjectMarker)
                {
                    nextState = new FastSubjectHelpers <T> .EmptySubjectWithValue(value);
                }
                else if (original is FastSubjectHelpers <T> .MultiSubjectWithValue)
                {
                    nextState = new FastSubjectHelpers <T> .MultiSubjectWithValue(
                        ((FastSubjectHelpers <T> .MultiSubjectWithValue)original).Array, value);
                }
                else if (original is FastSubjectHelpers <T> .MultiSubject)
                {
                    nextState = new FastSubjectHelpers <T> .MultiSubjectWithValue(
                        ((FastSubjectHelpers <T> .MultiSubject)original).Array, value);
                }
                else if (original is IStoppedSubjectMarker)
                {
                    break;
                }
                else
                {
                    nextState = new FastSubjectHelpers <T> .SingleSubjectWithValue(original, value);
                }
            } while (Interlocked.CompareExchange(ref _current, nextState, original) != original);
            original.OnNext(value);
        }