Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.Reactive.Disposables;
using System.Reactive.Subjects;
namespace System.Reactive.Linq
{
class GroupedObservable<TKey, TElement> : ObservableBase<TElement>, IGroupedObservable<TKey, TElement>
{
private readonly TKey _key;
private readonly IObservable<TElement> _subject;
private readonly RefCountDisposable _refCount;
public GroupedObservable(TKey key, ISubject<TElement> subject, RefCountDisposable refCount)
{
_key = key;
_subject = subject;
_refCount = refCount;
}
public GroupedObservable(TKey key, ISubject<TElement> subject)
{
_key = key;
_subject = subject;
}
public TKey Key
{
get { return _key; }
}
protected override IDisposable SubscribeCore(IObserver<TElement> observer)
{
if (_refCount != null)
{
//
// [OK] Use of unsafe Subscribe: called on a known subject implementation.
//
var release = _refCount.GetDisposable();
var subscription = _subject.Subscribe/*Unsafe*/(observer);
return new CompositeDisposable(release, subscription);
}
else
{
//
// [OK] Use of unsafe Subscribe: called on a known subject implementation.
//
return _subject.Subscribe/*Unsafe*/(observer);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.ComponentModel;
namespace System.Reactive.Linq
{
/// <summary>
/// Attribute applied to static classes providing expression tree forms of query methods,
/// mapping those to the corresponding methods for local query execution on the specified
/// target class type.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class LocalQueryMethodImplementationTypeAttribute : Attribute
{
private readonly Type _targetType;
/// <summary>
/// Creates a new mapping to the specified local execution query method implementation type.
/// </summary>
/// <param name="targetType">Type with query methods for local execution.</param>
public LocalQueryMethodImplementationTypeAttribute(Type targetType)
{
_targetType = targetType;
}
/// <summary>
/// Gets the type with the implementation of local query methods.
/// </summary>
public Type TargetType
{
get { return _targetType; }
}
}
}

View File

@@ -0,0 +1 @@
b541765bec0326b9015a7688ba921668b099e482

View File

@@ -0,0 +1 @@
8f740758525458373e70412caece3c4ffcd0ce2d

View File

@@ -0,0 +1,79 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if HAS_AWAIT
using System.Threading;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
namespace System.Reactive.Linq
{
public static partial class Observable
{
/// <summary>
/// Gets an awaiter that returns the last value of the observable sequence or throws an exception if the sequence is empty.
/// This operation subscribes to the observable sequence, making it hot.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence to await.</param>
/// <returns>Object that can be awaited.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static AsyncSubject<TSource> GetAwaiter<TSource>(this IObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
return s_impl.GetAwaiter<TSource>(source);
}
/// <summary>
/// Gets an awaiter that returns the last value of the observable sequence or throws an exception if the sequence is empty.
/// This operation subscribes and connects to the observable sequence, making it hot.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence to await.</param>
/// <returns>Object that can be awaited.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static AsyncSubject<TSource> GetAwaiter<TSource>(this IConnectableObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
return s_impl.GetAwaiter<TSource>(source);
}
/// <summary>
/// Gets an awaiter that returns the last value of the observable sequence or throws an exception if the sequence is empty.
/// This operation subscribes to the observable sequence, making it hot. The supplied CancellationToken can be used to cancel the subscription.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence to await.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Object that can be awaited.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static AsyncSubject<TSource> RunAsync<TSource>(this IObservable<TSource> source, CancellationToken cancellationToken)
{
if (source == null)
throw new ArgumentNullException("source");
return s_impl.RunAsync<TSource>(source, cancellationToken);
}
/// <summary>
/// Gets an awaiter that returns the last value of the observable sequence or throws an exception if the sequence is empty.
/// This operation subscribes and connects to the observable sequence, making it hot. The supplied CancellationToken can be used to cancel the subscription and connection.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence to await.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Object that can be awaited.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static AsyncSubject<TSource> RunAsync<TSource>(this IConnectableObservable<TSource> source, CancellationToken cancellationToken)
{
if (source == null)
throw new ArgumentNullException("source");
return s_impl.RunAsync<TSource>(source, cancellationToken);
}
}
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,155 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.Reactive.Concurrency;
using System.Threading;
namespace System.Reactive.Linq
{
public static partial class Observable
{
#region + ObserveOn +
/// <summary>
/// Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="scheduler">Scheduler to notify observers on.</param>
/// <returns>The source sequence whose observations happen on the specified scheduler.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
/// <remarks>
/// This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
/// that require to be run on a scheduler, use <see cref="Observable.SubscribeOn{TSource}(IObservable{TSource}, IScheduler)"/>.
/// </remarks>
public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, IScheduler scheduler)
{
if (source == null)
throw new ArgumentNullException("source");
if (scheduler == null)
throw new ArgumentNullException("scheduler");
return s_impl.ObserveOn<TSource>(source, scheduler);
}
#if !NO_SYNCCTX
/// <summary>
/// Wraps the source sequence in order to run its observer callbacks on the specified synchronization context.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="context">Synchronization context to notify observers on.</param>
/// <returns>The source sequence whose observations happen on the specified synchronization context.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="context"/> is null.</exception>
/// <remarks>
/// This only invokes observer callbacks on a synchronization context. In case the subscription and/or unsubscription actions have side-effects
/// that require to be run on a synchronization context, use <see cref="Observable.SubscribeOn{TSource}(IObservable{TSource}, SynchronizationContext)"/>.
/// </remarks>
public static IObservable<TSource> ObserveOn<TSource>(this IObservable<TSource> source, SynchronizationContext context)
{
if (source == null)
throw new ArgumentNullException("source");
if (context == null)
throw new ArgumentNullException("context");
return s_impl.ObserveOn<TSource>(source, context);
}
#endif
#endregion
#region + SubscribeOn +
/// <summary>
/// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
/// see the remarks section for more information on the distinction between SubscribeOn and ObserveOn.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="scheduler">Scheduler to perform subscription and unsubscription actions on.</param>
/// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
/// <remarks>
/// This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
/// callbacks on a scheduler, use <see cref="Observable.ObserveOn{TSource}(IObservable{TSource}, IScheduler)"/>.
/// </remarks>
public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, IScheduler scheduler)
{
if (source == null)
throw new ArgumentNullException("source");
if (scheduler == null)
throw new ArgumentNullException("scheduler");
return s_impl.SubscribeOn<TSource>(source, scheduler);
}
#if !NO_SYNCCTX
/// <summary>
/// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified synchronization context. This operation is not commonly used;
/// see the remarks section for more information on the distinction between SubscribeOn and ObserveOn.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="context">Synchronization context to perform subscription and unsubscription actions on.</param>
/// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified synchronization context.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="context"/> is null.</exception>
/// <remarks>
/// This only performs the side-effects of subscription and unsubscription on the specified synchronization context. In order to invoke observer
/// callbacks on a synchronization context, use <see cref="Observable.ObserveOn{TSource}(IObservable{TSource}, SynchronizationContext)"/>.
/// </remarks>
public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, SynchronizationContext context)
{
if (source == null)
throw new ArgumentNullException("source");
if (context == null)
throw new ArgumentNullException("context");
return s_impl.SubscribeOn<TSource>(source, context);
}
#endif
#endregion
#region + Synchronize +
/// <summary>
/// Synchronizes the observable sequence such that observer notifications cannot be delivered concurrently.
/// This overload is useful to "fix" an observable sequence that exhibits concurrent callbacks on individual observers, which is invalid behavior for the query processor.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <returns>The source sequence whose outgoing calls to observers are synchronized.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
/// <remarks>
/// It's invalid behavior - according to the observer grammar - for a sequence to exhibit concurrent callbacks on a given observer.
/// This operator can be used to "fix" a source that doesn't conform to this rule.
/// </remarks>
public static IObservable<TSource> Synchronize<TSource>(this IObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
return s_impl.Synchronize<TSource>(source);
}
/// <summary>
/// Synchronizes the observable sequence such that observer notifications cannot be delivered concurrently, using the specified gate object.
/// This overload is useful when writing n-ary query operators, in order to prevent concurrent callbacks from different sources by synchronizing on a common gate object.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="gate">Gate object to synchronize each observer call on.</param>
/// <returns>The source sequence whose outgoing calls to observers are synchronized on the given gate object.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="gate"/> is null.</exception>
public static IObservable<TSource> Synchronize<TSource>(this IObservable<TSource> source, object gate)
{
if (source == null)
throw new ArgumentNullException("source");
if (gate == null)
throw new ArgumentNullException("gate");
return s_impl.Synchronize<TSource>(source, gate);
}
#endregion
}
}

