Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some improvements to core classes #376

Merged
merged 3 commits into from
Apr 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Rx.NET/Source/src/System.Reactive/AnonymousObservable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace System.Reactive
{
/// <summary>
/// Class to create an <see cref="IObservable{T}"/> instance from a delegate-based implementation of the Subscribe method.
/// Class to create an <see cref="IObservable{T}"/> instance from a delegate-based implementation of the <see cref="IObservable{T}.Subscribe(IObserver{T})"/> method.
/// </summary>
/// <typeparam name="T">The type of the elements in the sequence.</typeparam>
public sealed class AnonymousObservable<T> : ObservableBase<T>
Expand All @@ -17,8 +17,8 @@ public sealed class AnonymousObservable<T> : ObservableBase<T>
/// <summary>
/// Creates an observable sequence object from the specified subscription function.
/// </summary>
/// <param name="subscribe">Subscribe method implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="subscribe"/> is null.</exception>
/// <param name="subscribe"><see cref="IObservable{T}.Subscribe(IObserver{T})"/> method implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="subscribe"/> is <c>null</c>.</exception>
public AnonymousObservable(Func<IObserver<T>, IDisposable> subscribe)
{
if (subscribe == null)
Expand Down
58 changes: 23 additions & 35 deletions Rx.NET/Source/src/System.Reactive/AnonymousObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ public sealed class AnonymousObserver<T> : ObserverBase<T>
private readonly Action _onCompleted;

/// <summary>
/// Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
/// Creates an observer from the specified <see cref="IObserver{T}.OnNext(T)"/>, <see cref="IObserver{T}.OnError(Exception)"/>, and <see cref="IObserver{T}.OnCompleted()"/> actions.
/// </summary>
/// <param name="onNext">Observer's OnNext action implementation.</param>
/// <param name="onError">Observer's OnError action implementation.</param>
/// <param name="onCompleted">Observer's OnCompleted action implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="onNext"/> or <paramref name="onError"/> or <paramref name="onCompleted"/> is null.</exception>
/// <param name="onNext">Observer's <see cref="IObserver{T}.OnNext(T)"/> action implementation.</param>
/// <param name="onError">Observer's <see cref="IObserver{T}.OnError(Exception)"/> action implementation.</param>
/// <param name="onCompleted">Observer's <see cref="IObserver{T}.OnCompleted()"/> action implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="onNext"/> or <paramref name="onError"/> or <paramref name="onCompleted"/> is <c>null</c>.</exception>
public AnonymousObserver(Action<T> onNext, Action<Exception> onError, Action onCompleted)
{
if (onNext == null)
Expand All @@ -36,66 +36,54 @@ public AnonymousObserver(Action<T> onNext, Action<Exception> onError, Action onC
}

/// <summary>
/// Creates an observer from the specified OnNext action.
/// Creates an observer from the specified <see cref="IObserver{T}.OnNext(T)"/> action.
/// </summary>
/// <param name="onNext">Observer's OnNext action implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="onNext"/> is null.</exception>
/// <param name="onNext">Observer's <see cref="IObserver{T}.OnNext(T)"/> action implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="onNext"/> is <c>null</c>.</exception>
public AnonymousObserver(Action<T> onNext)
: this(onNext, Stubs.Throw, Stubs.Nop)
{
}

/// <summary>
/// Creates an observer from the specified OnNext and OnError actions.
/// Creates an observer from the specified <see cref="IObserver{T}.OnNext(T)"/> and <see cref="IObserver{T}.OnError(Exception)"/> actions.
/// </summary>
/// <param name="onNext">Observer's OnNext action implementation.</param>
/// <param name="onError">Observer's OnError action implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="onNext"/> or <paramref name="onError"/> is null.</exception>
/// <param name="onNext">Observer's <see cref="IObserver{T}.OnNext(T)"/> action implementation.</param>
/// <param name="onError">Observer's <see cref="IObserver{T}.OnError(Exception)"/> action implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="onNext"/> or <paramref name="onError"/> is <c>null</c>.</exception>
public AnonymousObserver(Action<T> onNext, Action<Exception> onError)
: this(onNext, onError, Stubs.Nop)
{
}

/// <summary>
/// Creates an observer from the specified OnNext and OnCompleted actions.
/// Creates an observer from the specified <see cref="IObserver{T}.OnNext(T)"/> and <see cref="IObserver{T}.OnCompleted()"/> actions.
/// </summary>
/// <param name="onNext">Observer's OnNext action implementation.</param>
/// <param name="onCompleted">Observer's OnCompleted action implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="onNext"/> or <paramref name="onCompleted"/> is null.</exception>
/// <param name="onNext">Observer's <see cref="IObserver{T}.OnNext(T)"/> action implementation.</param>
/// <param name="onCompleted">Observer's <see cref="IObserver{T}.OnCompleted()"/> action implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="onNext"/> or <paramref name="onCompleted"/> is <c>null</c>.</exception>
public AnonymousObserver(Action<T> onNext, Action onCompleted)
: this(onNext, Stubs.Throw, onCompleted)
{
}

/// <summary>
/// Calls the onNext action.
/// Calls the action implementing <see cref="IObserver{T}.OnNext(T)"/>.
/// </summary>
/// <param name="value">Next element in the sequence.</param>
protected override void OnNextCore(T value)
{
_onNext(value);
}
protected override void OnNextCore(T value) => _onNext(value);

/// <summary>
/// Calls the onError action.
/// Calls the action implementing <see cref="IObserver{T}.OnError(Exception)"/>.
/// </summary>
/// <param name="error">The error that has occurred.</param>
protected override void OnErrorCore(Exception error)
{
_onError(error);
}
protected override void OnErrorCore(Exception error) => _onError(error);

/// <summary>
/// Calls the onCompleted action.
/// Calls the action implementing <see cref="IObserver{T}.OnCompleted()"/>.
/// </summary>
protected override void OnCompletedCore()
{
_onCompleted();
}
protected override void OnCompletedCore() => _onCompleted();

internal IObserver<T> MakeSafe(IDisposable disposable)
{
return new AnonymousSafeObserver<T>(_onNext, _onError, _onCompleted, disposable);
}
internal IObserver<T> MakeSafe(IDisposable disposable) => new AnonymousSafeObserver<T>(_onNext, _onError, _onCompleted, disposable);
}
}
2 changes: 1 addition & 1 deletion Rx.NET/Source/src/System.Reactive/AnonymousSafeObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace System.Reactive
/// that accept delegates for the On* handlers. By doing the fusion, we make the call stack depth shorter which
/// helps debugging and some performance.
/// </summary>
class AnonymousSafeObserver<T> : IObserver<T>
internal sealed class AnonymousSafeObserver<T> : IObserver<T>
{
private readonly Action<T> _onNext;
private readonly Action<Exception> _onError;
Expand Down
4 changes: 2 additions & 2 deletions Rx.NET/Source/src/System.Reactive/EnlightenmentProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ namespace System.Reactive.PlatformServices
/// <summary>
/// Provides access to the platform enlightenments used by other Rx libraries to improve system performance and
/// runtime efficiency. While Rx can run without platform enlightenments loaded, it's recommended to deploy the
/// System.Reactive.PlatformServices assembly with your application and call <see cref="EnlightenmentProvider.
/// EnsureLoaded"/> during application startup to ensure enlightenments are properly loaded.
/// System.Reactive.PlatformServices assembly with your application and call <see cref="EnsureLoaded"/> during
/// application startup to ensure enlightenments are properly loaded.
/// </summary>
public static class EnlightenmentProvider
{
Expand Down
19 changes: 5 additions & 14 deletions Rx.NET/Source/src/System.Reactive/EventPattern.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ public EventPattern(TSender sender, TEventArgs e)
/// <returns><c>true</c> if both <see cref="EventPattern{TSender, TEventArgs}"/> objects represent the same event; otherwise, <c>false</c>.</returns>
public bool Equals(EventPattern<TSender, TEventArgs> other)
{
if (object.ReferenceEquals(null, other))
if (ReferenceEquals(null, other))
return false;
if (object.ReferenceEquals(this, other))
if (ReferenceEquals(this, other))
return true;

return EqualityComparer<TSender>.Default.Equals(Sender, other.Sender) && EqualityComparer<TEventArgs>.Default.Equals(EventArgs, other.EventArgs);
Expand All @@ -71,10 +71,7 @@ public bool Equals(EventPattern<TSender, TEventArgs> other)
/// </summary>
/// <param name="obj">The System.Object to compare with the current <see cref="EventPattern{TSender, TEventArgs}"/>.</param>
/// <returns><c>true</c> if the specified System.Object is equal to the current <see cref="EventPattern{TSender, TEventArgs}"/>; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
return Equals(obj as EventPattern<TSender, TEventArgs>);
}
public override bool Equals(object obj) => Equals(obj as EventPattern<TSender, TEventArgs>);

/// <summary>
/// Returns the hash code for the current <see cref="EventPattern{TSender, TEventArgs}"/> instance.
Expand All @@ -93,20 +90,14 @@ public override int GetHashCode()
/// <param name="first">The first <see cref="EventPattern{TSender, TEventArgs}"/> to compare, or <c>null</c>.</param>
/// <param name="second">The second <see cref="EventPattern{TSender, TEventArgs}"/> to compare, or <c>null</c>.</param>
/// <returns><c>true</c> if both <see cref="EventPattern{TSender, TEventArgs}"/> objects represent the same event; otherwise, <c>false</c>.</returns>
public static bool operator ==(EventPattern<TSender, TEventArgs> first, EventPattern<TSender, TEventArgs> second)
{
return object.Equals(first, second);
}
public static bool operator ==(EventPattern<TSender, TEventArgs> first, EventPattern<TSender, TEventArgs> second) => Equals(first, second);

/// <summary>
/// Determines whether two specified <see cref="EventPattern{TSender, TEventArgs}"/> objects represent a different event.
/// </summary>
/// <param name="first">The first <see cref="EventPattern{TSender, TEventArgs}"/> to compare, or <c>null</c>.</param>
/// <param name="second">The second <see cref="EventPattern{TSender, TEventArgs}"/> to compare, or <c>null</c>.</param>
/// <returns><c>true</c> if both <see cref="EventPattern{TSender, TEventArgs}"/> objects don't represent the same event; otherwise, <c>false</c>.</returns>
public static bool operator !=(EventPattern<TSender, TEventArgs> first, EventPattern<TSender, TEventArgs> second)
{
return !object.Equals(first, second);
}
public static bool operator !=(EventPattern<TSender, TEventArgs> first, EventPattern<TSender, TEventArgs> second) => !Equals(first, second);
}
}
2 changes: 1 addition & 1 deletion Rx.NET/Source/src/System.Reactive/EventPatternSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace System.Reactive
{
class EventPatternSource<TEventArgs> : EventPatternSourceBase<object, TEventArgs>, IEventPatternSource<TEventArgs>
internal sealed class EventPatternSource<TEventArgs> : EventPatternSourceBase<object, TEventArgs>, IEventPatternSource<TEventArgs>
{
public EventPatternSource(IObservable<EventPattern<object, TEventArgs>> source, Action<Action<object, TEventArgs>, /*object,*/ EventPattern<object, TEventArgs>> invokeHandler)
: base(source, invokeHandler)
Expand Down
24 changes: 16 additions & 8 deletions Rx.NET/Source/src/System.Reactive/EventPatternSourceBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public abstract class EventPatternSourceBase<TSender, TEventArgs>
/// </summary>
/// <param name="source">Source sequence to expose as an event.</param>
/// <param name="invokeHandler">Delegate used to invoke the event for each element of the sequence.</param>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="invokeHandler"/> is null.</exception>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="invokeHandler"/> is <c>null</c>.</exception>
protected EventPatternSourceBase(IObservable<EventPattern<TSender, TEventArgs>> source, Action<Action<TSender, TEventArgs>, /*object,*/ EventPattern<TSender, TEventArgs>> invokeHandler)
{
if (source == null)
Expand All @@ -40,9 +40,9 @@ protected EventPatternSourceBase(IObservable<EventPattern<TSender, TEventArgs>>
/// <summary>
/// Adds the specified event handler, causing a subscription to the underlying source.
/// </summary>
/// <param name="handler">Event handler to add. The same delegate should be passed to the Remove operation in order to remove the event handler.</param>
/// <param name="handler">Event handler to add. The same delegate should be passed to the <see cref="Remove(Delegate)"/> operation in order to remove the event handler.</param>
/// <param name="invoke">Invocation delegate to raise the event in the derived class.</param>
/// <exception cref="ArgumentNullException"><paramref name="handler"/> or <paramref name="invoke"/> is null.</exception>
/// <exception cref="ArgumentNullException"><paramref name="handler"/> or <paramref name="invoke"/> is <c>null</c>.</exception>
protected void Add(Delegate handler, Action<TSender, TEventArgs> invoke)
{
if (handler == null)
Expand All @@ -59,9 +59,13 @@ protected void Add(Delegate handler, Action<TSender, TEventArgs> invoke)
lock (gate)
{
if (isAdded)
{
Remove(handler);
}
else
{
isDone = true;
}
}
});

Expand Down Expand Up @@ -90,17 +94,19 @@ private void Add(Delegate handler, IDisposable disposable)
{
var l = new Stack<IDisposable>();
if (!_subscriptions.TryGetValue(handler, out l))
{
_subscriptions[handler] = l = new Stack<IDisposable>();
}

l.Push(disposable);
}
}

/// <summary>
/// Removes the specified event handler, causing a disposal of the corresponding subscription to the underlying source that was created during the Add operation.
/// Removes the specified event handler, causing a disposal of the corresponding subscription to the underlying source that was created during the <see cref="Add(Delegate, Action{TSender, TEventArgs})"/> operation.
/// </summary>
/// <param name="handler">Event handler to remove. This should be the same delegate as one that was passed to the Add operation.</param>
/// <exception cref="ArgumentNullException"><paramref name="handler"/> is null.</exception>
/// <param name="handler">Event handler to remove. This should be the same delegate as one that was passed to the <see cref="Add(Delegate, Action{TSender, TEventArgs})"/> operation.</param>
/// <exception cref="ArgumentNullException"><paramref name="handler"/> is <c>null</c>.</exception>
protected void Remove(Delegate handler)
{
if (handler == null)
Expand All @@ -114,13 +120,15 @@ protected void Remove(Delegate handler)
if (_subscriptions.TryGetValue(handler, out l))
{
d = l.Pop();

if (l.Count == 0)
{
_subscriptions.Remove(handler);
}
}
}

if (d != null)
d.Dispose();
d?.Dispose();
}
}
}
14 changes: 11 additions & 3 deletions Rx.NET/Source/src/System.Reactive/EventSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace System.Reactive
{
class EventSource<T> : IEventSource<T>
internal sealed class EventSource<T> : IEventSource<T>
{
private readonly IObservable<T> _source;
private readonly Dictionary<Delegate, Stack<IDisposable>> _subscriptions;
Expand All @@ -32,9 +32,13 @@ public event Action<T> OnNext
lock (gate)
{
if (isAdded)
{
Remove(value);
}
else
{
isDone = true;
}
}
});

Expand Down Expand Up @@ -69,7 +73,9 @@ private void Add(Delegate handler, IDisposable disposable)
{
var l = new Stack<IDisposable>();
if (!_subscriptions.TryGetValue(handler, out l))
{
_subscriptions[handler] = l = new Stack<IDisposable>();
}

l.Push(disposable);
}
Expand All @@ -85,13 +91,15 @@ private void Remove(Delegate handler)
if (_subscriptions.TryGetValue(handler, out l))
{
d = l.Pop();

if (l.Count == 0)
{
_subscriptions.Remove(handler);
}
}
}

if (d != null)
d.Dispose();
d?.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ internal sealed class ExcludeFromCodeCoverageAttribute : Attribute
}
}

#endif
#endif
Loading