mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-26 17:46:26 +03:00
562a2d567b
This enables the eslint rule requiring jsdocs on all class
declarations, function declarations, and methods.
Unfortunately, there are two problems with this:
1. We don't use class _declarations_, we use class _expressions_,
which are not covered by this rule. So it does not enforce jsdoc at
the class level.
2. We tend to document a class at the class-level, rather than at the
constructor. But a constructor counts as a method for eslint, so it
requires docs on the constructor. There is no way to configure it to
make an exception for trivial constructors.
So for all trivial (no-argument) constructors, we add empty jsdocs:
/** */
constructor() {
This was quicker and easier than setting up some alternative plugin in
eslint to make an exception for us.
The good news is that this rule caught several undocumented parameters
and places where the jsdoc comment was malformed. So fixing those
also improves the compiler's ability to enforce types.
Change-Id: Icbc46ed690c94e53d354648a883119524f8fca45
157 lines
3.4 KiB
JavaScript
157 lines
3.4 KiB
JavaScript
/*! @license
|
|
* Shaka Player
|
|
* Copyright 2016 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
goog.provide('shaka.util.StateHistory');
|
|
|
|
goog.require('goog.asserts');
|
|
goog.require('shaka.log');
|
|
|
|
|
|
/**
|
|
* This class is used to track the time spent in arbitrary states. When told of
|
|
* a state, it will assume that state was active until a new state is provided.
|
|
* When provided with identical states back-to-back, the existing entry will be
|
|
* updated.
|
|
*
|
|
* @final
|
|
*/
|
|
shaka.util.StateHistory = class {
|
|
/** */
|
|
constructor() {
|
|
/**
|
|
* The state that we think is still the current change. It is "open" for
|
|
* updating.
|
|
*
|
|
* @private {?shaka.extern.StateChange}
|
|
*/
|
|
this.open_ = null;
|
|
|
|
/**
|
|
* The stats that are "closed" for updating. The "open" state becomes closed
|
|
* once we move to a new state.
|
|
*
|
|
* @private {!Array.<shaka.extern.StateChange>}
|
|
*/
|
|
this.closed_ = [];
|
|
}
|
|
|
|
/**
|
|
* @param {string} state
|
|
*/
|
|
update(state) {
|
|
// |open_| will only be |null| when we first call |update|.
|
|
if (this.open_ == null) {
|
|
this.start_(state);
|
|
} else {
|
|
this.update_(state);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Go through all entries in the history and count how much time was spend in
|
|
* the given state.
|
|
*
|
|
* @param {string} state
|
|
* @return {number}
|
|
*/
|
|
getTimeSpentIn(state) {
|
|
let sum = 0;
|
|
|
|
if (this.open_ && this.open_.state == state) {
|
|
sum += this.open_.duration;
|
|
}
|
|
|
|
for (const entry of this.closed_) {
|
|
sum += entry.state == state ? entry.duration : 0;
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
/**
|
|
* Get a copy of each state change entry in the history. A copy of each entry
|
|
* is created to break the reference to the internal data.
|
|
*
|
|
* @return {!Array.<shaka.extern.StateChange>}
|
|
*/
|
|
getCopy() {
|
|
const clone = (entry) => {
|
|
return {
|
|
timestamp: entry.timestamp,
|
|
state: entry.state,
|
|
duration: entry.duration,
|
|
};
|
|
};
|
|
|
|
const copy = [];
|
|
for (const entry of this.closed_) {
|
|
copy.push(clone(entry));
|
|
}
|
|
if (this.open_) {
|
|
copy.push(clone(this.open_));
|
|
}
|
|
|
|
return copy;
|
|
}
|
|
|
|
/**
|
|
* @param {string} state
|
|
* @private
|
|
*/
|
|
start_(state) {
|
|
goog.asserts.assert(
|
|
this.open_ == null,
|
|
'There must be no open entry in order when we start');
|
|
shaka.log.v1('Changing Player state to', state);
|
|
|
|
this.open_ = {
|
|
timestamp: this.getNowInSeconds_(),
|
|
state: state,
|
|
duration: 0,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param {string} state
|
|
* @private
|
|
*/
|
|
update_(state) {
|
|
goog.asserts.assert(
|
|
this.open_,
|
|
'There must be an open entry in order to update it');
|
|
|
|
const currentTimeSeconds = this.getNowInSeconds_();
|
|
|
|
// Always update the duration so that it can always be as accurate as
|
|
// possible.
|
|
this.open_.duration = currentTimeSeconds - this.open_.timestamp;
|
|
|
|
// If the state has not changed, there is no need to add a new entry.
|
|
if (this.open_.state == state) {
|
|
return;
|
|
}
|
|
|
|
// We have changed states, so "close" the open state.
|
|
shaka.log.v1('Changing Player state to', state);
|
|
this.closed_.push(this.open_);
|
|
this.open_ = {
|
|
timestamp: currentTimeSeconds,
|
|
state: state,
|
|
duration: 0,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get the system time in seconds.
|
|
*
|
|
* @return {number}
|
|
* @private
|
|
*/
|
|
getNowInSeconds_() {
|
|
return Date.now() / 1000;
|
|
}
|
|
};
|