View File

@@ -0,0 +1,164 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Reactive.Concurrency;
namespace System.Reactive.Linq
{
public static partial class Observable
{
#region + Subscribe +
/// <summary>
/// Subscribes an observer to an enumerable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Enumerable sequence to subscribe to.</param>
/// <param name="observer">Observer that will receive notifications from the enumerable sequence.</param>
/// <returns>Disposable object that can be used to unsubscribe the observer from the enumerable</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="observer"/> is null.</exception>
public static IDisposable Subscribe<TSource>(this IEnumerable<TSource> source, IObserver<TSource> observer)
{
if (source == null)
throw new ArgumentNullException("source");
if (observer == null)
throw new ArgumentNullException("observer");
return s_impl.Subscribe<TSource>(source, observer);
}
/// <summary>
/// Subscribes an observer to an enumerable sequence, using the specified scheduler to run the enumeration loop.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Enumerable sequence to subscribe to.</param>
/// <param name="observer">Observer that will receive notifications from the enumerable sequence.</param>
/// <param name="scheduler">Scheduler to perform the enumeration on.</param>
/// <returns>Disposable object that can be used to unsubscribe the observer from the enumerable</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="observer"/> or <paramref name="scheduler"/> is null.</exception>
public static IDisposable Subscribe<TSource>(this IEnumerable<TSource> source, IObserver<TSource> observer, IScheduler scheduler)
{
if (source == null)
throw new ArgumentNullException("source");
if (observer == null)
throw new ArgumentNullException("observer");
if (scheduler == null)
throw new ArgumentNullException("scheduler");
return s_impl.Subscribe<TSource>(source, observer, scheduler);
}
#endregion
#region + ToEnumerable +
/// <summary>
/// Converts an observable sequence to an enumerable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">An observable sequence to convert to an enumerable sequence.</param>
/// <returns>The enumerable sequence containing the elements in the observable sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IEnumerable<TSource> ToEnumerable<TSource>(this IObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
return s_impl.ToEnumerable<TSource>(source);
}
#endregion
#region ToEvent
/// <summary>
/// Exposes an observable sequence as an object with an Action-based .NET event.
/// </summary>
/// <param name="source">Observable source sequence.</param>
/// <returns>The event source object.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IEventSource<Unit> ToEvent(this IObservable<Unit> source)
{
if (source == null)
throw new ArgumentNullException("source");
return s_impl.ToEvent(source);
}
/// <summary>
/// Exposes an observable sequence as an object with an Action&lt;TSource&gt;-based .NET event.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Observable source sequence.</param>
/// <returns>The event source object.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IEventSource<TSource> ToEvent<TSource>(this IObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
return s_impl.ToEvent<TSource>(source);
}
#endregion
#region ToEventPattern
/// <summary>
/// Exposes an observable sequence as an object with a .NET event, conforming to the standard .NET event pattern.
/// </summary>
/// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam>
/// <param name="source">Observable source sequence.</param>
/// <returns>The event source object.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IEventPatternSource<TEventArgs> ToEventPattern<TEventArgs>(this IObservable<EventPattern<TEventArgs>> source)
#if !NO_EVENTARGS_CONSTRAINT
where TEventArgs : EventArgs
#endif
{
if (source == null)
throw new ArgumentNullException("source");
return s_impl.ToEventPattern<TEventArgs>(source);
}
#endregion
#region + ToObservable +
/// <summary>
/// Converts an enumerable sequence to an observable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Enumerable sequence to convert to an observable sequence.</param>
/// <returns>The observable sequence whose elements are pulled from the given enumerable sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
public static IObservable<TSource> ToObservable<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
return s_impl.ToObservable<TSource>(source);
}
/// <summary>
/// Converts an enumerable sequence to an observable sequence, using the specified scheduler to run the enumeration loop.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Enumerable sequence to convert to an observable sequence.</param>
/// <param name="scheduler">Scheduler to run the enumeration of the input sequence on.</param>
/// <returns>The observable sequence whose elements are pulled from the given enumerable sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="scheduler"/> is null.</exception>
public static IObservable<TSource> ToObservable<TSource>(this IEnumerable<TSource> source, IScheduler scheduler)
{
if (source == null)
throw new ArgumentNullException("source");
if (scheduler == null)
throw new ArgumentNullException("scheduler");
return s_impl.ToObservable<TSource>(source, scheduler);
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,299 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Reactive.Concurrency;
using System.Threading;
#if !NO_TPL
using System.Threading.Tasks;
#endif
namespace System.Reactive.Linq
{
public static partial class Observable
{
#region + ForEachAsync +
#if !NO_TPL
/// <summary>
/// Invokes an action for each element in the observable sequence, and returns a Task object that will get signaled when the sequence terminates.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
/// <returns>Task that signals the termination of the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
/// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
public static Task ForEachAsync<TSource>(this IObservable<TSource> source, Action<TSource> onNext)
{
if (source == null)
throw new ArgumentNullException("source");
if (onNext == null)
throw new ArgumentNullException("onNext");
return s_impl.ForEachAsync<TSource>(source, onNext);
}
/// <summary>
/// Invokes an action for each element in the observable sequence, and returns a Task object that will get signaled when the sequence terminates.
/// The loop can be quit prematurely by setting the specified cancellation token.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
/// <param name="cancellationToken">Cancellation token used to stop the loop.</param>
/// <returns>Task that signals the termination of the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
/// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
public static Task ForEachAsync<TSource>(this IObservable<TSource> source, Action<TSource> onNext, CancellationToken cancellationToken)
{
if (source == null)
throw new ArgumentNullException("source");
if (onNext == null)
throw new ArgumentNullException("onNext");
return s_impl.ForEachAsync<TSource>(source, onNext, cancellationToken);
}
/// <summary>
/// Invokes an action for each element in the observable sequence, incorporating the element's index, and returns a Task object that will get signaled when the sequence terminates.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
/// <returns>Task that signals the termination of the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
/// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
public static Task ForEachAsync<TSource>(this IObservable<TSource> source, Action<TSource, int> onNext)
{
if (source == null)
throw new ArgumentNullException("source");
if (onNext == null)
throw new ArgumentNullException("onNext");
return s_impl.ForEachAsync<TSource>(source, onNext);
}
/// <summary>
/// Invokes an action for each element in the observable sequence, incorporating the element's index, and returns a Task object that will get signaled when the sequence terminates.
/// The loop can be quit prematurely by setting the specified cancellation token.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
/// <param name="cancellationToken">Cancellation token used to stop the loop.</param>
/// <returns>Task that signals the termination of the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> is null.</exception>
/// <remarks>This operator is especially useful in conjunction with the asynchronous programming features introduced in C# 5.0 and Visual Basic 11.</remarks>
public static Task ForEachAsync<TSource>(this IObservable<TSource> source, Action<TSource, int> onNext, CancellationToken cancellationToken)
{
if (source == null)
throw new ArgumentNullException("source");
if (onNext == null)
throw new ArgumentNullException("onNext");
return s_impl.ForEachAsync<TSource>(source, onNext, cancellationToken);
}
#endif
#endregion
#region + Case +
/// <summary>
/// Uses <paramref name="selector"/> to determine which source in <paramref name="sources"/> to return, choosing <paramref name="defaultSource"/> if no match is found.
/// </summary>
/// <typeparam name="TValue">The type of the value returned by the selector function, used to look up the resulting source.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
/// <param name="selector">Selector function invoked to determine the source to lookup in the <paramref name="sources"/> dictionary.</param>
/// <param name="sources">Dictionary of sources to select from based on the <paramref name="selector"/> invocation result.</param>
/// <param name="defaultSource">Default source to select in case no matching source in <paramref name="sources"/> is found.</param>
/// <returns>The observable sequence retrieved from the <paramref name="sources"/> dictionary based on the <paramref name="selector"/> invocation result, or <paramref name="defaultSource"/> if no match is found.</returns>
/// <exception cref="ArgumentNullException"><paramref name="selector"/> or <paramref name="sources"/> or <paramref name="defaultSource"/> is null.</exception>
public static IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources, IObservable<TResult> defaultSource)
{
if (selector == null)
throw new ArgumentNullException("selector");
if (sources == null)
throw new ArgumentNullException("sources");
if (defaultSource == null)
throw new ArgumentNullException("defaultSource");
return s_impl.Case<TValue, TResult>(selector, sources, defaultSource);
}
/// <summary>
/// Uses <paramref name="selector"/> to determine which source in <paramref name="sources"/> to return, choosing an empty sequence on the specified scheduler if no match is found.
/// </summary>
/// <typeparam name="TValue">The type of the value returned by the selector function, used to look up the resulting source.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
/// <param name="selector">Selector function invoked to determine the source to lookup in the <paramref name="sources"/> dictionary.</param>
/// <param name="sources">Dictionary of sources to select from based on the <paramref name="selector"/> invocation result.</param>
/// <param name="scheduler">Scheduler to generate an empty sequence on in case no matching source in <paramref name="sources"/> is found.</param>
/// <returns>The observable sequence retrieved from the <paramref name="sources"/> dictionary based on the <paramref name="selector"/> invocation result, or an empty sequence if no match is found.</returns>
/// <exception cref="ArgumentNullException"><paramref name="selector"/> or <paramref name="sources"/> or <paramref name="scheduler"/> is null.</exception>
public static IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources, IScheduler scheduler)
{
if (selector == null)
throw new ArgumentNullException("selector");
if (sources == null)
throw new ArgumentNullException("sources");
if (scheduler == null)
throw new ArgumentNullException("scheduler");
return s_impl.Case<TValue, TResult>(selector, sources, scheduler);
}
/// <summary>
/// Uses <paramref name="selector"/> to determine which source in <paramref name="sources"/> to return, choosing an empty sequence if no match is found.
/// </summary>
/// <typeparam name="TValue">The type of the value returned by the selector function, used to look up the resulting source.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
/// <param name="selector">Selector function invoked to determine the source to lookup in the <paramref name="sources"/> dictionary.</param>
/// <param name="sources">Dictionary of sources to select from based on the <paramref name="selector"/> invocation result.</param>
/// <returns>The observable sequence retrieved from the <paramref name="sources"/> dictionary based on the <paramref name="selector"/> invocation result, or an empty sequence if no match is found.</returns>
/// <exception cref="ArgumentNullException"><paramref name="selector"/> or <paramref name="sources"/> is null.</exception>
public static IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources)
{
if (selector == null)
throw new ArgumentNullException("selector");
if (sources == null)
throw new ArgumentNullException("sources");
return s_impl.Case<TValue, TResult>(selector, sources);
}
#endregion
#region + DoWhile +
/// <summary>
/// Repeats the given <paramref name="source"/> as long as the specified <paramref name="condition"/> holds, where the <paramref name="condition"/> is evaluated after each repeated <paramref name="source"/> completed.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source to repeat as long as the <paramref name="condition"/> function evaluates to true.</param>
/// <param name="condition">Condition that will be evaluated upon the completion of an iteration through the <paramref name="source"/>, to determine whether repetition of the source is required.</param>
/// <returns>The observable sequence obtained by concatenating the <paramref name="source"/> sequence as long as the <paramref name="condition"/> holds.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="condition"/> is null.</exception>
public static IObservable<TSource> DoWhile<TSource>(this IObservable<TSource> source, Func<bool> condition)
{
if (source == null)
throw new ArgumentNullException("source");
if (condition == null)
throw new ArgumentNullException("condition");
return s_impl.DoWhile<TSource>(source, condition);
}
#endregion
#region + For +
/// <summary>
/// Concatenates the observable sequences obtained by running the <paramref name="resultSelector"/> for each element in the given enumerable <paramref name="source"/>.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the enumerable source sequence.</typeparam>
/// <typeparam name="TResult">The type of the elements in the observable result sequence.</typeparam>
/// <param name="source">Enumerable source for which each element will be mapped onto an observable source that will be concatenated in the result sequence.</param>
/// <param name="resultSelector">Function to select an observable source for each element in the <paramref name="source"/>.</param>
/// <returns>The observable sequence obtained by concatenating the sources returned by <paramref name="resultSelector"/> for each element in the <paramref name="source"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="resultSelector"/> is null.</exception>
public static IObservable<TResult> For<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IObservable<TResult>> resultSelector)
{
if (source == null)
throw new ArgumentNullException("source");
if (resultSelector == null)
throw new ArgumentNullException("resultSelector");
return s_impl.For<TSource, TResult>(source, resultSelector);
}
#endregion
#region + If +
/// <summary>
/// If the specified <paramref name="condition"/> evaluates true, select the <paramref name="thenSource"/> sequence. Otherwise, select the <paramref name="elseSource"/> sequence.
/// </summary>
/// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
/// <param name="condition">Condition evaluated to decide which sequence to return.</param>
/// <param name="thenSource">Sequence returned in case <paramref name="condition"/> evaluates true.</param>
/// <param name="elseSource">Sequence returned in case <paramref name="condition"/> evaluates false.</param>
/// <returns><paramref name="thenSource"/> if <paramref name="condition"/> evaluates true; <paramref name="elseSource"/> otherwise.</returns>
/// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="thenSource"/> or <paramref name="elseSource"/> is null.</exception>
public static IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource, IObservable<TResult> elseSource)
{
if (condition == null)
throw new ArgumentNullException("condition");
if (thenSource == null)
throw new ArgumentNullException("thenSource");
if (elseSource == null)
throw new ArgumentNullException("elseSource");
return s_impl.If<TResult>(condition, thenSource, elseSource);
}
/// <summary>
/// If the specified <paramref name="condition"/> evaluates true, select the <paramref name="thenSource"/> sequence. Otherwise, return an empty sequence.
/// </summary>
/// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
/// <param name="condition">Condition evaluated to decide which sequence to return.</param>
/// <param name="thenSource">Sequence returned in case <paramref name="condition"/> evaluates true.</param>
/// <returns><paramref name="thenSource"/> if <paramref name="condition"/> evaluates true; an empty sequence otherwise.</returns>
/// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="thenSource"/> is null.</exception>
public static IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource)
{
if (condition == null)
throw new ArgumentNullException("condition");
if (thenSource == null)
throw new ArgumentNullException("thenSource");
return s_impl.If<TResult>(condition, thenSource);
}
/// <summary>
/// If the specified <paramref name="condition"/> evaluates true, select the <paramref name="thenSource"/> sequence. Otherwise, return an empty sequence generated on the specified scheduler.
/// </summary>
/// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
/// <param name="condition">Condition evaluated to decide which sequence to return.</param>
/// <param name="thenSource">Sequence returned in case <paramref name="condition"/> evaluates true.</param>
/// <param name="scheduler">Scheduler to generate an empty sequence on in case <paramref name="condition"/> evaluates false.</param>
/// <returns><paramref name="thenSource"/> if <paramref name="condition"/> evaluates true; an empty sequence otherwise.</returns>
/// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="thenSource"/> or <paramref name="scheduler"/> is null.</exception>
public static IObservable<TResult> If<TResult>(Func<bool> condition, IObservable<TResult> thenSource, IScheduler scheduler)
{
if (condition == null)
throw new ArgumentNullException("condition");
if (thenSource == null)
throw new ArgumentNullException("thenSource");
if (scheduler == null)
throw new ArgumentNullException("scheduler");
return s_impl.If<TResult>(condition, thenSource, scheduler);
}
#endregion
#region + While +
/// <summary>
/// Repeats the given <paramref name="source"/> as long as the specified <paramref name="condition"/> holds, where the <paramref name="condition"/> is evaluated before each repeated <paramref name="source"/> is subscribed to.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Source to repeat as long as the <paramref name="condition"/> function evaluates to true.</param>
/// <param name="condition">Condition that will be evaluated before subscription to the <paramref name="source"/>, to determine whether repetition of the source is required.</param>
/// <returns>The observable sequence obtained by concatenating the <paramref name="source"/> sequence as long as the <paramref name="condition"/> holds.</returns>
/// <exception cref="ArgumentNullException"><paramref name="condition"/> or <paramref name="source"/> is null.</exception>
public static IObservable<TSource> While<TSource>(Func<bool> condition, IObservable<TSource> source)
{
if (condition == null)
throw new ArgumentNullException("condition");
if (source == null)
throw new ArgumentNullException("source");
return s_impl.While<TSource>(condition, source);
}
#endregion
}
}

