PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/source/library/Interlace/ReactorUtilities/Deferred.cs

https://bitbucket.org/VahidN/interlace
C# | 213 lines | 150 code | 38 blank | 25 comment | 3 complexity | fc2e4d5f0b9b5318422ffc4fd83cf37c MD5 | raw file
  1. #region Using Directives and Copyright Notice
  2. // Copyright (c) 2007-2010, Computer Consultancy Pty Ltd
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are met:
  7. // * Redistributions of source code must retain the above copyright
  8. // notice, this list of conditions and the following disclaimer.
  9. // * Redistributions in binary form must reproduce the above copyright
  10. // notice, this list of conditions and the following disclaimer in the
  11. // documentation and/or other materials provided with the distribution.
  12. // * Neither the name of the Computer Consultancy Pty Ltd nor the
  13. // names of its contributors may be used to endorse or promote products
  14. // derived from this software without specific prior written permission.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. // ARE DISCLAIMED. IN NO EVENT SHALL COMPUTER CONSULTANCY PTY LTD BE LIABLE
  20. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22. // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  26. // DAMAGE.
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Text;
  30. using Interlace.Utilities;
  31. #endregion
  32. namespace Interlace.ReactorUtilities
  33. {
  34. public static class Deferred
  35. {
  36. public static Deferred<T> Success<T>(T value)
  37. {
  38. Deferred<T> deferred = new Deferred<T>();
  39. deferred.SucceedObject(value);
  40. return deferred;
  41. }
  42. public static Deferred<T> Failure<T>(DeferredFailure failure)
  43. {
  44. Deferred<T> deferred = new Deferred<T>();
  45. deferred.Fail(failure);
  46. return deferred;
  47. }
  48. public static bool IsDeferred(Type type)
  49. {
  50. return typeof(DeferredObject).IsAssignableFrom(type);
  51. }
  52. public static bool IsTypedDeferred(Type type)
  53. {
  54. return
  55. type.Equals(typeof(VoidDeferred)) ||
  56. (!type.IsGenericTypeDefinition &&
  57. type.GetGenericTypeDefinition().Equals(typeof(Deferred<>)) &&
  58. type.GetGenericArguments().Length == 1);
  59. }
  60. public static Type DeferredResultType(Type type)
  61. {
  62. if (!IsTypedDeferred(type))
  63. {
  64. throw new InvalidOperationException(
  65. "The type of a deferred is only available on a typed (generic or void) deferred.");
  66. }
  67. if (type.Equals(typeof(VoidDeferred)))
  68. {
  69. return typeof(void);
  70. }
  71. else
  72. {
  73. return type.GetGenericArguments()[0];
  74. }
  75. }
  76. public static DeferredObject CreateInstanceOfSameType(DeferredObject deferred)
  77. {
  78. Type type = deferred.GetType();
  79. return Activator.CreateInstance(type) as DeferredObject;
  80. }
  81. }
  82. public class Deferred<T> : DeferredObject
  83. {
  84. public delegate void Callback(T result);
  85. public delegate void CallbackWithState<TState>(T result, TState state);
  86. public delegate void Failback(DeferredFailure result);
  87. public delegate void FailbackWithState<TState>(DeferredFailure result, TState state);
  88. public delegate TReturn ConvertingCallback<TReturn>(T result);
  89. public delegate Deferred<TReturn> ChainingCallback<TReturn>(T result);
  90. public delegate void ConvertingCallback(T result);
  91. public delegate VoidDeferred ChainingCallback(T result);
  92. public void Completion(Callback callback, Failback failback)
  93. {
  94. ObjectCompletion(
  95. delegate(object result) { callback((T)result); return null; },
  96. delegate(DeferredFailure failure) { failback(failure); return null; },
  97. null);
  98. }
  99. public void Completion(Deferred<T> deferred)
  100. {
  101. ObjectCompletion(IdentityCallback, IdentityFailback, deferred);
  102. }
  103. public void Completion<TState>(CallbackWithState<TState> callback, Failback failback, TState state)
  104. {
  105. ObjectCompletion(
  106. delegate(object result) { callback((T)result, state); return null; },
  107. delegate(DeferredFailure failure) { failback(failure); return null; },
  108. null);
  109. }
  110. public void Completion<TState>(CallbackWithState<TState> callback, FailbackWithState<TState> failback, TState state)
  111. {
  112. ObjectCompletion(
  113. delegate(object result) { callback((T)result, state); return null; },
  114. delegate(DeferredFailure failure) { failback(failure, state); return null; },
  115. null);
  116. }
  117. public void Succeed(T value)
  118. {
  119. SucceedObject(value);
  120. }
  121. public Deferred<TReturn> Chained<TReturn>(ChainingCallback<TReturn> callback)
  122. {
  123. Deferred<TReturn> returnDeferred = new Deferred<TReturn>();
  124. ObjectCompletion(delegate(object result)
  125. {
  126. Deferred<TReturn> resultDeferred = callback((T)result);
  127. resultDeferred.Completion(returnDeferred);
  128. return null;
  129. },
  130. delegate(DeferredFailure failure)
  131. {
  132. returnDeferred.Fail(failure);
  133. return null;
  134. }, null);
  135. return returnDeferred;
  136. }
  137. public Deferred<TReturn> Converted<TReturn>(ConvertingCallback<TReturn> callback)
  138. {
  139. Deferred<TReturn> returnDeferred = new Deferred<TReturn>();
  140. ObjectCompletion(delegate(object result)
  141. {
  142. return callback((T)result);
  143. },
  144. IdentityFailback, returnDeferred);
  145. return returnDeferred;
  146. }
  147. public VoidDeferred Chained(ChainingCallback callback)
  148. {
  149. VoidDeferred returnDeferred = new VoidDeferred();
  150. ObjectCompletion(delegate(object result)
  151. {
  152. VoidDeferred resultDeferred = callback((T)result);
  153. resultDeferred.ObjectCompletion(IdentityCallback, IdentityFailback, returnDeferred);
  154. return null;
  155. },
  156. delegate(DeferredFailure failure)
  157. {
  158. returnDeferred.Fail(failure);
  159. return null;
  160. }, null);
  161. return returnDeferred;
  162. }
  163. public VoidDeferred Converted(ConvertingCallback callback)
  164. {
  165. VoidDeferred returnDeferred = new VoidDeferred();
  166. ObjectCompletion(delegate(object result)
  167. {
  168. callback((T)result);
  169. return null;
  170. },
  171. IdentityFailback, returnDeferred);
  172. return returnDeferred;
  173. }
  174. }
  175. }