// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT License. // See the LICENSE file in the project root for more information. <#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> using System.Reactive.Concurrency; using System.Reactive.Disposables; using System.Threading.Tasks; namespace System.Reactive.Linq { public partial class AsyncObservable { <# for (var i = 2; i <= 16; i++) { var tuple = "(" + string.Join(", ", Enumerable.Range(1, i).Select(j => "T" + j + " arg" + j)) + ")"; var genArgs = string.Join(", ", Enumerable.Range(1, i).Select(j => "T" + j)); var pars = string.Join(", ", Enumerable.Range(1, i).Select(j => "arg" + j)); #> public static IAsyncObservable<<#=tuple#>> FromEvent<<#=genArgs#>>(Action>> addHandler, Action>> removeHandler) { if (addHandler == null) throw new ArgumentNullException(nameof(addHandler)); if (removeHandler == null) throw new ArgumentNullException(nameof(removeHandler)); return FromEventCore>, <#=genArgs#>>(h => h, addHandler, removeHandler, GetSchedulerForCurrentContext()); } public static IAsyncObservable<<#=tuple#>> FromEvent<<#=genArgs#>>(Action>> addHandler, Action>> removeHandler, IAsyncScheduler scheduler) { if (addHandler == null) throw new ArgumentNullException(nameof(addHandler)); if (removeHandler == null) throw new ArgumentNullException(nameof(removeHandler)); if (scheduler == null) throw new ArgumentNullException(nameof(scheduler)); return FromEventCore>, <#=genArgs#>>(h => h, addHandler, removeHandler, scheduler); } public static IAsyncObservable<<#=tuple#>> FromEvent>(Func>, TDelegate> conversion, Action addHandler, Action removeHandler) { if (conversion == null) throw new ArgumentNullException(nameof(conversion)); if (addHandler == null) throw new ArgumentNullException(nameof(addHandler)); if (removeHandler == null) throw new ArgumentNullException(nameof(removeHandler)); return FromEventCore>(conversion, addHandler, removeHandler, GetSchedulerForCurrentContext()); } public static IAsyncObservable<<#=tuple#>> FromEvent>(Func>, TDelegate> conversion, Action addHandler, Action removeHandler, IAsyncScheduler scheduler) { if (conversion == null) throw new ArgumentNullException(nameof(conversion)); if (addHandler == null) throw new ArgumentNullException(nameof(addHandler)); if (removeHandler == null) throw new ArgumentNullException(nameof(removeHandler)); if (scheduler == null) throw new ArgumentNullException(nameof(scheduler)); return FromEventCore>(conversion, addHandler, removeHandler, scheduler); } private static IAsyncObservable<<#=tuple#>> FromEventCore>(Func>, TDelegate> conversion, Action addHandler, Action removeHandler, IAsyncScheduler scheduler) { return SynchronizeEvents( Create<<#=tuple#>>(observer => { var handler = new Action<<#=genArgs#>>((<#=pars#>) => { observer.OnNextAsync((<#=pars#>)); // REVIEW: Fire-and-forget can lead to out of order processing, and observers may reject these calls as "busy". }); var converted = conversion(handler); addHandler(converted); return new ValueTask(AsyncDisposable.Create(() => { removeHandler(converted); return default; })); }), scheduler ); } <# } #> } }