View File

@@ -0,0 +1,91 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Reactive.Joins;
namespace System.Reactive.Linq
{
public static partial class Observable
{
#region And
/// <summary>
/// Creates a pattern that matches when both observable sequences have an available element.
/// </summary>
/// <typeparam name="TLeft">The type of the elements in the left sequence.</typeparam>
/// <typeparam name="TRight">The type of the elements in the right sequence.</typeparam>
/// <param name="left">Observable sequence to match with the right sequence.</param>
/// <param name="right">Observable sequence to match with the left sequence.</param>
/// <returns>Pattern object that matches when both observable sequences have an available element.</returns>
/// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is null.</exception>
public static Pattern<TLeft, TRight> And<TLeft, TRight>(this IObservable<TLeft> left, IObservable<TRight> right)
{
if (left == null)
throw new ArgumentNullException("left");
if (right == null)
throw new ArgumentNullException("right");
return s_impl.And<TLeft, TRight>(left, right);
}
#endregion
#region Then
/// <summary>
/// Matches when the observable sequence has an available element and projects the element by invoking the selector function.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence, returned by the selector function.</typeparam>
/// <param name="source">Observable sequence to apply the selector on.</param>
/// <param name="selector">Selector that will be invoked for elements in the source sequence.</param>
/// <returns>Plan that produces the projected results, to be fed (with other plans) to the When operator.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
public static Plan<TResult> Then<TSource, TResult>(this IObservable<TSource> source, Func<TSource, TResult> selector)
{
if (source == null)
throw new ArgumentNullException("source");
if (selector == null)
throw new ArgumentNullException("selector");
return s_impl.Then<TSource, TResult>(source, selector);
}
#endregion
#region When
/// <summary>
/// Joins together the results from several patterns.
/// </summary>
/// <typeparam name="TResult">The type of the elements in the result sequence, obtained from the specified patterns.</typeparam>
/// <param name="plans">A series of plans created by use of the Then operator on patterns.</param>
/// <returns>An observable sequence with the results from matching several patterns.</returns>
/// <exception cref="ArgumentNullException"><paramref name="plans"/> is null.</exception>
public static IObservable<TResult> When<TResult>(params Plan<TResult>[] plans)
{
if (plans == null)
throw new ArgumentNullException("plans");
return s_impl.When<TResult>(plans);
}
/// <summary>
/// Joins together the results from several patterns.
/// </summary>
/// <typeparam name="TResult">The type of the elements in the result sequence, obtained from the specified patterns.</typeparam>
/// <param name="plans">A series of plans created by use of the Then operator on patterns.</param>
/// <returns>An observable sequence with the results form matching several patterns.</returns>
/// <exception cref="ArgumentNullException"><paramref name="plans"/> is null.</exception>
public static IObservable<TResult> When<TResult>(this IEnumerable<Plan<TResult>> plans)
{
if (plans == null)
throw new ArgumentNullException("plans");
return s_impl.When<TResult>(plans);
}
#endregion
}
}

