ClockViewModel.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*global define*/
  2. define([
  3. '../Core/Clock',
  4. '../Core/defined',
  5. '../Core/defineProperties',
  6. '../Core/destroyObject',
  7. '../Core/EventHelper',
  8. '../Core/JulianDate',
  9. '../ThirdParty/knockout'
  10. ], function(
  11. Clock,
  12. defined,
  13. defineProperties,
  14. destroyObject,
  15. EventHelper,
  16. JulianDate,
  17. knockout) {
  18. "use strict";
  19. /**
  20. * A view model which exposes a {@link Clock} for user interfaces.
  21. * @alias ClockViewModel
  22. * @constructor
  23. *
  24. * @param {Clock} [clock] The clock object wrapped by this view model, if undefined a new instance will be created.
  25. *
  26. * @see Clock
  27. */
  28. var ClockViewModel = function(clock) {
  29. if (!defined(clock)) {
  30. clock = new Clock();
  31. }
  32. this._clock = clock;
  33. this._eventHelper = new EventHelper();
  34. this._eventHelper.add(clock.onTick, this.synchronize, this);
  35. var startTime = knockout.observable(clock.startTime);
  36. startTime.equalityComparer = JulianDate.equals;
  37. /**
  38. * Gets the current system time. This property is observable.
  39. * @type {JulianDate}
  40. * @default JulianDate()
  41. */
  42. this.systemTime = knockout.observable(JulianDate.now());
  43. this.systemTime.equalityComparer = JulianDate.equals;
  44. knockout.track(this, ['systemTime']);
  45. /**
  46. * Gets or sets the start time of the clock. This property is observable.
  47. * @type {JulianDate}
  48. * @default undefined
  49. */
  50. this.startTime = undefined;
  51. knockout.defineProperty(this, 'startTime', {
  52. get : startTime,
  53. set : function(value) {
  54. startTime(value);
  55. clock.startTime = value;
  56. }
  57. });
  58. var stopTime = knockout.observable(clock.stopTime);
  59. stopTime.equalityComparer = JulianDate.equals;
  60. /**
  61. * Gets or sets the stop time of the clock. This property is observable.
  62. * @type {JulianDate}
  63. * @default undefined
  64. */
  65. this.stopTime = undefined;
  66. knockout.defineProperty(this, 'stopTime', {
  67. get : stopTime,
  68. set : function(value) {
  69. clock.stopTime = value;
  70. stopTime(value);
  71. }
  72. });
  73. var currentTime = knockout.observable(clock.currentTime);
  74. currentTime.equalityComparer = JulianDate.equals;
  75. /**
  76. * Gets or sets the current time. This property is observable.
  77. * @type {JulianDate}
  78. * @default undefined
  79. */
  80. this.currentTime = undefined;
  81. knockout.defineProperty(this, 'currentTime', {
  82. get : currentTime,
  83. set : function(value) {
  84. clock.currentTime = value;
  85. currentTime(value);
  86. }
  87. });
  88. var multiplier = knockout.observable(clock.multiplier);
  89. /**
  90. * Gets or sets how much time advances when tick is called, negative values allow for advancing backwards.
  91. * If <code>clockStep</code> is set to ClockStep.TICK_DEPENDENT this is the number of seconds to advance.
  92. * If <code>clockStep</code> is set to ClockStep.SYSTEM_CLOCK_MULTIPLIER this value is multiplied by the
  93. * elapsed system time since the last call to tick. This property is observable.
  94. * @type {Number}
  95. * @default undefined
  96. */
  97. this.multiplier = undefined;
  98. knockout.defineProperty(this, 'multiplier', {
  99. get : multiplier,
  100. set : function(value) {
  101. clock.multiplier = value;
  102. multiplier(value);
  103. }
  104. });
  105. var clockStep = knockout.observable(clock.clockStep);
  106. clockStep.equalityComparer = function(a, b) {
  107. return a === b;
  108. };
  109. /**
  110. * Gets or sets whether calls to <code>Clock.tick</code> are frame dependent or system clock dependent.
  111. * This property is observable.
  112. * @type {ClockStep}
  113. * @default undefined
  114. */
  115. this.clockStep = undefined;
  116. knockout.defineProperty(this, 'clockStep', {
  117. get : clockStep,
  118. set : function(value) {
  119. clockStep(value);
  120. clock.clockStep = value;
  121. }
  122. });
  123. var clockRange = knockout.observable(clock.clockRange);
  124. clockRange.equalityComparer = function(a, b) {
  125. return a === b;
  126. };
  127. /**
  128. * Gets or sets how tick should behave when <code>startTime</code> or <code>stopTime</code> is reached.
  129. * This property is observable.
  130. * @type {ClockRange}
  131. * @default undefined
  132. */
  133. this.clockRange = undefined;
  134. knockout.defineProperty(this, 'clockRange', {
  135. get : clockRange,
  136. set : function(value) {
  137. clockRange(value);
  138. clock.clockRange = value;
  139. }
  140. });
  141. var canAnimate = knockout.observable(clock.canAnimate);
  142. /**
  143. * Gets or sets whether or not <code>Clock.tick</code> can advance time.
  144. * This could be false if data is being buffered, for example.
  145. * The clock will only tick when both <code>canAnimate</code> and <code>shouldAnimate</code> are true.
  146. * This property is observable.
  147. * @type {Boolean}
  148. * @default undefined
  149. */
  150. this.canAnimate = undefined;
  151. knockout.defineProperty(this, 'canAnimate', {
  152. get : canAnimate,
  153. set : function(value) {
  154. canAnimate(value);
  155. clock.canAnimate = value;
  156. }
  157. });
  158. var shouldAnimate = knockout.observable(clock.shouldAnimate);
  159. /**
  160. * Gets or sets whether or not <code>Clock.tick</code> should attempt to advance time.
  161. * The clock will only tick when both <code>canAnimate</code> and <code>shouldAnimate</code> are true.
  162. * This property is observable.
  163. * @type {Boolean}
  164. * @default undefined
  165. */
  166. this.shouldAnimate = undefined;
  167. knockout.defineProperty(this, 'shouldAnimate', {
  168. get : shouldAnimate,
  169. set : function(value) {
  170. shouldAnimate(value);
  171. clock.shouldAnimate = value;
  172. }
  173. });
  174. };
  175. defineProperties(ClockViewModel.prototype, {
  176. /**
  177. * Gets the underlying Clock.
  178. * @memberof ClockViewModel.prototype
  179. *
  180. * @type {Clock}
  181. */
  182. clock : {
  183. get : function() {
  184. return this._clock;
  185. }
  186. }
  187. });
  188. /**
  189. * Updates the view model with the contents of the underlying clock.
  190. * Can be called to force an update of the viewModel if the underlying
  191. * clock has changed and <code>Clock.tick</code> has not yet been called.
  192. */
  193. ClockViewModel.prototype.synchronize = function() {
  194. var clock = this._clock;
  195. var startTime = clock.startTime;
  196. var stopTime = clock.stopTime;
  197. var currentTime = clock.currentTime;
  198. var multiplier = clock.multiplier;
  199. var clockStep = clock.clockStep;
  200. var clockRange = clock.clockRange;
  201. var canAnimate = clock.canAnimate;
  202. var shouldAnimate = clock.shouldAnimate;
  203. this.systemTime = JulianDate.now();
  204. this.startTime = startTime;
  205. this.stopTime = stopTime;
  206. this.currentTime = currentTime;
  207. this.multiplier = multiplier;
  208. this.clockStep = clockStep;
  209. this.clockRange = clockRange;
  210. this.canAnimate = canAnimate;
  211. this.shouldAnimate = shouldAnimate;
  212. };
  213. /**
  214. * @returns {Boolean} true if the object has been destroyed, false otherwise.
  215. */
  216. ClockViewModel.prototype.isDestroyed = function() {
  217. return false;
  218. };
  219. /**
  220. * Destroys the view model. Should be called to
  221. * properly clean up the view model when it is no longer needed.
  222. */
  223. ClockViewModel.prototype.destroy = function() {
  224. this._eventHelper.removeAll();
  225. destroyObject(this);
  226. };
  227. return ClockViewModel;
  228. });