diff --git a/CHANGES.md b/CHANGES.md
index 465e85390cc7..21af77015935 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -9,6 +9,7 @@ Change Log
* Fix some large polygon triangulations. [#2788](https://github.com/AnalyticalGraphicsInc/cesium/issues/2788)
* Improved performance and accuracy of polygon triangulation by using the [earcut](https://github.com/mapbox/earcut) library. Loading a GeoJSON with polygons for each country was 2x faster.
* Added CZML support for Box, Corridor and Cylinder
+* `Clock` now keeps its configuration settings self-consistent. Previously, this was done by `AnimationViewModel` and could become inconsistent in certain cases. [#4007](https://github.com/AnalyticalGraphicsInc/cesium/pull/4007)
### 1.22 - 2016-06-01
diff --git a/Source/Core/Clock.js b/Source/Core/Clock.js
index a7a67672b213..f310104c5440 100644
--- a/Source/Core/Clock.js
+++ b/Source/Core/Clock.js
@@ -4,6 +4,7 @@ define([
'./ClockStep',
'./defaultValue',
'./defined',
+ './defineProperties',
'./DeveloperError',
'./Event',
'./getTimestamp',
@@ -13,6 +14,7 @@ define([
ClockStep,
defaultValue,
defined,
+ defineProperties,
DeveloperError,
Event,
getTimestamp,
@@ -29,11 +31,11 @@ define([
* @param {JulianDate} [options.startTime] The start time of the clock.
* @param {JulianDate} [options.stopTime] The stop time of the clock.
* @param {JulianDate} [options.currentTime] The current time.
- * @param {Number} [options.multiplier=1.0] Determines how much time advances when tick is called, negative values allow for advancing backwards.
- * @param {ClockStep} [options.clockStep=ClockStep.SYSTEM_CLOCK_MULTIPLIER] Determines if calls to tick
are frame dependent or system clock dependent.
- * @param {ClockRange} [options.clockRange=ClockRange.UNBOUNDED] Determines how the clock should behave when startTime
or stopTime
is reached.
- * @param {Boolean} [options.canAnimate=true] Indicates whether tick can advance time. This could be false if data is being buffered, for example. The clock will only tick when both canAnimate
and shouldAnimate
are true.
- * @param {Boolean} [options.shouldAnimate=true] Indicates whether tick should attempt to advance time. The clock will only tick when both canAnimate
and shouldAnimate
are true.
+ * @param {Number} [options.multiplier=1.0] Determines how much time advances when {@link Clock#tick} is called, negative values allow for advancing backwards.
+ * @param {ClockStep} [options.clockStep=ClockStep.SYSTEM_CLOCK_MULTIPLIER] Determines if calls to {@link Clock#tick} are frame dependent or system clock dependent.
+ * @param {ClockRange} [options.clockRange=ClockRange.UNBOUNDED] Determines how the clock should behave when {@link Clock#startTime} or {@link Clock#stopTime} is reached.
+ * @param {Boolean} [options.canAnimate=true] Indicates whether {@link Clock#tick} can advance time. This could be false if data is being buffered, for example. The clock will only tick when both {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true.
+ * @param {Boolean} [options.shouldAnimate=true] Indicates whether {@link Clock#tick} should attempt to advance time. The clock will only tick when both {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true.
*
* @exception {DeveloperError} startTime must come before stopTime.
*
@@ -47,7 +49,7 @@ define([
* clockRange : Cesium.ClockRange.LOOP_STOP,
* clockStep : Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER
* });
- *
+ *
* @see ClockStep
* @see ClockRange
* @see JulianDate
@@ -55,34 +57,39 @@ define([
function Clock(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
+ var currentTime = options.currentTime;
var startTime = options.startTime;
- var startTimeUndefined = !defined(startTime);
-
var stopTime = options.stopTime;
- var stopTimeUndefined = !defined(stopTime);
- var currentTime = options.currentTime;
- var currentTimeUndefined = !defined(currentTime);
+ if (!defined(currentTime)) {
+ // if not specified, current time is the start time,
+ // or if that is not specified, 1 day before the stop time,
+ // or if that is not specified, then now.
+ if (defined(startTime)) {
+ currentTime = JulianDate.clone(startTime);
+ } else if (defined(stopTime)) {
+ currentTime = JulianDate.addDays(stopTime, -1.0, new JulianDate());
+ } else {
+ currentTime = JulianDate.now();
+ }
+ } else {
+ currentTime = JulianDate.clone(currentTime);
+ }
- if (startTimeUndefined && stopTimeUndefined && currentTimeUndefined) {
- currentTime = JulianDate.now();
- startTime = JulianDate.clone(currentTime);
- stopTime = JulianDate.addDays(currentTime, 1.0, new JulianDate());
- } else if (startTimeUndefined && stopTimeUndefined) {
+ if (!defined(startTime)) {
+ // if not specified, start time is the current time
+ // (as determined above)
startTime = JulianDate.clone(currentTime);
- stopTime = JulianDate.addDays(currentTime, 1.0, new JulianDate());
- } else if (startTimeUndefined && currentTimeUndefined) {
- startTime = JulianDate.addDays(stopTime, -1.0, new JulianDate());
- currentTime = JulianDate.clone(startTime);
- } else if (currentTimeUndefined && stopTimeUndefined) {
- currentTime = JulianDate.clone(startTime);
+ } else {
+ startTime = JulianDate.clone(startTime);
+ }
+
+ if (!defined(stopTime)) {
+ // if not specified, stop time is 1 day after the start time
+ // (as determined above)
stopTime = JulianDate.addDays(startTime, 1.0, new JulianDate());
- } else if (currentTimeUndefined) {
- currentTime = JulianDate.clone(startTime);
- } else if (stopTimeUndefined) {
- stopTime = JulianDate.addDays(currentTime, 1.0, new JulianDate());
- } else if (startTimeUndefined) {
- startTime = JulianDate.clone(currentTime);
+ } else {
+ stopTime = JulianDate.clone(stopTime);
}
//>>includeStart('debug', pragmas.debug);
@@ -103,93 +110,190 @@ define([
*/
this.stopTime = stopTime;
+ /**
+ * Determines how the clock should behave when
+ * {@link Clock#startTime} or {@link Clock#stopTime}
+ * is reached.
+ * @type {ClockRange}
+ * @default {@link ClockRange.UNBOUNDED}
+ */
+ this.clockRange = defaultValue(options.clockRange, ClockRange.UNBOUNDED);
+
+ /**
+ * Indicates whether {@link Clock#tick} can advance time. This could be false if data is being buffered,
+ * for example. The clock will only advance time when both
+ * {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true.
+ * @type {Boolean}
+ * @default true
+ */
+ this.canAnimate = defaultValue(options.canAnimate, true);
+
+ /**
+ * An {@link Event} that is fired whenever {@link Clock#tick} is called.
+ * @type {Event}
+ */
+ this.onTick = new Event();
+
+ this._currentTime = undefined;
+ this._multiplier = undefined;
+ this._clockStep = undefined;
+ this._shouldAnimate = undefined;
+ this._lastSystemTime = getTimestamp();
+
+ // set values using the property setters to
+ // make values consistent.
+
+ this.currentTime = currentTime;
+ this.multiplier = defaultValue(options.multiplier, 1.0);
+ this.clockStep = defaultValue(options.clockStep, ClockStep.SYSTEM_CLOCK_MULTIPLIER);
+ this.shouldAnimate = defaultValue(options.shouldAnimate, true);
+ }
+
+ defineProperties(Clock.prototype, {
/**
* The current time.
+ * Changing this property will change
+ * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to
+ * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}.
+ * @memberof Clock.prototype
* @type {JulianDate}
*/
- this.currentTime = currentTime;
+ currentTime : {
+ get : function() {
+ return this._currentTime;
+ },
+ set : function(value) {
+ if (JulianDate.equals(this._currentTime, value)) {
+ return;
+ }
+
+ if (this._clockStep === ClockStep.SYSTEM_CLOCK) {
+ this._clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER;
+ }
+
+ this._currentTime = value;
+ }
+ },
/**
- * Determines how much time advances when tick is called, negative values allow for advancing backwards.
- * If clockStep
is set to ClockStep.TICK_DEPENDENT this is the number of seconds to advance.
- * If clockStep
is set to ClockStep.SYSTEM_CLOCK_MULTIPLIER this value is multiplied by the
- * elapsed system time since the last call to tick.
+ * Gets or sets how much time advances when {@link Clock#tick} is called. Negative values allow for advancing backwards.
+ * If {@link Clock#clockStep} is set to {@link ClockStep.TICK_DEPENDENT}, this is the number of seconds to advance.
+ * If {@link Clock#clockStep} is set to {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}, this value is multiplied by the
+ * elapsed system time since the last call to {@link Clock#tick}.
+ * Changing this property will change
+ * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to
+ * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}.
+ * @memberof Clock.prototype
* @type {Number}
* @default 1.0
*/
- this.multiplier = defaultValue(options.multiplier, 1.0);
+ multiplier : {
+ get : function() {
+ return this._multiplier;
+ },
+ set : function(value) {
+ if (this._multiplier === value) {
+ return;
+ }
+
+ if (this._clockStep === ClockStep.SYSTEM_CLOCK) {
+ this._clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER;
+ }
+
+ this._multiplier = value;
+ }
+ },
/**
- * Determines if calls to tick
are frame dependent or system clock dependent.
+ * Determines if calls to {@link Clock#tick} are frame dependent or system clock dependent.
+ * Changing this property to {@link ClockStep.SYSTEM_CLOCK} will set
+ * {@link Clock#multiplier} to 1.0, {@link Clock#shouldAnimate} to true, and
+ * {@link Clock#currentTime} to the current system clock time.
+ * @memberof Clock.prototype
* @type ClockStep
* @default {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}
*/
- this.clockStep = defaultValue(options.clockStep, ClockStep.SYSTEM_CLOCK_MULTIPLIER);
+ clockStep : {
+ get : function() {
+ return this._clockStep;
+ },
+ set : function(value) {
+ if (value === ClockStep.SYSTEM_CLOCK) {
+ this._multiplier = 1.0;
+ this._shouldAnimate = true;
+ this._currentTime = JulianDate.now();
+ }
- /**
- * Determines how the clock should behave when startTime
or stopTime
is reached.
- * @type {ClockRange}
- * @default {@link ClockRange.UNBOUNDED}
- */
- this.clockRange = defaultValue(options.clockRange, ClockRange.UNBOUNDED);
+ this._clockStep = value;
+ }
+ },
- /**
- * Indicates whether tick can advance time. This could be false if data is being buffered,
- * for example. The clock will only tick when both canAnimate
and shouldAnimate
are true.
- * @type {Boolean}
- * @default true
- */
- this.canAnimate = defaultValue(options.canAnimate, true);
/**
- * Indicates whether tick should attempt to advance time.
- * The clock will only tick when both canAnimate
and shouldAnimate
are true.
+ * Indicates whether {@link Clock#tick} should attempt to advance time.
+ * The clock will only advance time when both
+ * {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true.
+ * Changing this property will change
+ * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to
+ * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}.
+ * @memberof Clock.prototype
* @type {Boolean}
* @default true
*/
- this.shouldAnimate = defaultValue(options.shouldAnimate, true);
+ shouldAnimate : {
+ get : function() {
+ return this._shouldAnimate;
+ },
+ set : function(value) {
+ if (this._shouldAnimate === value) {
+ return;
+ }
- /**
- * An {@link Event} that is fired whenever tick
.
- * @type {Event}
- */
- this.onTick = new Event();
+ if (this._clockStep === ClockStep.SYSTEM_CLOCK) {
+ this._clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER;
+ }
- this._lastSystemTime = getTimestamp();
- }
+ this._shouldAnimate = value;
+ }
+ }
+ });
/**
- * Advances the clock from the currentTime based on the current configuration options.
+ * Advances the clock from the current time based on the current configuration options.
* tick should be called every frame, regardless of whether animation is taking place
- * or not. To control animation, use the shouldAnimate
property.
+ * or not. To control animation, use the {@link Clock#shouldAnimate} property.
*
- * @returns {JulianDate} The new value of the currentTime
property.
+ * @returns {JulianDate} The new value of the {@link Clock#currentTime} property.
*/
Clock.prototype.tick = function() {
var currentSystemTime = getTimestamp();
- var currentTime = JulianDate.clone(this.currentTime);
- var startTime = this.startTime;
- var stopTime = this.stopTime;
- var multiplier = this.multiplier;
+ var currentTime = JulianDate.clone(this._currentTime);
- if (this.canAnimate && this.shouldAnimate) {
- if (this.clockStep === ClockStep.SYSTEM_CLOCK) {
+ if (this.canAnimate && this._shouldAnimate) {
+ var clockStep = this._clockStep;
+ if (clockStep === ClockStep.SYSTEM_CLOCK) {
currentTime = JulianDate.now(currentTime);
} else {
- if (this.clockStep === ClockStep.TICK_DEPENDENT) {
+ var multiplier = this._multiplier;
+
+ if (clockStep === ClockStep.TICK_DEPENDENT) {
currentTime = JulianDate.addSeconds(currentTime, multiplier, currentTime);
} else {
var milliseconds = currentSystemTime - this._lastSystemTime;
currentTime = JulianDate.addSeconds(currentTime, multiplier * (milliseconds / 1000.0), currentTime);
}
- if (this.clockRange === ClockRange.CLAMPED) {
+ var clockRange = this.clockRange;
+ var startTime = this.startTime;
+ var stopTime = this.stopTime;
+
+ if (clockRange === ClockRange.CLAMPED) {
if (JulianDate.lessThan(currentTime, startTime)) {
currentTime = JulianDate.clone(startTime, currentTime);
} else if (JulianDate.greaterThan(currentTime, stopTime)) {
currentTime = JulianDate.clone(stopTime, currentTime);
}
- } else if (this.clockRange === ClockRange.LOOP_STOP) {
+ } else if (clockRange === ClockRange.LOOP_STOP) {
if (JulianDate.lessThan(currentTime, startTime)) {
currentTime = JulianDate.clone(startTime, currentTime);
}
@@ -200,7 +304,7 @@ define([
}
}
- this.currentTime = currentTime;
+ this._currentTime = currentTime;
this._lastSystemTime = currentSystemTime;
this.onTick.raiseEvent(this);
return currentTime;
diff --git a/Source/DataSources/DataSourceClock.js b/Source/DataSources/DataSourceClock.js
index a9dc430fb1b6..454d8fe7b050 100644
--- a/Source/DataSources/DataSourceClock.js
+++ b/Source/DataSources/DataSourceClock.js
@@ -20,7 +20,8 @@ define([
'use strict';
/**
- * Represents CZML document-level clock settings.
+ * Represents desired clock settings for a particular {@link DataSource}. These settings may be applied
+ * to the {@link Clock} when the DataSource is loaded.
*
* @alias DataSourceClock
* @constructor
@@ -50,45 +51,48 @@ define([
},
/**
- * Gets or sets the start time of the clock to use when looping or clamped.
+ * Gets or sets the desired start time of the clock.
+ * See {@link Clock#startTime}.
* @memberof DataSourceClock.prototype
* @type {JulianDate}
*/
startTime : createRawPropertyDescriptor('startTime'),
/**
- * Gets or sets the stop time of the clock to use when looping or clamped.
+ * Gets or sets the desired stop time of the clock.
+ * See {@link Clock#stopTime}.
* @memberof DataSourceClock.prototype
* @type {JulianDate}
*/
stopTime : createRawPropertyDescriptor('stopTime'),
/**
- * Gets or sets the initial time to use when switching to this clock.
+ * Gets or sets the desired current time when this data source is loaded.
+ * See {@link Clock#currentTime}.
* @memberof DataSourceClock.prototype
* @type {JulianDate}
*/
currentTime : createRawPropertyDescriptor('currentTime'),
/**
- * Gets or sets how the clock should behave when startTime
or stopTime
is reached.
+ * Gets or sets the desired clock range setting.
+ * See {@link Clock#clockRange}.
* @memberof DataSourceClock.prototype
* @type {ClockRange}
*/
clockRange : createRawPropertyDescriptor('clockRange'),
/**
- * Gets or sets if clock advancement is frame dependent or system clock dependent.
+ * Gets or sets the desired clock step setting.
+ * See {@link Clock#clockStep}.
* @memberof DataSourceClock.prototype
* @type {ClockStep}
*/
clockStep : createRawPropertyDescriptor('clockStep'),
/**
- * Gets or sets how much time advances with each tick, negative values allow for advancing backwards.
- * If clockStep
is set to ClockStep.TICK_DEPENDENT this is the number of seconds to advance.
- * If clockStep
is set to ClockStep.SYSTEM_CLOCK_MULTIPLIER this value is multiplied by the
- * elapsed system time since the last call to tick.
+ * Gets or sets the desired clock multiplier.
+ * See {@link Clock#multiplier}.
* @memberof DataSourceClock.prototype
* @type {Number}
*/
@@ -163,10 +167,10 @@ define([
}
result.startTime = this.startTime;
result.stopTime = this.stopTime;
+ result.currentTime = this.currentTime;
result.clockRange = this.clockRange;
- result.clockStep = this.clockStep;
result.multiplier = this.multiplier;
- result.currentTime = this.currentTime;
+ result.clockStep = this.clockStep;
return result;
};
diff --git a/Source/Widgets/Animation/AnimationViewModel.js b/Source/Widgets/Animation/AnimationViewModel.js
index 08b734d69b2e..6409bf9d9250 100644
--- a/Source/Widgets/Animation/AnimationViewModel.js
+++ b/Source/Widgets/Animation/AnimationViewModel.js
@@ -29,18 +29,6 @@ define([
var realtimeShuttleRingAngle = 15;
var maxShuttleRingAngle = 105;
- function cancelRealtime(clockViewModel) {
- if (clockViewModel.clockStep === ClockStep.SYSTEM_CLOCK) {
- clockViewModel.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER;
- clockViewModel.multiplier = 1;
- }
- }
-
- function unpause(clockViewModel) {
- cancelRealtime(clockViewModel);
- clockViewModel.shouldAnimate = true;
- }
-
function numberComparator(left, right) {
return left - right;
}
@@ -284,10 +272,9 @@ define([
var pauseCommand = createCommand(function() {
var clockViewModel = that._clockViewModel;
if (clockViewModel.shouldAnimate) {
- cancelRealtime(clockViewModel);
clockViewModel.shouldAnimate = false;
} else if (that._canAnimate) {
- unpause(clockViewModel);
+ clockViewModel.shouldAnimate = true;
}
});
@@ -300,7 +287,6 @@ define([
var playReverseCommand = createCommand(function() {
var clockViewModel = that._clockViewModel;
- cancelRealtime(clockViewModel);
var multiplier = clockViewModel.multiplier;
if (multiplier > 0) {
clockViewModel.multiplier = -multiplier;
@@ -317,7 +303,6 @@ define([
var playForwardCommand = createCommand(function() {
var clockViewModel = that._clockViewModel;
- cancelRealtime(clockViewModel);
var multiplier = clockViewModel.multiplier;
if (multiplier < 0) {
clockViewModel.multiplier = -multiplier;
@@ -333,15 +318,12 @@ define([
});
var playRealtimeCommand = createCommand(function() {
- var clockViewModel = that._clockViewModel;
- clockViewModel.clockStep = ClockStep.SYSTEM_CLOCK;
- clockViewModel.multiplier = 1.0;
- clockViewModel.shouldAnimate = true;
+ that._clockViewModel.clockStep = ClockStep.SYSTEM_CLOCK;
}, knockout.getObservable(this, '_isSystemTimeAvailable'));
this._playRealtimeViewModel = new ToggleButtonViewModel(playRealtimeCommand, {
toggled : knockout.computed(function() {
- return clockViewModel.shouldAnimate && clockViewModel.clockStep === ClockStep.SYSTEM_CLOCK;
+ return clockViewModel.clockStep === ClockStep.SYSTEM_CLOCK;
}),
tooltip : knockout.computed(function() {
return that._isSystemTimeAvailable ? 'Today (real-time)' : 'Current time not in range';
@@ -350,7 +332,6 @@ define([
this._slower = createCommand(function() {
var clockViewModel = that._clockViewModel;
- cancelRealtime(clockViewModel);
var shuttleRingTicks = that._allShuttleRingTicks;
var multiplier = clockViewModel.multiplier;
var index = getTypicalMultiplierIndex(multiplier, shuttleRingTicks) - 1;
@@ -361,7 +342,6 @@ define([
this._faster = createCommand(function() {
var clockViewModel = that._clockViewModel;
- cancelRealtime(clockViewModel);
var shuttleRingTicks = that._allShuttleRingTicks;
var multiplier = clockViewModel.multiplier;
var index = getTypicalMultiplierIndex(multiplier, shuttleRingTicks) + 1;
diff --git a/Source/Widgets/ClockViewModel.js b/Source/Widgets/ClockViewModel.js
index fccea3e39686..96bd1cf9351e 100644
--- a/Source/Widgets/ClockViewModel.js
+++ b/Source/Widgets/ClockViewModel.js
@@ -35,168 +35,120 @@ define([
this._eventHelper = new EventHelper();
this._eventHelper.add(clock.onTick, this.synchronize, this);
- var startTime = knockout.observable(clock.startTime);
- startTime.equalityComparer = JulianDate.equals;
-
/**
- * Gets the current system time. This property is observable.
+ * Gets the current system time.
+ * This property is observable.
* @type {JulianDate}
- * @default JulianDate()
*/
this.systemTime = knockout.observable(JulianDate.now());
this.systemTime.equalityComparer = JulianDate.equals;
- knockout.track(this, ['systemTime']);
-
/**
- * Gets or sets the start time of the clock. This property is observable.
+ * Gets or sets the start time of the clock.
+ * See {@link Clock#startTime}.
+ * This property is observable.
* @type {JulianDate}
- * @default undefined
*/
- this.startTime = undefined;
- knockout.defineProperty(this, 'startTime', {
- get : startTime,
- set : function(value) {
- startTime(value);
- clock.startTime = value;
- }
- });
-
- var stopTime = knockout.observable(clock.stopTime);
- stopTime.equalityComparer = JulianDate.equals;
+ this.startTime = knockout.observable(clock.startTime);
+ this.startTime.equalityComparer = JulianDate.equals;
+ this.startTime.subscribe(function(value) {
+ clock.startTime = value;
+ this.synchronize();
+ }, this);
/**
- * Gets or sets the stop time of the clock. This property is observable.
+ * Gets or sets the stop time of the clock.
+ * See {@link Clock#stopTime}.
+ * This property is observable.
* @type {JulianDate}
- * @default undefined
*/
- this.stopTime = undefined;
- knockout.defineProperty(this, 'stopTime', {
- get : stopTime,
- set : function(value) {
- clock.stopTime = value;
- stopTime(value);
- }
- });
-
- var currentTime = knockout.observable(clock.currentTime);
- currentTime.equalityComparer = JulianDate.equals;
+ this.stopTime = knockout.observable(clock.stopTime);
+ this.stopTime.equalityComparer = JulianDate.equals;
+ this.stopTime.subscribe(function(value) {
+ clock.stopTime = value;
+ this.synchronize();
+ }, this);
/**
- * Gets or sets the current time. This property is observable.
+ * Gets or sets the current time.
+ * See {@link Clock#currentTime}.
+ * This property is observable.
* @type {JulianDate}
- * @default undefined
*/
- this.currentTime = undefined;
- knockout.defineProperty(this, 'currentTime', {
- get : currentTime,
- set : function(value) {
- clock.currentTime = value;
- currentTime(value);
- }
- });
+ this.currentTime = knockout.observable(clock.currentTime);
+ this.currentTime.equalityComparer = JulianDate.equals;
+ this.currentTime.subscribe(function(value) {
+ clock.currentTime = value;
+ this.synchronize();
+ }, this);
- var multiplier = knockout.observable(clock.multiplier);
/**
- * Gets or sets how much time advances when tick is called, negative values allow for advancing backwards.
- * If clockStep
is set to ClockStep.TICK_DEPENDENT this is the number of seconds to advance.
- * If clockStep
is set to ClockStep.SYSTEM_CLOCK_MULTIPLIER this value is multiplied by the
- * elapsed system time since the last call to tick. This property is observable.
+ * Gets or sets the clock multiplier.
+ * See {@link Clock#multiplier}.
+ * This property is observable.
* @type {Number}
- * @default undefined
*/
- this.multiplier = undefined;
- knockout.defineProperty(this, 'multiplier', {
- get : multiplier,
- set : function(value) {
- clock.multiplier = value;
- multiplier(value);
- }
- });
-
- var clockStep = knockout.observable(clock.clockStep);
- clockStep.equalityComparer = function(a, b) {
- return a === b;
- };
+ this.multiplier = knockout.observable(clock.multiplier);
+ this.multiplier.subscribe(function(value) {
+ clock.multiplier = value;
+ this.synchronize();
+ }, this);
/**
- * Gets or sets whether calls to Clock.tick
are frame dependent or system clock dependent.
+ * Gets or sets the clock step setting.
+ * See {@link Clock#clockStep}.
* This property is observable.
* @type {ClockStep}
- * @default undefined
*/
- this.clockStep = undefined;
- knockout.defineProperty(this, 'clockStep', {
- get : clockStep,
- set : function(value) {
- clockStep(value);
- clock.clockStep = value;
- }
- });
-
- var clockRange = knockout.observable(clock.clockRange);
- clockRange.equalityComparer = function(a, b) {
- return a === b;
- };
+ this.clockStep = knockout.observable(clock.clockStep);
+ this.clockStep.subscribe(function(value) {
+ clock.clockStep = value;
+ this.synchronize();
+ }, this);
/**
- * Gets or sets how tick should behave when startTime
or stopTime
is reached.
+ * Gets or sets the clock range setting.
+ * See {@link Clock#clockRange}.
* This property is observable.
* @type {ClockRange}
- * @default undefined
*/
- this.clockRange = undefined;
- knockout.defineProperty(this, 'clockRange', {
- get : clockRange,
- set : function(value) {
- clockRange(value);
- clock.clockRange = value;
- }
- });
-
- var canAnimate = knockout.observable(clock.canAnimate);
+ this.clockRange = knockout.observable(clock.clockRange);
+ this.clockRange.subscribe(function(value) {
+ clock.clockRange = value;
+ this.synchronize();
+ }, this);
/**
- * Gets or sets whether or not Clock.tick
can advance time.
- * This could be false if data is being buffered, for example.
- * The clock will only tick when both canAnimate
and shouldAnimate
are true.
+ * Gets or sets whether the clock can animate.
+ * See {@link Clock#canAnimate}.
* This property is observable.
* @type {Boolean}
- * @default undefined
*/
- this.canAnimate = undefined;
- knockout.defineProperty(this, 'canAnimate', {
- get : canAnimate,
- set : function(value) {
- canAnimate(value);
- clock.canAnimate = value;
- }
- });
-
- var shouldAnimate = knockout.observable(clock.shouldAnimate);
+ this.canAnimate = knockout.observable(clock.canAnimate);
+ this.canAnimate.subscribe(function(value) {
+ clock.canAnimate = value;
+ this.synchronize();
+ }, this);
/**
- * Gets or sets whether or not Clock.tick
should attempt to advance time.
- * The clock will only tick when both canAnimate
and shouldAnimate
are true.
+ * Gets or sets whether the clock should animate.
+ * See {@link Clock#shouldAnimate}.
* This property is observable.
* @type {Boolean}
- * @default undefined
*/
- this.shouldAnimate = undefined;
- knockout.defineProperty(this, 'shouldAnimate', {
- get : shouldAnimate,
- set : function(value) {
- shouldAnimate(value);
- clock.shouldAnimate = value;
- }
- });
+ this.shouldAnimate = knockout.observable(clock.shouldAnimate);
+ this.shouldAnimate.subscribe(function(value) {
+ clock.shouldAnimate = value;
+ this.synchronize();
+ }, this);
+
+ knockout.track(this, ['systemTime', 'startTime', 'stopTime', 'currentTime', 'multiplier', 'clockStep', 'clockRange', 'canAnimate', 'shouldAnimate']);
}
defineProperties(ClockViewModel.prototype, {
/**
* Gets the underlying Clock.
* @memberof ClockViewModel.prototype
- *
* @type {Clock}
*/
clock : {
@@ -214,24 +166,15 @@ define([
ClockViewModel.prototype.synchronize = function() {
var clock = this._clock;
- var startTime = clock.startTime;
- var stopTime = clock.stopTime;
- var currentTime = clock.currentTime;
- var multiplier = clock.multiplier;
- var clockStep = clock.clockStep;
- var clockRange = clock.clockRange;
- var canAnimate = clock.canAnimate;
- var shouldAnimate = clock.shouldAnimate;
-
this.systemTime = JulianDate.now();
- this.startTime = startTime;
- this.stopTime = stopTime;
- this.currentTime = currentTime;
- this.multiplier = multiplier;
- this.clockStep = clockStep;
- this.clockRange = clockRange;
- this.canAnimate = canAnimate;
- this.shouldAnimate = shouldAnimate;
+ this.startTime = clock.startTime;
+ this.stopTime = clock.stopTime;
+ this.currentTime = clock.currentTime;
+ this.multiplier = clock.multiplier;
+ this.clockStep = clock.clockStep;
+ this.clockRange = clock.clockRange;
+ this.canAnimate = clock.canAnimate;
+ this.shouldAnimate = clock.shouldAnimate;
};
/**
diff --git a/Specs/Core/ClockSpec.js b/Specs/Core/ClockSpec.js
index c0003f2509fc..b7ba51e50e97 100644
--- a/Specs/Core/ClockSpec.js
+++ b/Specs/Core/ClockSpec.js
@@ -3,26 +3,30 @@ defineSuite([
'Core/Clock',
'Core/ClockRange',
'Core/ClockStep',
+ 'Core/defined',
'Core/JulianDate',
'Specs/pollToPromise'
], function(
Clock,
ClockRange,
ClockStep,
+ defined,
JulianDate,
pollToPromise) {
'use strict';
- it('constructor sets default parameters', function() {
+ it('sets default parameters when constructed', function() {
var clock = new Clock();
expect(clock.stopTime).toEqual(JulianDate.addDays(clock.startTime, 1, new JulianDate()));
expect(clock.startTime).toEqual(clock.currentTime);
+ expect(clock.multiplier).toEqual(1.0);
expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK_MULTIPLIER);
expect(clock.clockRange).toEqual(ClockRange.UNBOUNDED);
- expect(clock.multiplier).toEqual(1.0);
+ expect(clock.canAnimate).toEqual(true);
+ expect(clock.shouldAnimate).toEqual(true);
});
- it('constructor sets provided parameters correctly', function() {
+ it('sets provided constructor parameters correctly', function() {
var start = new JulianDate(12);
var stop = new JulianDate(112);
var currentTime = new JulianDate(13);
@@ -30,67 +34,84 @@ defineSuite([
var range = ClockRange.LOOP_STOP;
var multiplier = 1.5;
var clock = new Clock({
+ startTime : start,
+ stopTime : stop,
currentTime : currentTime,
clockStep : step,
multiplier : multiplier,
- startTime : start,
- stopTime : stop,
clockRange : range
});
+
expect(clock.startTime).toEqual(start);
+ expect(clock.startTime).not.toBe(start);
expect(clock.stopTime).toEqual(stop);
+ expect(clock.stopTime).not.toBe(stop);
expect(clock.currentTime).toEqual(currentTime);
+ expect(clock.currentTime).not.toBe(currentTime);
expect(clock.clockStep).toEqual(step);
expect(clock.clockRange).toEqual(range);
expect(clock.multiplier).toEqual(multiplier);
+ expect(clock.canAnimate).toEqual(true);
+ expect(clock.shouldAnimate).toEqual(true);
+
+ clock = new Clock({
+ canAnimate : false
+ });
+ expect(clock.canAnimate).toEqual(false);
+
+ clock = new Clock({
+ shouldAnimate : false
+ });
+ expect(clock.shouldAnimate).toEqual(false);
});
- it('constructor works with no currentTime parameter', function() {
+ it('works when constructed with no currentTime parameter', function() {
var start = new JulianDate(12);
var stop = new JulianDate(112);
- var currentTime = new JulianDate(12);
var step = ClockStep.TICK_DEPENDENT;
var range = ClockRange.LOOP_STOP;
var multiplier = 1.5;
var clock = new Clock({
- clockStep : step,
- multiplier : multiplier,
startTime : start,
stopTime : stop,
+ clockStep : step,
+ multiplier : multiplier,
clockRange : range
});
expect(clock.startTime).toEqual(start);
expect(clock.stopTime).toEqual(stop);
- expect(clock.currentTime).toEqual(currentTime);
+ expect(clock.currentTime).toEqual(start);
expect(clock.clockStep).toEqual(step);
expect(clock.clockRange).toEqual(range);
expect(clock.multiplier).toEqual(multiplier);
+ expect(clock.canAnimate).toEqual(true);
+ expect(clock.shouldAnimate).toEqual(true);
});
- it('constructor works with no startTime parameter', function() {
+ it('works when constructed with no startTime parameter', function() {
var stop = new JulianDate(112);
var currentTime = new JulianDate(13);
var step = ClockStep.TICK_DEPENDENT;
var range = ClockRange.LOOP_STOP;
var multiplier = 1.5;
var clock = new Clock({
+ stopTime : stop,
currentTime : currentTime,
clockStep : step,
multiplier : multiplier,
- stopTime : stop,
clockRange : range
});
- expect(clock.startTime).toEqual(clock.currentTime);
+ expect(clock.startTime).toEqual(currentTime);
expect(clock.stopTime).toEqual(stop);
expect(clock.currentTime).toEqual(currentTime);
expect(clock.clockStep).toEqual(step);
expect(clock.clockRange).toEqual(range);
expect(clock.multiplier).toEqual(multiplier);
+ expect(clock.canAnimate).toEqual(true);
+ expect(clock.shouldAnimate).toEqual(true);
});
- it('constructor works with no start or stop time', function() {
- var start = new JulianDate(12);
- var stop = new JulianDate(13);
+ it('works when constructed with no startTime or stopTime', function() {
var currentTime = new JulianDate(12);
var step = ClockStep.TICK_DEPENDENT;
var range = ClockRange.LOOP_STOP;
@@ -101,93 +122,108 @@ defineSuite([
multiplier : multiplier,
clockRange : range
});
- expect(clock.startTime).toEqual(start);
- expect(clock.stopTime).toEqual(stop);
+ var expectedStop = JulianDate.addDays(currentTime, 1.0, new JulianDate());
+ expect(clock.startTime).toEqual(currentTime);
+ expect(clock.stopTime).toEqual(expectedStop);
expect(clock.currentTime).toEqual(currentTime);
expect(clock.clockStep).toEqual(step);
expect(clock.clockRange).toEqual(range);
expect(clock.multiplier).toEqual(multiplier);
+ expect(clock.canAnimate).toEqual(true);
+ expect(clock.shouldAnimate).toEqual(true);
});
- it('constructor works with no start or current time', function() {
- var start = new JulianDate(12);
+ it('works when constructed with no startTime or currentTime', function() {
var stop = new JulianDate(13);
- var currentTime = new JulianDate(12);
var step = ClockStep.TICK_DEPENDENT;
var range = ClockRange.LOOP_STOP;
var multiplier = 1.5;
var clock = new Clock({
+ stopTime : stop,
clockStep : step,
multiplier : multiplier,
- stopTime : stop,
clockRange : range
});
- expect(clock.startTime).toEqual(start);
+ var expectedStart = JulianDate.addDays(stop, -1.0, new JulianDate());
+ expect(clock.startTime).toEqual(expectedStart);
expect(clock.stopTime).toEqual(stop);
- expect(clock.currentTime).toEqual(currentTime);
+ expect(clock.currentTime).toEqual(expectedStart);
expect(clock.clockStep).toEqual(step);
expect(clock.clockRange).toEqual(range);
expect(clock.multiplier).toEqual(multiplier);
+ expect(clock.canAnimate).toEqual(true);
+ expect(clock.shouldAnimate).toEqual(true);
});
-
- it('constructor works with no current or stop time', function() {
+ it('works when constructed with no currentTime or stopTime', function() {
var start = new JulianDate(12);
- var stop = new JulianDate(13);
- var currentTime = new JulianDate(12);
var step = ClockStep.TICK_DEPENDENT;
var range = ClockRange.LOOP_STOP;
var multiplier = 1.5;
var clock = new Clock({
+ startTime : start,
clockStep : step,
multiplier : multiplier,
- startTime : start,
clockRange : range
});
+ var expectedStop = JulianDate.addDays(start, 1.0, new JulianDate());
expect(clock.startTime).toEqual(start);
- expect(clock.stopTime).toEqual(stop);
- expect(clock.currentTime).toEqual(currentTime);
+ expect(clock.stopTime).toEqual(expectedStop);
+ expect(clock.currentTime).toEqual(start);
expect(clock.clockStep).toEqual(step);
expect(clock.clockRange).toEqual(range);
expect(clock.multiplier).toEqual(multiplier);
+ expect(clock.canAnimate).toEqual(true);
+ expect(clock.shouldAnimate).toEqual(true);
});
- it('constructor works with no stopTime parameter', function() {
+ it('works when constructed with no stopTime parameter', function() {
var start = new JulianDate(12);
- var stop = new JulianDate(13);
var currentTime = new JulianDate(12);
var step = ClockStep.TICK_DEPENDENT;
var range = ClockRange.LOOP_STOP;
var multiplier = 1.5;
var clock = new Clock({
+ startTime : start,
currentTime : currentTime,
clockStep : step,
multiplier : multiplier,
- startTime : start,
clockRange : range
});
+ var expectedStop = JulianDate.addDays(start, 1.0, new JulianDate());
expect(clock.startTime).toEqual(start);
- expect(clock.stopTime).toEqual(stop);
+ expect(clock.stopTime).toEqual(expectedStop);
expect(clock.currentTime).toEqual(currentTime);
expect(clock.clockStep).toEqual(step);
expect(clock.clockRange).toEqual(range);
expect(clock.multiplier).toEqual(multiplier);
+ expect(clock.canAnimate).toEqual(true);
+ expect(clock.shouldAnimate).toEqual(true);
});
- it('Tick dependant clock step works animating forward.', function() {
+ it('throws when constructed if start time is after stop time', function() {
+ var start = new JulianDate(1);
+ var stop = new JulianDate(0);
+ expect(function() {
+ return new Clock({
+ startTime : start,
+ stopTime : stop
+ });
+ }).toThrowDeveloperError();
+ });
+
+ it('animates forward in TICK_DEPENDENT mode', function() {
var start = new JulianDate(0);
var stop = new JulianDate(1);
var currentTime = new JulianDate(0.5);
- var step = ClockStep.TICK_DEPENDENT;
- var range = ClockRange.LOOP_STOP;
var multiplier = 1.5;
var clock = new Clock({
- currentTime : currentTime,
- clockStep : step,
- multiplier : multiplier,
startTime : start,
stopTime : stop,
- clockRange : range
+ currentTime : currentTime,
+ clockStep : ClockStep.TICK_DEPENDENT,
+ multiplier : multiplier,
+ clockRange : ClockRange.LOOP_STOP
});
expect(clock.currentTime).toEqual(currentTime);
@@ -200,20 +236,18 @@ defineSuite([
expect(clock.currentTime).toEqual(currentTime);
});
- it('Tick dependant clock step works animating backwards.', function() {
+ it('animates backwards in TICK_DEPENDENT mode', function() {
var start = new JulianDate(0);
var stop = new JulianDate(1);
var currentTime = new JulianDate(0.5);
- var step = ClockStep.TICK_DEPENDENT;
- var range = ClockRange.LOOP_STOP;
var multiplier = -1.5;
var clock = new Clock({
- currentTime : currentTime,
- clockStep : step,
- multiplier : multiplier,
startTime : start,
stopTime : stop,
- clockRange : range
+ currentTime : currentTime,
+ clockStep : ClockStep.TICK_DEPENDENT,
+ multiplier : multiplier,
+ clockRange : ClockRange.LOOP_STOP
});
expect(clock.currentTime).toEqual(currentTime);
@@ -226,20 +260,18 @@ defineSuite([
expect(clock.currentTime).toEqual(currentTime);
});
- it('Tick dependant clock step works unbounded animating forward.', function() {
+ it('animates forwards past stop time in UNBOUNDED TICK_DEPENDENT mode', function() {
var start = new JulianDate(0);
var stop = new JulianDate(1);
- var currentTime = new JulianDate(1);
- var step = ClockStep.TICK_DEPENDENT;
- var range = ClockRange.UNBOUNDED;
+ var currentTime = stop;
var multiplier = 1.5;
var clock = new Clock({
- currentTime : currentTime,
- clockStep : step,
- multiplier : multiplier,
startTime : start,
stopTime : stop,
- clockRange : range
+ currentTime : currentTime,
+ clockStep : ClockStep.TICK_DEPENDENT,
+ multiplier : multiplier,
+ clockRange : ClockRange.UNBOUNDED
});
expect(clock.currentTime).toEqual(currentTime);
@@ -252,20 +284,18 @@ defineSuite([
expect(clock.currentTime).toEqual(currentTime);
});
- it('Tick dependant clock step works unbounded animating backwards.', function() {
+ it('animates backwards past start time in UNBOUNDED TICK_DEPENDENT mode', function() {
var start = new JulianDate(0);
var stop = new JulianDate(1);
- var currentTime = new JulianDate(0);
- var step = ClockStep.TICK_DEPENDENT;
- var range = ClockRange.UNBOUNDED;
+ var currentTime = start;
var multiplier = -1.5;
var clock = new Clock({
- currentTime : currentTime,
- clockStep : step,
- multiplier : multiplier,
startTime : start,
stopTime : stop,
- clockRange : range
+ currentTime : currentTime,
+ clockStep : ClockStep.TICK_DEPENDENT,
+ multiplier : multiplier,
+ clockRange : ClockRange.UNBOUNDED
});
expect(clock.currentTime).toEqual(currentTime);
@@ -278,20 +308,18 @@ defineSuite([
expect(clock.currentTime).toEqual(currentTime);
});
- it('Tick dependant clock loops animating forward.', function() {
+ it('loops back to start time when animating forward past stop time in LOOP_STOP TICK_DEPENDENT mode', function() {
var start = new JulianDate(0);
var stop = new JulianDate(1);
- var currentTime = new JulianDate(1);
- var step = ClockStep.TICK_DEPENDENT;
- var range = ClockRange.LOOP_STOP;
+ var currentTime = stop;
var multiplier = 1.5;
var clock = new Clock({
- currentTime : currentTime,
- clockStep : step,
- multiplier : multiplier,
startTime : start,
stopTime : stop,
- clockRange : range
+ currentTime : currentTime,
+ clockStep : ClockStep.TICK_DEPENDENT,
+ multiplier : multiplier,
+ clockRange : ClockRange.LOOP_STOP
});
expect(clock.currentTime).toEqual(currentTime);
@@ -304,21 +332,18 @@ defineSuite([
expect(clock.currentTime).toEqual(currentTime);
});
- it('Tick dependant clock step stops at start when animating backwards with ClockRange.LOOP_STOP.', function() {
+ it('stops at start when animating backwards past start time in LOOP_STOP TICK_DEPENDENT mode', function() {
var start = new JulianDate(0);
var stop = new JulianDate(1);
-
- var currentTime = new JulianDate(0);
- var step = ClockStep.TICK_DEPENDENT;
- var range = ClockRange.LOOP_STOP;
+ var currentTime = start;
var multiplier = -100.0;
var clock = new Clock({
- currentTime : currentTime,
- clockStep : step,
- multiplier : multiplier,
startTime : start,
stopTime : stop,
- clockRange : range
+ currentTime : currentTime,
+ clockStep : ClockStep.TICK_DEPENDENT,
+ multiplier : multiplier,
+ clockRange : ClockRange.LOOP_STOP
});
expect(clock.currentTime).toEqual(currentTime);
@@ -326,21 +351,18 @@ defineSuite([
expect(start).toEqual(clock.currentTime);
});
- it('Tick dependant clock step stops at end when animating forwards.', function() {
+ it('stops at stop time when animating forwards past stop time in CLAMPED TICK_DEPENDENT mode', function() {
var start = new JulianDate(0);
var stop = new JulianDate(1);
-
- var currentTime = new JulianDate(1);
- var step = ClockStep.TICK_DEPENDENT;
- var range = ClockRange.CLAMPED;
+ var currentTime = stop;
var multiplier = 100.0;
var clock = new Clock({
- currentTime : currentTime,
- clockStep : step,
- multiplier : multiplier,
startTime : start,
stopTime : stop,
- clockRange : range
+ currentTime : currentTime,
+ clockStep : ClockStep.TICK_DEPENDENT,
+ multiplier : multiplier,
+ clockRange : ClockRange.CLAMPED
});
expect(clock.currentTime).toEqual(currentTime);
@@ -348,35 +370,18 @@ defineSuite([
expect(stop).toEqual(clock.currentTime);
});
- it('Ticks in real-time.', function() {
- //We can't numerically validate the real-time clock, but we
- //can at least make sure the code executes.
- var clock = new Clock({
- clockStep : ClockStep.SYSTEM_CLOCK
- });
- var time1 = JulianDate.clone(clock.tick());
-
- return pollToPromise(function() {
- var time2 = clock.tick();
- return JulianDate.greaterThan(time2, time1);
- });
- });
-
- it('Tick dependant clock step stops at start animating backwards.', function() {
+ it('stops at start time when animating backwards past start time in CLAMPED TICK_DEPENDENT mode', function() {
var start = new JulianDate(0);
var stop = new JulianDate(1);
-
- var currentTime = new JulianDate(0);
- var step = ClockStep.TICK_DEPENDENT;
- var range = ClockRange.CLAMPED;
+ var currentTime = start;
var multiplier = -100.0;
var clock = new Clock({
- currentTime : currentTime,
- clockStep : step,
- multiplier : multiplier,
startTime : start,
stopTime : stop,
- clockRange : range
+ currentTime : currentTime,
+ clockStep : ClockStep.TICK_DEPENDENT,
+ multiplier : multiplier,
+ clockRange : ClockRange.CLAMPED
});
expect(clock.currentTime).toEqual(currentTime);
@@ -384,66 +389,173 @@ defineSuite([
expect(start).toEqual(clock.currentTime);
});
- it('throws if start time is after stop time.', function() {
- var start = new JulianDate(1);
- var stop = new JulianDate(0);
- expect(function() {
- return new Clock({
- startTime : start,
- stopTime : stop
- });
- }).toThrowDeveloperError();
- });
+ describe('SYSTEM_CLOCK modes', function() {
+ var baseDate = new Date(2016, 6, 7);
- it('system clock multiplier clock step works fine', function() {
- var clock = new Clock({
- clockStep : ClockStep.SYSTEM_CLOCK_MULTIPLIER
+ beforeEach(function() {
+ jasmine.clock().install();
+ jasmine.clock().mockDate(baseDate);
+
+ if (typeof performance !== 'undefined' && defined(performance.now)) {
+ spyOn(performance, 'now').and.callFake(function() {
+ return Date.now();
+ });
+ }
+ });
+
+ afterEach(function() {
+ jasmine.clock().uninstall();
});
- var time1 = JulianDate.clone(clock.tick());
- return pollToPromise(function() {
+ it('uses current time in SYSTEM_CLOCK mode (real-time mode)', function() {
+ var clock = new Clock({
+ clockStep : ClockStep.SYSTEM_CLOCK
+ });
+
+ expect(clock.currentTime).toEqual(JulianDate.fromDate(baseDate));
+ expect(clock.multiplier).toEqual(1.0);
+ expect(clock.shouldAnimate).toEqual(true);
+
+ var time1 = clock.tick();
+ expect(time1).toEqual(JulianDate.fromDate(baseDate));
+
+ jasmine.clock().tick(1000);
+
var time2 = clock.tick();
- return JulianDate.greaterThan(time2, time1);
+ expect(time2).toEqual(JulianDate.addSeconds(JulianDate.fromDate(baseDate), 1.0, new JulianDate()));
});
- });
- it('clock does not advance if shouldAnimate is false and advances if true', function() {
- var clock = new Clock();
- var time1;
- var time2;
+ it('switches out of SYSTEM_CLOCK mode when changing currentTime', function() {
+ var clock = new Clock({
+ clockStep : ClockStep.SYSTEM_CLOCK
+ });
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
- clock.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER;
- var currentTime = clock.currentTime;
- clock.shouldAnimate = false;
- expect(currentTime).toEqual(clock.tick());
- expect(clock.currentTime).toEqual(currentTime);
- clock.shouldAnimate = true;
- time1 = JulianDate.clone(clock.tick());
+ clock.currentTime = clock.currentTime;
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
+
+ clock.currentTime = new JulianDate(1);
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK_MULTIPLIER);
+ });
+
+ it('switches out of SYSTEM_CLOCK mode when changing multiplier', function() {
+ var clock = new Clock({
+ clockStep : ClockStep.SYSTEM_CLOCK
+ });
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
+
+ clock.multiplier = clock.multiplier;
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
+
+ clock.multiplier = 1.5;
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK_MULTIPLIER);
+ });
+
+ it('switches out of SYSTEM_CLOCK mode when changing shouldAnimate', function() {
+ var clock = new Clock({
+ clockStep : ClockStep.SYSTEM_CLOCK
+ });
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
+
+ clock.shouldAnimate = clock.shouldAnimate;
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
+
+ clock.shouldAnimate = false;
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK_MULTIPLIER);
+ });
+
+ it('sets currentTime, multiplier and shouldAnimate when switching to SYSTEM_CLOCK mode', function() {
+ var clock = new Clock({
+ currentTime : new JulianDate(1),
+ clockStep : ClockStep.SYSTEM_CLOCK_MULTIPLIER,
+ multiplier : 1.5,
+ shouldAnimate : false
+ });
- return pollToPromise(function() {
- time2 = clock.tick();
- return JulianDate.greaterThan(time2, time1);
- }).then(function() {
clock.clockStep = ClockStep.SYSTEM_CLOCK;
- currentTime = clock.currentTime;
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
+ expect(clock.currentTime).toEqual(JulianDate.fromDate(baseDate));
+ expect(clock.multiplier).toEqual(1.0);
+ expect(clock.shouldAnimate).toEqual(true);
+ });
+
+ it('stays in SYSTEM_CLOCK mode when changing other unrelated properties', function() {
+ var clock = new Clock({
+ clockStep : ClockStep.SYSTEM_CLOCK
+ });
+
+ clock.startTime = new JulianDate(1);
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
+
+ clock.stopTime = new JulianDate(2);
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
+
+ clock.clockRange = ClockRange.CLAMP;
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
+
+ clock.canAnimate = false;
+ expect(clock.clockStep).toEqual(ClockStep.SYSTEM_CLOCK);
+ });
+
+ it('uses multiplier in SYSTEM_CLOCK_MULTIPLIER mode', function() {
+ var clock = new Clock({
+ clockStep : ClockStep.SYSTEM_CLOCK_MULTIPLIER,
+ multiplier : 2.0
+ });
+
+ var time1 = clock.tick();
+ expect(time1).toEqual(JulianDate.fromDate(baseDate));
+
+ jasmine.clock().tick(1000);
+
+ var time2 = clock.tick();
+ expect(time2).toEqual(JulianDate.addSeconds(JulianDate.fromDate(baseDate), 2.0, new JulianDate()));
+ });
+
+ it('does not advance if shouldAnimate is false and does advance if true', function() {
+ var start = JulianDate.fromDate(baseDate);
+
+ var clock = new Clock({
+ startTime : start,
+ clockStep : ClockStep.SYSTEM_CLOCK_MULTIPLIER
+ });
+
+ expect(clock.currentTime).toEqual(start);
clock.shouldAnimate = false;
- expect(currentTime).toEqual(clock.tick());
- expect(clock.currentTime).toEqual(currentTime);
+
+ jasmine.clock().tick(1000);
+
+ var time1 = clock.tick();
+ expect(time1).toEqual(start);
+ expect(clock.currentTime).toEqual(start);
+
clock.shouldAnimate = true;
- time1 = JulianDate.clone(clock.tick());
-
- return pollToPromise(function() {
- time2 = clock.tick();
- return JulianDate.greaterThan(time2, time1);
- }).then(function() {
- clock.clockStep = ClockStep.TICK_DEPENDENT;
- currentTime = JulianDate.clone(clock.currentTime);
- clock.shouldAnimate = false;
- expect(currentTime).toEqual(clock.tick());
- expect(clock.currentTime).toEqual(currentTime);
- clock.shouldAnimate = true;
- expect(JulianDate.greaterThan(clock.tick(), currentTime)).toEqual(true);
- });
+
+ jasmine.clock().tick(1000);
+
+ time1 = clock.tick();
+
+ expect(time1).toEqual(JulianDate.addSeconds(JulianDate.fromDate(baseDate), 1.0, new JulianDate()));
+
+ jasmine.clock().tick(1000);
+
+ var time2 = clock.tick();
+
+ expect(time2).toEqual(JulianDate.addSeconds(JulianDate.fromDate(baseDate), 2.0, new JulianDate()));
+
+ clock.currentTime = start;
+ clock.clockStep = ClockStep.TICK_DEPENDENT;
+
+ clock.shouldAnimate = false;
+
+ time1 = clock.tick();
+ expect(time1).toEqual(start);
+ expect(clock.currentTime).toEqual(start);
+
+ clock.shouldAnimate = true;
+ time1 = clock.tick();
+
+ expect(time1).toEqual(JulianDate.addSeconds(JulianDate.fromDate(baseDate), 1.0, new JulianDate()));
});
});
});
diff --git a/Specs/Widgets/Animation/AnimationViewModelSpec.js b/Specs/Widgets/Animation/AnimationViewModelSpec.js
index 639d99a90336..1d7b3a9b61fc 100644
--- a/Specs/Widgets/Animation/AnimationViewModelSpec.js
+++ b/Specs/Widgets/Animation/AnimationViewModelSpec.js
@@ -486,9 +486,9 @@ defineSuite([
viewModel.playRealtimeViewModel.command();
verifyRealtimeState(viewModel);
- //Play breaks realtime state
+ //Play does not break realtime state
viewModel.playForwardViewModel.command();
- verifyForwardState(viewModel);
+ verifyRealtimeState(viewModel);
expect(clockViewModel.multiplier).toEqual(1);
viewModel.playRealtimeViewModel.command();
@@ -499,7 +499,7 @@ defineSuite([
verifyForwardState(viewModel);
});
- it('real time mode toggles only if shouldAnimate is true', function() {
+ it('real time mode toggles off but not back on when shouldAnimate changes', function() {
var viewModel = new AnimationViewModel(clockViewModel);
viewModel.playRealtimeViewModel.command();
@@ -509,7 +509,7 @@ defineSuite([
expect(viewModel.playRealtimeViewModel.toggled).toEqual(false);
clockViewModel.shouldAnimate = true;
- expect(viewModel.playRealtimeViewModel.toggled).toEqual(true);
+ expect(viewModel.playRealtimeViewModel.toggled).toEqual(false);
});
it('Shuttle ring angles set expected multipliers', function() {
diff --git a/Specs/Widgets/Viewer/ViewerSpec.js b/Specs/Widgets/Viewer/ViewerSpec.js
index 152c3c1aca64..5975bd670773 100644
--- a/Specs/Widgets/Viewer/ViewerSpec.js
+++ b/Specs/Widgets/Viewer/ViewerSpec.js
@@ -687,8 +687,8 @@ defineSuite([
dataSource.clock.stopTime = JulianDate.fromIso8601('2014-08-21T02:00Z');
dataSource.clock.currentTime = JulianDate.fromIso8601('2014-08-02T00:00Z');
dataSource.clock.clockRange = ClockRange.UNBOUNDED;
- dataSource.clock.clockStep = ClockStep.SYSTEM_CLOCK;
- dataSource.clock.multiplier = 20.0;
+ dataSource.clock.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER;
+ dataSource.clock.multiplier = 10.0;
dataSource.changedEvent.raiseEvent(dataSource);
@@ -698,6 +698,13 @@ defineSuite([
expect(viewer.clock.clockRange).toEqual(dataSource.clock.clockRange);
expect(viewer.clock.clockStep).toEqual(dataSource.clock.clockStep);
expect(viewer.clock.multiplier).toEqual(dataSource.clock.multiplier);
+
+ dataSource.clock.clockStep = ClockStep.SYSTEM_CLOCK;
+ dataSource.clock.multiplier = 1.0;
+
+ dataSource.changedEvent.raiseEvent(dataSource);
+
+ expect(viewer.clock.clockStep).toEqual(dataSource.clock.clockStep);
});
it('can manually control the clock tracking', function() {