View File

@@ -0,0 +1 @@
db0d61b5f515142ee430e91b3e1eeefd08142e8b

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
803ba2609415c255e4de0ebaf03b3446d4e0d9df

View File

@@ -0,0 +1 @@
37364167a53cae6f2bfabb9d0d2b3c7fde26176a

View File

@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if !NO_PERF
using System;
using System.Reactive.Disposables;
namespace System.Reactive.Linq.ObservableImpl
{
class AddRef<TSource> : Producer<TSource>
{
private readonly IObservable<TSource> _source;
private readonly RefCountDisposable _refCount;
public AddRef(IObservable<TSource> source, RefCountDisposable refCount)
{
_source = source;
_refCount = refCount;
}
protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
{
var d = new CompositeDisposable(_refCount.GetDisposable(), cancel);
var sink = new _(observer, d);
setSink(sink);
return _source.SubscribeSafe(sink);
}
class _ : Sink<TSource>, IObserver<TSource>
{
public _(IObserver<TSource> observer, IDisposable cancel)
: base(observer, cancel)
{
}
public void OnNext(TSource value)
{
base._observer.OnNext(value);
}
public void OnError(Exception error)
{
base._observer.OnError(error);
base.Dispose();
}
public void OnCompleted()
{
base._observer.OnCompleted();
base.Dispose();
}
}
}
}
#endif

