Methods.cs
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license.
4 //
5 // Microsoft Bot Framework: http://botframework.com
6 //
7 // Bot Builder SDK GitHub:
8 // https://github.com/Microsoft/BotBuilder
9 //
10 // Copyright (c) Microsoft Corporation
11 // All rights reserved.
12 //
13 // MIT License:
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33 
34 using System;
35 using System.Threading;
36 using System.Threading.Tasks;
37 
38 namespace Microsoft.Bot.Builder.Internals.Fibers
39 {
40  public static class Methods
41  {
42  public static Rest<C, T> Identity<C, T>()
43  {
44  return IdentityMethod<C, T>.Instance.IdentityAsync;
45  }
46 
47  public static Rest<C, T> Loop<C, T>(Rest<C, T> rest, int count)
48  {
49  var loop = new LoopMethod<C, T>(rest, count);
50  return loop.LoopAsync;
51  }
52 
53  public static Rest<C, T> Void<C, T>(Rest<C, T> rest)
54  {
55  var root = new VoidMethod<C, T>(rest);
56  return root.RootAsync;
57  }
58 
59  [Serializable]
60  private sealed class IdentityMethod<C, T>
61  {
62  public static readonly IdentityMethod<C, T> Instance = new IdentityMethod<C, T>();
63 
64  private IdentityMethod()
65  {
66  }
67 
68  public async Task<IWait<C>> IdentityAsync(IFiber<C> fiber, C context, IItem<T> item, CancellationToken token)
69  {
70  return fiber.Done(await item);
71  }
72  }
73 
74  [Serializable]
75  private sealed class LoopMethod<C, T>
76  {
77  private readonly Rest<C, T> rest;
78  private int count;
79  private T item;
80 
81  public LoopMethod(Rest<C, T> rest, int count)
82  {
83  SetField.NotNull(out this.rest, nameof(rest), rest);
84  this.count = count;
85  }
86 
87  public async Task<IWait<C>> LoopAsync(IFiber<C> fiber, C context, IItem<T> item, CancellationToken token)
88  {
89  this.item = await item;
90 
91  --this.count;
92  if (this.count >= 0)
93  {
94  return fiber.Call<C, T, object>(this.rest, this.item, NextAsync);
95  }
96  else
97  {
98  return fiber.Done(this.item);
99  }
100  }
101 
102  public async Task<IWait<C>> NextAsync(IFiber<C> fiber, C context, IItem<object> ignore, CancellationToken token)
103  {
104  --this.count;
105  if (this.count >= 0)
106  {
107  return fiber.Call<C, T, object>(this.rest, this.item, NextAsync);
108  }
109  else
110  {
111  return fiber.Done(this.item);
112  }
113  }
114  }
115 
116  [Serializable]
117  private sealed class VoidMethod<C, T>
118  {
119  private readonly Rest<C, T> rest;
120 
121  public VoidMethod(Rest<C, T> rest)
122  {
123  SetField.NotNull(out this.rest, nameof(rest), rest);
124  }
125 
126  public async Task<IWait<C>> RootAsync(IFiber<C> fiber, C context, IItem<T> item, CancellationToken token)
127  {
128  return fiber.Call<C, T, object>(this.rest, await item, DoneAsync);
129  }
130 
131  public async Task<IWait<C>> DoneAsync(IFiber<C> fiber, C context, IItem<object> ignore, CancellationToken token)
132  {
133  return NullWait<C>.Instance;
134  }
135  }
136  }
137 }
static readonly IWait< C > Instance
Definition: Wait.cs:129
Null object pattern implementation of wait interface.
Definition: Wait.cs:127