PageRenderTime 49ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs/rxjs/3.0.0/rx.virtualtime.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 394 lines | 237 code | 53 blank | 104 comment | 68 complexity | 599ac1b80a932c94f281b7555f3ff74f MD5 | raw file
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2. ;(function (factory) {
  3. var objectTypes = {
  4. 'function': true,
  5. 'object': true
  6. };
  7. var
  8. freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports,
  9. freeSelf = objectTypes[typeof self] && self.Object && self,
  10. freeWindow = objectTypes[typeof window] && window && window.Object && window,
  11. freeModule = objectTypes[typeof module] && module && !module.nodeType && module,
  12. moduleExports = freeModule && freeModule.exports === freeExports && freeExports,
  13. freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;
  14. var root = root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
  15. // Because of build optimizers
  16. if (typeof define === 'function' && define.amd) {
  17. define(['rx'], function (Rx, exports) {
  18. return factory(root, exports, Rx);
  19. });
  20. } else if (typeof module === 'object' && module && module.exports === freeExports) {
  21. module.exports = factory(root, module.exports, require('./rx'));
  22. } else {
  23. root.Rx = factory(root, {}, root.Rx);
  24. }
  25. }.call(this, function (root, exp, Rx, undefined) {
  26. // Aliases
  27. var Scheduler = Rx.Scheduler,
  28. ScheduledItem = Rx.internals.ScheduledItem,
  29. SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive,
  30. disposableEmpty = Rx.Disposable.empty,
  31. inherits = Rx.internals.inherits,
  32. defaultSubComparer = Rx.helpers.defaultSubComparer,
  33. notImplemented = Rx.helpers.notImplemented;
  34. // Collections
  35. function IndexedItem(id, value) {
  36. this.id = id;
  37. this.value = value;
  38. }
  39. IndexedItem.prototype.compareTo = function (other) {
  40. var c = this.value.compareTo(other.value);
  41. c === 0 && (c = this.id - other.id);
  42. return c;
  43. };
  44. // Priority Queue for Scheduling
  45. var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
  46. this.items = new Array(capacity);
  47. this.length = 0;
  48. };
  49. var priorityProto = PriorityQueue.prototype;
  50. priorityProto.isHigherPriority = function (left, right) {
  51. return this.items[left].compareTo(this.items[right]) < 0;
  52. };
  53. priorityProto.percolate = function (index) {
  54. if (index >= this.length || index < 0) { return; }
  55. var parent = index - 1 >> 1;
  56. if (parent < 0 || parent === index) { return; }
  57. if (this.isHigherPriority(index, parent)) {
  58. var temp = this.items[index];
  59. this.items[index] = this.items[parent];
  60. this.items[parent] = temp;
  61. this.percolate(parent);
  62. }
  63. };
  64. priorityProto.heapify = function (index) {
  65. +index || (index = 0);
  66. if (index >= this.length || index < 0) { return; }
  67. var left = 2 * index + 1,
  68. right = 2 * index + 2,
  69. first = index;
  70. if (left < this.length && this.isHigherPriority(left, first)) {
  71. first = left;
  72. }
  73. if (right < this.length && this.isHigherPriority(right, first)) {
  74. first = right;
  75. }
  76. if (first !== index) {
  77. var temp = this.items[index];
  78. this.items[index] = this.items[first];
  79. this.items[first] = temp;
  80. this.heapify(first);
  81. }
  82. };
  83. priorityProto.peek = function () { return this.items[0].value; };
  84. priorityProto.removeAt = function (index) {
  85. this.items[index] = this.items[--this.length];
  86. this.items[this.length] = undefined;
  87. this.heapify();
  88. };
  89. priorityProto.dequeue = function () {
  90. var result = this.peek();
  91. this.removeAt(0);
  92. return result;
  93. };
  94. priorityProto.enqueue = function (item) {
  95. var index = this.length++;
  96. this.items[index] = new IndexedItem(PriorityQueue.count++, item);
  97. this.percolate(index);
  98. };
  99. priorityProto.remove = function (item) {
  100. for (var i = 0; i < this.length; i++) {
  101. if (this.items[i].value === item) {
  102. this.removeAt(i);
  103. return true;
  104. }
  105. }
  106. return false;
  107. };
  108. PriorityQueue.count = 0;
  109. /** Provides a set of extension methods for virtual time scheduling. */
  110. var VirtualTimeScheduler = Rx.VirtualTimeScheduler = (function (__super__) {
  111. function localNow() {
  112. return this.toDateTimeOffset(this.clock);
  113. }
  114. function scheduleNow(state, action) {
  115. return this.scheduleAbsoluteWithState(state, this.clock, action);
  116. }
  117. function scheduleRelative(state, dueTime, action) {
  118. return this.scheduleRelativeWithState(state, this.toRelative(dueTime), action);
  119. }
  120. function scheduleAbsolute(state, dueTime, action) {
  121. return this.scheduleRelativeWithState(state, this.toRelative(dueTime - this.now()), action);
  122. }
  123. function invokeAction(scheduler, action) {
  124. action();
  125. return disposableEmpty;
  126. }
  127. inherits(VirtualTimeScheduler, __super__);
  128. /**
  129. * Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer.
  130. *
  131. * @constructor
  132. * @param {Number} initialClock Initial value for the clock.
  133. * @param {Function} comparer Comparer to determine causality of events based on absolute time.
  134. */
  135. function VirtualTimeScheduler(initialClock, comparer) {
  136. this.clock = initialClock;
  137. this.comparer = comparer;
  138. this.isEnabled = false;
  139. this.queue = new PriorityQueue(1024);
  140. __super__.call(this, localNow, scheduleNow, scheduleRelative, scheduleAbsolute);
  141. }
  142. var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype;
  143. /**
  144. * Adds a relative time value to an absolute time value.
  145. * @param {Number} absolute Absolute virtual time value.
  146. * @param {Number} relative Relative virtual time value to add.
  147. * @return {Number} Resulting absolute virtual time sum value.
  148. */
  149. VirtualTimeSchedulerPrototype.add = notImplemented;
  150. /**
  151. * Converts an absolute time to a number
  152. * @param {Any} The absolute time.
  153. * @returns {Number} The absolute time in ms
  154. */
  155. VirtualTimeSchedulerPrototype.toDateTimeOffset = notImplemented;
  156. /**
  157. * Converts the TimeSpan value to a relative virtual time value.
  158. * @param {Number} timeSpan TimeSpan value to convert.
  159. * @return {Number} Corresponding relative virtual time value.
  160. */
  161. VirtualTimeSchedulerPrototype.toRelative = notImplemented;
  162. /**
  163. * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling.
  164. * @param {Mixed} state Initial state passed to the action upon the first iteration.
  165. * @param {Number} period Period for running the work periodically.
  166. * @param {Function} action Action to be executed, potentially updating the state.
  167. * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
  168. */
  169. VirtualTimeSchedulerPrototype.schedulePeriodicWithState = function (state, period, action) {
  170. var s = new SchedulePeriodicRecursive(this, state, period, action);
  171. return s.start();
  172. };
  173. /**
  174. * Schedules an action to be executed after dueTime.
  175. * @param {Mixed} state State passed to the action to be executed.
  176. * @param {Number} dueTime Relative time after which to execute the action.
  177. * @param {Function} action Action to be executed.
  178. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
  179. */
  180. VirtualTimeSchedulerPrototype.scheduleRelativeWithState = function (state, dueTime, action) {
  181. var runAt = this.add(this.clock, dueTime);
  182. return this.scheduleAbsoluteWithState(state, runAt, action);
  183. };
  184. /**
  185. * Schedules an action to be executed at dueTime.
  186. * @param {Number} dueTime Relative time after which to execute the action.
  187. * @param {Function} action Action to be executed.
  188. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
  189. */
  190. VirtualTimeSchedulerPrototype.scheduleRelative = function (dueTime, action) {
  191. return this.scheduleRelativeWithState(action, dueTime, invokeAction);
  192. };
  193. /**
  194. * Starts the virtual time scheduler.
  195. */
  196. VirtualTimeSchedulerPrototype.start = function () {
  197. if (!this.isEnabled) {
  198. this.isEnabled = true;
  199. do {
  200. var next = this.getNext();
  201. if (next !== null) {
  202. this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
  203. next.invoke();
  204. } else {
  205. this.isEnabled = false;
  206. }
  207. } while (this.isEnabled);
  208. }
  209. };
  210. /**
  211. * Stops the virtual time scheduler.
  212. */
  213. VirtualTimeSchedulerPrototype.stop = function () {
  214. this.isEnabled = false;
  215. };
  216. /**
  217. * Advances the scheduler's clock to the specified time, running all work till that point.
  218. * @param {Number} time Absolute time to advance the scheduler's clock to.
  219. */
  220. VirtualTimeSchedulerPrototype.advanceTo = function (time) {
  221. var dueToClock = this.comparer(this.clock, time);
  222. if (this.comparer(this.clock, time) > 0) { throw new ArgumentOutOfRangeError(); }
  223. if (dueToClock === 0) { return; }
  224. if (!this.isEnabled) {
  225. this.isEnabled = true;
  226. do {
  227. var next = this.getNext();
  228. if (next !== null && this.comparer(next.dueTime, time) <= 0) {
  229. this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
  230. next.invoke();
  231. } else {
  232. this.isEnabled = false;
  233. }
  234. } while (this.isEnabled);
  235. this.clock = time;
  236. }
  237. };
  238. /**
  239. * Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
  240. * @param {Number} time Relative time to advance the scheduler's clock by.
  241. */
  242. VirtualTimeSchedulerPrototype.advanceBy = function (time) {
  243. var dt = this.add(this.clock, time),
  244. dueToClock = this.comparer(this.clock, dt);
  245. if (dueToClock > 0) { throw new ArgumentOutOfRangeError(); }
  246. if (dueToClock === 0) { return; }
  247. this.advanceTo(dt);
  248. };
  249. /**
  250. * Advances the scheduler's clock by the specified relative time.
  251. * @param {Number} time Relative time to advance the scheduler's clock by.
  252. */
  253. VirtualTimeSchedulerPrototype.sleep = function (time) {
  254. var dt = this.add(this.clock, time);
  255. if (this.comparer(this.clock, dt) >= 0) { throw new ArgumentOutOfRangeError(); }
  256. this.clock = dt;
  257. };
  258. /**
  259. * Gets the next scheduled item to be executed.
  260. * @returns {ScheduledItem} The next scheduled item.
  261. */
  262. VirtualTimeSchedulerPrototype.getNext = function () {
  263. while (this.queue.length > 0) {
  264. var next = this.queue.peek();
  265. if (next.isCancelled()) {
  266. this.queue.dequeue();
  267. } else {
  268. return next;
  269. }
  270. }
  271. return null;
  272. };
  273. /**
  274. * Schedules an action to be executed at dueTime.
  275. * @param {Scheduler} scheduler Scheduler to execute the action on.
  276. * @param {Number} dueTime Absolute time at which to execute the action.
  277. * @param {Function} action Action to be executed.
  278. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
  279. */
  280. VirtualTimeSchedulerPrototype.scheduleAbsolute = function (dueTime, action) {
  281. return this.scheduleAbsoluteWithState(action, dueTime, invokeAction);
  282. };
  283. /**
  284. * Schedules an action to be executed at dueTime.
  285. * @param {Mixed} state State passed to the action to be executed.
  286. * @param {Number} dueTime Absolute time at which to execute the action.
  287. * @param {Function} action Action to be executed.
  288. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
  289. */
  290. VirtualTimeSchedulerPrototype.scheduleAbsoluteWithState = function (state, dueTime, action) {
  291. var self = this;
  292. function run(scheduler, state1) {
  293. self.queue.remove(si);
  294. return action(scheduler, state1);
  295. }
  296. var si = new ScheduledItem(this, state, run, dueTime, this.comparer);
  297. this.queue.enqueue(si);
  298. return si.disposable;
  299. };
  300. return VirtualTimeScheduler;
  301. }(Scheduler));
  302. /** Provides a virtual time scheduler that uses Date for absolute time and number for relative time. */
  303. Rx.HistoricalScheduler = (function (__super__) {
  304. inherits(HistoricalScheduler, __super__);
  305. /**
  306. * Creates a new historical scheduler with the specified initial clock value.
  307. * @constructor
  308. * @param {Number} initialClock Initial value for the clock.
  309. * @param {Function} comparer Comparer to determine causality of events based on absolute time.
  310. */
  311. function HistoricalScheduler(initialClock, comparer) {
  312. var clock = initialClock == null ? 0 : initialClock;
  313. var cmp = comparer || defaultSubComparer;
  314. __super__.call(this, clock, cmp);
  315. }
  316. var HistoricalSchedulerProto = HistoricalScheduler.prototype;
  317. /**
  318. * Adds a relative time value to an absolute time value.
  319. * @param {Number} absolute Absolute virtual time value.
  320. * @param {Number} relative Relative virtual time value to add.
  321. * @return {Number} Resulting absolute virtual time sum value.
  322. */
  323. HistoricalSchedulerProto.add = function (absolute, relative) {
  324. return absolute + relative;
  325. };
  326. HistoricalSchedulerProto.toDateTimeOffset = function (absolute) {
  327. return new Date(absolute).getTime();
  328. };
  329. /**
  330. * Converts the TimeSpan value to a relative virtual time value.
  331. * @memberOf HistoricalScheduler
  332. * @param {Number} timeSpan TimeSpan value to convert.
  333. * @return {Number} Corresponding relative virtual time value.
  334. */
  335. HistoricalSchedulerProto.toRelative = function (timeSpan) {
  336. return timeSpan;
  337. };
  338. return HistoricalScheduler;
  339. }(Rx.VirtualTimeScheduler));
  340. return Rx;
  341. }));