FromEvent.Generated.tt 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT License.
  3. // See the LICENSE file in the project root for more information.
  4. <#@ template debug="false" hostspecific="false" language="C#" #>
  5. <#@ assembly name="System.Core" #>
  6. <#@ import namespace="System.Linq" #>
  7. <#@ import namespace="System.Text" #>
  8. <#@ import namespace="System.Collections.Generic" #>
  9. <#@ output extension=".cs" #>
  10. using System.Reactive.Concurrency;
  11. using System.Reactive.Disposables;
  12. using System.Threading.Tasks;
  13. namespace System.Reactive.Linq
  14. {
  15. partial class AsyncObservable
  16. {
  17. <#
  18. for (var i = 2; i <= 16; i++)
  19. {
  20. var tuple = "(" + string.Join(", ", Enumerable.Range(1, i).Select(j => "T" + j + " arg" + j)) + ")";
  21. var genArgs = string.Join(", ", Enumerable.Range(1, i).Select(j => "T" + j));
  22. var pars = string.Join(", ", Enumerable.Range(1, i).Select(j => "arg" + j));
  23. #>
  24. public static IAsyncObservable<<#=tuple#>> FromEvent<<#=genArgs#>>(Action<Action<<#=genArgs#>>> addHandler, Action<Action<<#=genArgs#>>> removeHandler)
  25. {
  26. if (addHandler == null)
  27. throw new ArgumentNullException(nameof(addHandler));
  28. if (removeHandler == null)
  29. throw new ArgumentNullException(nameof(removeHandler));
  30. return FromEventCore<Action<<#=genArgs#>>, <#=genArgs#>>(h => h, addHandler, removeHandler, GetSchedulerForCurrentContext());
  31. }
  32. public static IAsyncObservable<<#=tuple#>> FromEvent<<#=genArgs#>>(Action<Action<<#=genArgs#>>> addHandler, Action<Action<<#=genArgs#>>> removeHandler, IAsyncScheduler scheduler)
  33. {
  34. if (addHandler == null)
  35. throw new ArgumentNullException(nameof(addHandler));
  36. if (removeHandler == null)
  37. throw new ArgumentNullException(nameof(removeHandler));
  38. if (scheduler == null)
  39. throw new ArgumentNullException(nameof(scheduler));
  40. return FromEventCore<Action<<#=genArgs#>>, <#=genArgs#>>(h => h, addHandler, removeHandler, scheduler);
  41. }
  42. public static IAsyncObservable<<#=tuple#>> FromEvent<TDelegate, <#=genArgs#>>(Func<Action<<#=genArgs#>>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
  43. {
  44. if (conversion == null)
  45. throw new ArgumentNullException(nameof(conversion));
  46. if (addHandler == null)
  47. throw new ArgumentNullException(nameof(addHandler));
  48. if (removeHandler == null)
  49. throw new ArgumentNullException(nameof(removeHandler));
  50. return FromEventCore<TDelegate, <#=genArgs#>>(conversion, addHandler, removeHandler, GetSchedulerForCurrentContext());
  51. }
  52. public static IAsyncObservable<<#=tuple#>> FromEvent<TDelegate, <#=genArgs#>>(Func<Action<<#=genArgs#>>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IAsyncScheduler scheduler)
  53. {
  54. if (conversion == null)
  55. throw new ArgumentNullException(nameof(conversion));
  56. if (addHandler == null)
  57. throw new ArgumentNullException(nameof(addHandler));
  58. if (removeHandler == null)
  59. throw new ArgumentNullException(nameof(removeHandler));
  60. if (scheduler == null)
  61. throw new ArgumentNullException(nameof(scheduler));
  62. return FromEventCore<TDelegate, <#=genArgs#>>(conversion, addHandler, removeHandler, scheduler);
  63. }
  64. private static IAsyncObservable<<#=tuple#>> FromEventCore<TDelegate, <#=genArgs#>>(Func<Action<<#=genArgs#>>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IAsyncScheduler scheduler)
  65. {
  66. return
  67. SynchronizeEvents(
  68. Create<<#=tuple#>>(observer =>
  69. {
  70. var handler = new Action<<#=genArgs#>>((<#=pars#>) =>
  71. {
  72. observer.OnNextAsync((<#=pars#>)); // REVIEW: Fire-and-forget can lead to out of order processing, and observers may reject these calls as "busy".
  73. });
  74. var converted = conversion(handler);
  75. addHandler(converted);
  76. return Task.FromResult(AsyncDisposable.Create(() =>
  77. {
  78. removeHandler(converted);
  79. return Task.CompletedTask;
  80. }));
  81. }),
  82. scheduler
  83. );
  84. }
  85. <#
  86. }
  87. #>
  88. }
  89. }