View File

@@ -0,0 +1,158 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
#if !NO_PERF
using System;
namespace System.Reactive.Linq.ObservableImpl
{
class Aggregate<TSource, TAccumulate, TResult> : Producer<TResult>
{
private readonly IObservable<TSource> _source;
private readonly TAccumulate _seed;
private readonly Func<TAccumulate, TSource, TAccumulate> _accumulator;
private readonly Func<TAccumulate, TResult> _resultSelector;
public Aggregate(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector)
{
_source = source;
_seed = seed;
_accumulator = accumulator;
_resultSelector = resultSelector;
}
protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
{
var sink = new _(this, observer, cancel);
setSink(sink);
return _source.SubscribeSafe(sink);
}
class _ : Sink<TResult>, IObserver<TSource>
{
private readonly Aggregate<TSource, TAccumulate, TResult> _parent;
private TAccumulate _accumulation;
public _(Aggregate<TSource, TAccumulate, TResult> parent, IObserver<TResult> observer, IDisposable cancel)
: base(observer, cancel)
{
_parent = parent;
_accumulation = _parent._seed;
}
public void OnNext(TSource value)
{
try
{
_accumulation = _parent._accumulator(_accumulation, value);
}
catch (Exception exception)
{
base._observer.OnError(exception);
base.Dispose();
}
}
public void OnError(Exception error)
{
base._observer.OnError(error);
base.Dispose();
}
public void OnCompleted()
{
var result = default(TResult);
try
{
result = _parent._resultSelector(_accumulation);
}
catch (Exception exception)
{
base._observer.OnError(exception);
base.Dispose();
return;
}
base._observer.OnNext(result);
base._observer.OnCompleted();
base.Dispose();
}
}
}
class Aggregate<TSource> : Producer<TSource>
{
private readonly IObservable<TSource> _source;
private readonly Func<TSource, TSource, TSource> _accumulator;
public Aggregate(IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
{
_source = source;
_accumulator = accumulator;
}
protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
{
var sink = new _(this, observer, cancel);
setSink(sink);
return _source.SubscribeSafe(sink);
}
class _ : Sink<TSource>, IObserver<TSource>
{
private readonly Aggregate<TSource> _parent;
private TSource _accumulation;
private bool _hasAccumulation;
public _(Aggregate<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
: base(observer, cancel)
{
_parent = parent;
_accumulation = default(TSource);
_hasAccumulation = false;
}
public void OnNext(TSource value)
{
if (!_hasAccumulation)
{
_accumulation = value;
_hasAccumulation = true;
}
else
{
try
{
_accumulation = _parent._accumulator(_accumulation, value);
}
catch (Exception exception)
{
base._observer.OnError(exception);
base.Dispose();
}
}
}
public void OnError(Exception error)
{
base._observer.OnError(error);
base.Dispose();
}
public void OnCompleted()
{
if (!_hasAccumulation)
{
base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
base.Dispose();
}
else
{
base._observer.OnNext(_accumulation);
base._observer.OnCompleted();
base.Dispose();
}
}
}
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More