diff --git a/src/api/time/TimeAPI.js b/src/api/time/TimeAPI.js index 0720c9c073..9c96cf14bb 100644 --- a/src/api/time/TimeAPI.js +++ b/src/api/time/TimeAPI.js @@ -25,15 +25,21 @@ define(['EventEmitter'], function (EventEmitter) { var tick; /** - * The public API for setting and querying time conductor state. The - * time conductor is the means by which the temporal bounds of a view - * are controlled. Time-sensitive views will typically respond to - * changes to bounds or other properties of the time conductor and - * update the data displayed based on the time conductor state. + * The public API for setting and querying the temporal state of the + * application. The concept of time is integral to Open MCT, and at least + * one {@link TimeSystem}, as well as some default time bounds must be + * registered and enabled via {@link TimeAPI.addTimeSystem} and + * {@link TimeAPI.timeSystem} respectively for Open MCT to work. + * + * Time-sensitive views will typically respond to changes to bounds or other + * properties of the time conductor and update the data displayed based on + * the temporal state of the application. The current time bounds are also + * used in queries for historical data. + * + * The TimeAPI extends the EventEmitter class. A number of events are + * fired when properties of the time conductor change, which are documented + * below. * - * The TimeConductor extends the EventEmitter class. A number of events are - * fired when properties of the time conductor change, which are - * documented below. * @interface * @memberof module:openmct */ @@ -56,9 +62,8 @@ define(['EventEmitter'], function (EventEmitter) { this.offsets = undefined; /** - * Tick is not exposed via public API, even @privately to avoid misuse. + * Tick is private to avoid misuse. */ - tick = function (timestamp) { var newBounds = { start: timestamp + this.offsets.start, @@ -79,26 +84,84 @@ define(['EventEmitter'], function (EventEmitter) { TimeAPI.prototype = Object.create(EventEmitter.prototype); + /** + * A TimeSystem provides meaning to the values returned by the TimeAPI. Open + * MCT supports multiple different types of time values, although all are + * intrinsically represented by numbers, the meaning of those numbers can + * differ depending on context. + * + * A default time system is provided by Open MCT in the form of the {@link UTCTimeSystem}, + * which represents integer values as ms in the Unix epoch. An example of + * another time system might be "sols" for a Martian mission. TimeSystems do + * not address the issue of converting between time systems. + * + * @typedef {object} TimeSystem + * @property {string} key A unique identifier + * @property {string} name A human-readable descriptor + * @property {string} [cssClass] Specify a css class defining an icon for + * this time system. This will be visible next to the time system in the + * menu in the Time Conductor + * @property {string} timeFormat The key of a format to use when displaying + * discrete timestamps from this time system + * @property {string} [durationFormat] The key of a format to use when + * displaying a duration or relative span of time in this time system. + */ + + /** + * Register a new time system. Once registered it can activated using + * {@link TimeAPI.timeSystem}, and can be referenced via its key in [Time Conductor configuration](@link https://github.com/nasa/openmct/blob/master/API.md#time-conductor). + * @memberof module:openmct.TimeAPI# + * @param {TimeSystem} timeSystem A time system object. + */ TimeAPI.prototype.addTimeSystem = function (timeSystem) { this.timeSystems.set(timeSystem.key, timeSystem); }; + /** + * @returns {TimeSystem[]} + */ TimeAPI.prototype.getAllTimeSystems = function () { return Array.from(this.timeSystems.values()); }; + /** + * Clocks provide a timing source that is used to + * automatically update the time bounds of the data displayed in Open MCT. + * + * @typedef {object} Clock + * @memberof openmct.timeAPI + * @property {string} key A unique identifier + * @property {string} name A human-readable name. The name will be used to + * represent this clock in the Time Conductor UI + * @property {string} description A longer description, ideally identifying + * what the clock ticks on. + * @property {function} currentValue Returns the last value generated by a tick, or a default value + * if no ticking has yet occurred + * @see {LocalClock} + */ + + /** + * Register a new Clock. + * @memberof module:openmct.TimeAPI# + * @param {Clock} clock + */ TimeAPI.prototype.addClock = function (clock) { this.clocks.set(clock.key, clock); }; + /** + * @memberof module:openmct.TimeAPI# + * @returns {Clock[]} + * @memberof module:openmct.TimeAPI# + */ TimeAPI.prototype.getAllClocks = function () { return Array.from(this.clocks.values()); }; /** - * Validate the given bounds. This can be used for pre-validation of - * bounds, for example by views validating user inputs. - * @param bounds The start and end time of the conductor. + * Validate the given bounds. This can be used for pre-validation of bounds, + * for example by views validating user inputs. + * @param {TimeBounds} bounds The start and end time of the conductor. * @returns {string | true} A validation error, or true if valid * @memberof module:openmct.TimeAPI# * @method validateBounds @@ -118,8 +181,8 @@ define(['EventEmitter'], function (EventEmitter) { /** * Validate the given offsets. This can be used for pre-validation of - * offsetse, for example by views validating user inputs. - * @param offsets The start and end offsets from a 'now' value. + * offsets, for example by views validating user inputs. + * @param {ClockOffsets} offsets The start and end offsets from a 'now' value. * @returns {string | true} A validation error, or true if valid * @memberof module:openmct.TimeAPI# * @method validateBounds @@ -140,9 +203,11 @@ define(['EventEmitter'], function (EventEmitter) { }; /** - * @typedef {Object} TimeConductorBounds - * @property {number} start The start time displayed by the time conductor in ms since epoch. Epoch determined by current time system - * @property {number} end The end time displayed by the time conductor in ms since epoch. + * @typedef {Object} TimeBounds + * @property {number} start The start time displayed by the time conductor + * in ms since epoch. Epoch determined by currently active time system + * @property {number} end The end time displayed by the time conductor in ms + * since epoch. * @memberof module:openmct.TimeAPI~ */ @@ -186,9 +251,7 @@ define(['EventEmitter'], function (EventEmitter) { }; /** - * Get or set the time system of the TimeAPI. Time systems determine - * units, epoch, and other aspects of time representation. When changing - * the time system in use, new valid bounds must also be provided. + * Get or set the time system of the TimeAPI. * @param {TimeSystem | string} timeSystem * @param {module:openmct.TimeAPI~TimeConductorBounds} bounds * @fires module:openmct.TimeAPI~timeSystem @@ -242,10 +305,11 @@ define(['EventEmitter'], function (EventEmitter) { }; /** - * Get or set the Time of Interest. The Time of Interest is the temporal - * focus of the current view. It can be manipulated by the user from the - * time conductor or from other views.The time of interest can - * effectively be unset by assigning a value of 'undefined'. + * Get or set the Time of Interest. The Time of Interest is a single point + * in time, and constitutes the temporal focus of application views. It can + * be manipulated by the user from the time conductor or from other views. + * The time of interest can effectively be unset by assigning a value of + * 'undefined'. * @fires module:openmct.TimeAPI~timeOfInterest * @param newTOI * @returns {number} the current time of interest @@ -268,11 +332,14 @@ define(['EventEmitter'], function (EventEmitter) { /** * Set the active clock. Tick source will be immediately subscribed to - * and ticking will begin. Offsets from 'now' must also be provided. + * and ticking will begin. Offsets from 'now' must also be provided. A clock + * can be unset by calling {@link stopClock}. + * * @param {Clock || string} The clock to activate, or its key * @param {ClockOffsets} offsets on each tick these will be used to calculate * the start and end bounds. This maintains a sliding time window of a fixed * width that automatically updates. + * @fires module:openmct.TimeAPI~clock * @return {Clock} the currently active clock; */ TimeAPI.prototype.clock = function (keyOrClock, offsets) { @@ -303,6 +370,13 @@ define(['EventEmitter'], function (EventEmitter) { this.activeClock.on("tick", tick); } + /** + * The active clock has changed. Clock can be unset by calling {@link stopClock} + * @event clock + * @memberof module:openmct.TimeAPI~ + * @property {Clock} clock The newly activated clock, or undefined + * if the system is no longer following a clock source + */ this.emit("clock", this.activeClock); } else if (arguments.length === 1){ @@ -312,6 +386,26 @@ define(['EventEmitter'], function (EventEmitter) { return this.activeClock; }; + /** + * Clock offsets are used to calculate temporal bounds when the system is + * ticking on a clock source. + * + * @typedef {object} ClockOffsets + * @property {number} start A time span relative to the current value of the + * ticking clock, from which start bounds will be calculated. This value must + * be < 0. When a clock is active, bounds will be calculated automatically + * based on the value provided by the clock, and the defined clock offsets. + * @property {number} end A time span relative to the current value of the + * ticking clock, from which end bounds will be calculated. This value must + * be >= 0. + */ + /** + * Get or set the currently applied clock offsets. If no parameter is provided, + * the current value will be returned. If provided, the new value will be + * used as the new clock offsets. + * @param {ClockOffsets} offsets + * @returns {ClockOffsets} + */ TimeAPI.prototype.clockOffsets = function (offsets) { if (arguments.length > 0) { @@ -330,11 +424,23 @@ define(['EventEmitter'], function (EventEmitter) { this.bounds(newBounds); + /** + * Event that is triggered when clock offsets change. + * @event clockOffsets + * @memberof module:openmct.TimeAPI~ + * @property {ClockOffsets} clockOffsets The newly activated clock + * offsets. + */ this.emit("clockOffsets", offsets); } return this.offsets; }; + /** + * Stop the currently active clock from ticking, and unset it. This will + * revert all views to showing a static time frame defined by the current + * bounds. + */ TimeAPI.prototype.stopClock = function () { if (this.activeClock) { this.clock(undefined, undefined);