UNPKG

dvbcss-clocks

Version:

Javascript library implementing clock objects for modelling timelines. Useful in DVB CSS implementations.

218 lines (192 loc) 9.21 kB
/**************************************************************************** * Copyright 2017 British Broadcasting Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *****************************************************************************/ var WeakMap = require('weak-map'); var PRIVATE = new WeakMap(); /** * @exports Correlation * @class Correlation * * @classdesc * This is an immutable object representing a correlation. * It also can represent associated error/uncertaint information. * * <p>The point of correlation ([parentTime]{@link Correlation#parentTime}, [childTime]{@link Correlation#childTime}) represents a relationship between * a parent clock and a child clock - by saying that the parent clock * is at point [parentTime]{@link Correlation#parentTime} when the child clock is at point [childTime]{@link Correlation#childTime}. * * <p>Error information is represented as an [initialError]{@link Correlation#initialError} amount and a * [errorGrowthRate]{@link Correlation#errorGrowthRate}. The initial amount of error represents the amount * of uncertainty at the point of the correlation; and the growth rate represents * how much uncertainty increases by as you move further away from the point * of correlation. Both are in units of seconds, and seconds per second, of * the child clock. By default these are set to zero, so there is assumed to * be no error. * * <p>The properties of the correlation can be read: * <pre class="prettyprint"><code> * corr = new Correlation(10, 20, 0.5, 0.1); * p = corr.parentTime; * t = corr.childTime; * i = corr.initialError; * g = corr.errorGrowthRate; * </code></pre> * * <p>However the object is immutable. The properties cannot be set. Instead use * the butWith() method to create a new correlation "but with" some properties * changed: * <pre class="prettyprint"><code> * corr = new Correlation(10, 20, 0.5, 0.1); * corr2= corr.butWith({parentTime: 11, childTime:19}) * </code></pre> * * @constructor * @param {Number|object|Number[]} parentTimeOrObject - The parent time, or the whole correlation expressed as an object, or an array with the arguments in this order. * @param {Number} [parentTimeOrObject.parentTime] The parent time * @param {Number} [parentTimeOrObject.childTime] The child time. * @param {Number} [parentTimeOrObject.initialError] The initial error (in seconds) * @param {Number} [parentTimeOrObject.errorGrowthRate] The error growth rate (in seconds per second.) * @param {Number} [childTime] The child time. * @param {Number} [initialError] The initial error (in seconds) * @param {Number} [errorGrowthRate] The error growth rate (in seconds per second.) * * @example * // parentTime = 10, childTime=20, initialError=0, errorGrowthRate=0 * c = new Correlation(10, 20); * @example * // parentTime = 10, childTime=20, initialError=0.5, errorGrowthRate=0.1 * c = new Correlation(10, 20, 0.5, 0.1); * @example * // parentTime = 10, childTime=20, initialError=0.5, errorGrowthRate=0.1 * c = new Correlation([10, 20, 0.5, 0.1]) * @example * // parentTime = 10, childTime=20, initialError=0.5, errorGrowthRate=0.1 * c = new Correlation({parentTime:10, childTime:20, initialError:0.5, errorGrowthRate:0.1]) */ var Correlation = function(parentTimeOrObject, childTime, initialError, errorGrowthRate) { PRIVATE.set(this, {}); var priv = PRIVATE.get(this); var parentTime; if (Array.isArray(parentTimeOrObject)) { parentTime = parentTimeOrObject[0]; childTime = parentTimeOrObject[1]; initialError = parentTimeOrObject[2]; errorGrowthRate = parentTimeOrObject[3]; } else if (typeof parentTimeOrObject === "object") { parentTime = parentTimeOrObject.parentTime; childTime = parentTimeOrObject.childTime; initialError = parentTimeOrObject.initialError; errorGrowthRate = parentTimeOrObject.errorGrowthRate; } else { parentTime = parentTimeOrObject; } priv.parentTime = (typeof parentTime !== "undefined") ? parentTime : 0; priv.childTime = (typeof childTime !== "undefined") ? childTime : 0; priv.initialError = (typeof initialError !== "undefined") ? initialError : 0; priv.errorGrowthRate = (typeof errorGrowthRate !== "undefined") ? errorGrowthRate : 0; }; /** * Build a new correlation object, but with the properties changed listed as * named properties of the object passed. * * @param {object} changes An object where the property names and values represent the properties of the correlation to be changed. * @param {Number} [changes.parentTime] The parent time * @param {Number} [changes.childTime] The child time. * @param {Number} [changes.initialError] The initial error (in seconds) * @param {Number} [changes.errorGrowthRate] The error growth rate (in seconds per second.) * * @returns {Correlation} new Correlation object that is the same as this one, but with the specified changes. * * @example * var corr = new Correlation(1,2); * var corr2 = corr.butWith({parentTime:5}); * console.log(corr.parentTime, corr.childTime); // 5 2 */ Correlation.prototype.butWith = function(changes) { var priv = PRIVATE.get(this); if (typeof changes === "undefined") { return this; } else { var p = changes.parentTime; var c = changes.childTime; var i = changes.initialError; var g = changes.errorGrowthRate; if (typeof p === "undefined") { p = priv.parentTime; } if (typeof c === "undefined") { c = priv.childTime; } if (typeof i === "undefined") { i = priv.initialError; } if (typeof g === "undefined") { g = priv.errorGrowthRate; } return new Correlation(p,c,i,g); } }; /** * @var {Number} parentTime Parent Time. Along with the [childTime]{@link Correlation#childTime} it defines the point of correlation ([parentTime]{@link Correlation#parentTime}, [childTime]{@link Correlation#childTime}). Read only. * @memberof Correlation * @instance */ Object.defineProperty(Correlation.prototype, "parentTime", { get: function() { return PRIVATE.get(this).parentTime; }, set: function(v) { throw "Cannot set this property, object is immutable. Use butWith() method."; } }); /** * @var {Number} childTime Child Time. Along with the [parentTime]{@link Correlation#parentTime} it defines the point of correlation ([parentTime]{@link Correlation#parentTime}, [childTime]{@link Correlation#childTime}). Read only. * @memberof Correlation * @instance */ Object.defineProperty(Correlation.prototype, "childTime", { get: function() { return PRIVATE.get(this).childTime; }, set: function(v) { throw "Cannot set this property, object is immutable. Use butWith() method."; } }); /** * @var {Number} initialError The intial amount of error/uncertainly (in seconds) at the point of correlation ([parentTime]{@link Correlation#parentTime}, [childTime]{@link Correlation#childTime}). Read only. * @memberof Correlation * @instance */ Object.defineProperty(Correlation.prototype, "initialError", { get: function() { return PRIVATE.get(this).initialError; }, set: function(v) { throw "Cannot set this property, object is immutable. Use butWith() method."; } }); /** * @var {Number} errorGrowthRate The amonut by which error/uncertainly will grown (in seconds) for every second of child clock time away from the point of correlation ([parentTime]{@link Correlation#parentTime}, [childTime]{@link Correlation#childTime}). Read only. * @memberof Correlation * @instance */ Object.defineProperty(Correlation.prototype, "errorGrowthRate", { get: function() { return PRIVATE.get(this).errorGrowthRate; }, set: function(v) { throw "Cannot set this property, object is immutable. Use butWith() method."; } }); /** * Compare this correlation with another to check if they are the same. * @param {Correlation} obj - another correlation to compare with. * @returns {boolean} True if this correlation represents the same correlation and error/uncertainty as the one provided. */ Correlation.prototype.equals = function(obj) { var priv = PRIVATE.get(this); return priv.parentTime === obj.parentTime && priv.childTime === obj.childTime && priv.initialError === obj.initialError && priv.errorGrowthRate === obj.errorGrowthRate; }; Correlation.prototype.toJSON = function() { var priv = PRIVATE.get(this); return JSON.stringify( { parentTime : priv.parentTime, childTime : priv.childTime, initialError : priv.initialError, errorGrowthRate : priv.errorGrowthRate } ); }; module.exports = Correlation;