From 57c73241a0e8ce1615f7b3aca4c3ad8f69b7e8c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Velad=20Galv=C3=A1n?= Date: Mon, 4 Apr 2022 19:58:16 +0200 Subject: [PATCH] fix(performance): Eliminate use of ES6 generators (#4092) See: https://github.com/shaka-project/shaka-player/issues/4062#issuecomment-1077826210 Co-authored-by: @joeyparrish Issue #4062 --- build/conformance.textproto | 13 ++++ lib/cea/cea708_service.js | 8 ++- lib/cea/sei_processor.js | 9 ++- lib/dash/segment_list.js | 3 +- lib/hls/hls_parser.js | 12 ++-- lib/hls/manifest_text_parser.js | 6 +- lib/media/adaptation_set.js | 3 +- lib/media/mp4_segment_index_parser.js | 5 +- lib/media/time_ranges_utils.js | 4 +- lib/polyfill/all.js | 5 +- lib/util/buffer_utils.js | 4 +- lib/util/ebml_parser.js | 6 +- lib/util/iterables.js | 46 -------------- lib/util/mp4_box_parsers.js | 5 +- lib/util/mp4_parser.js | 5 +- lib/util/periods.js | 18 +++--- lib/util/pssh.js | 5 +- lib/util/string_utils.js | 3 +- lib/util/uint8array_utils.js | 3 +- test/cast/cast_receiver_integration.js | 5 +- .../dash_parser_content_protection_unit.js | 3 +- test/dash/mpd_utils_unit.js | 5 +- test/hls/hls_live_unit.js | 6 +- test/media/buffering_observer_unit.js | 3 +- test/media/streaming_engine_unit.js | 11 ++-- test/player_integration.js | 5 +- test/player_unit.js | 5 +- test/test/util/indexeddb_utils.js | 5 +- test/test/util/manifest_generator.js | 3 +- test/test/util/util.js | 9 +-- test/ui/ui_unit.js | 6 +- test/util/iterables_unit.js | 62 ------------------- 32 files changed, 79 insertions(+), 212 deletions(-) diff --git a/build/conformance.textproto b/build/conformance.textproto index c9c59f4e2d..bcbf158ecb 100644 --- a/build/conformance.textproto +++ b/build/conformance.textproto @@ -320,3 +320,16 @@ requirement: { "instead." whitelist_regexp: "lib/net/http_fetch_plugin.js" } + +# Disallow the use of generators, which are a major performance issue. See +# https://github.com/shaka-project/shaka-player/issues/4062#issuecomment-1079428268 +requirement: { + type: BANNED_CODE_PATTERN + value: + "/** @param {*} x */ " + "function *template(x) { yield x; }" + error_message: + "ES6 generators are a major performance issue! Find another solution. " + "See also https://bit.ly/3wAsoj5" + whitelist_regexp: "node_modules/" +} diff --git a/lib/cea/cea708_service.js b/lib/cea/cea708_service.js index af8c2615dc..63652c6f48 100644 --- a/lib/cea/cea708_service.js +++ b/lib/cea/cea708_service.js @@ -300,17 +300,19 @@ shaka.cea.Cea708Service = class { /** * Yields each non-null window specified in the 8-bit bitmap. * @param {number} bitmap 8 bits corresponding to each of the 8 windows. - * @return {!Iterable.} + * @return {!Array.} * @private */ - * getSpecifiedWindowIds_(bitmap) { + getSpecifiedWindowIds_(bitmap) { + const ids = []; for (let i = 0; i < 8; i++) { const windowSpecified = (bitmap & 0x01) === 0x01; if (windowSpecified && this.windows_[i]) { - yield i; + ids.push(i); } bitmap >>= 1; } + return ids; } /** diff --git a/lib/cea/sei_processor.js b/lib/cea/sei_processor.js index 320264d298..af89c854a5 100644 --- a/lib/cea/sei_processor.js +++ b/lib/cea/sei_processor.js @@ -14,9 +14,10 @@ shaka.cea.SeiProcessor = class { /** * Processes supplemental enhancement information data. * @param {!Uint8Array} naluData NALU from which SEI data is to be processed. - * @return {!Iterable.} + * @return {!Array.} */ - * process(naluData) { + process(naluData) { + const seiPayloads = []; const naluClone = this.removeEmu(naluData); // The following is an implementation of section 7.3.2.3.1 @@ -41,10 +42,12 @@ shaka.cea.SeiProcessor = class { // Payload type 4 is user_data_registered_itu_t_t35, as per the H.264 // spec. This payload type contains caption data. if (payloadType == 0x04) { - yield naluClone.subarray(offset, offset + payloadSize); + seiPayloads.push(naluClone.subarray(offset, offset + payloadSize)); } offset += payloadSize; } + + return seiPayloads; } diff --git a/lib/dash/segment_list.js b/lib/dash/segment_list.js index 2814e1f2b5..81dd7fe56f 100644 --- a/lib/dash/segment_list.js +++ b/lib/dash/segment_list.js @@ -15,7 +15,6 @@ goog.require('shaka.media.SegmentIndex'); goog.require('shaka.media.SegmentReference'); goog.require('shaka.util.Error'); goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.ManifestParserUtils'); goog.require('shaka.util.XmlUtils'); goog.requireType('shaka.dash.DashParser'); @@ -222,7 +221,7 @@ shaka.dash.SegmentList = class { /** @type {!Array.} */ const references = []; let prevEndTime = info.startTime; - for (const i of shaka.util.Iterables.range(max)) { + for (let i = 0; i < max; i++) { const segment = info.mediaSegments[i]; const mediaUri = ManifestParserUtils.resolveUris( baseUris, [segment.mediaUri]); diff --git a/lib/hls/hls_parser.js b/lib/hls/hls_parser.js index 6b3055239e..236fcae9e3 100644 --- a/lib/hls/hls_parser.js +++ b/lib/hls/hls_parser.js @@ -30,7 +30,6 @@ goog.require('shaka.util.CmcdManager'); goog.require('shaka.util.Error'); goog.require('shaka.util.FakeEvent'); goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.LanguageUtils'); goog.require('shaka.util.ManifestParserUtils'); goog.require('shaka.util.MimeUtils'); @@ -1869,8 +1868,8 @@ shaka.hls.HlsParser = class { // Create SegmentReferences for the partial segments. const partialSegmentRefs = []; if (this.lowLatencyMode_ && hlsSegment.partialSegments.length) { - const enumerate = (it) => shaka.util.Iterables.enumerate(it); - for (const {i, item} of enumerate(hlsSegment.partialSegments)) { + for (let i = 0; i < hlsSegment.partialSegments.length; i++) { + const item = hlsSegment.partialSegments[i]; const pPreviousReference = i == 0 ? previousReference : partialSegmentRefs[partialSegmentRefs.length - 1]; const pStartTime = (i == 0) ? startTime : pPreviousReference.endTime; @@ -1891,6 +1890,9 @@ shaka.hls.HlsParser = class { this.parseByteRange_(pPreviousReference, pByterange); } const pUri = item.getAttributeValue('URI'); + if (!pUri) { + continue; + } const pAbsoluteUri = shaka.hls.Utils.constructAbsoluteUri( absoluteMediaPlaylistUri, pUri); @@ -2066,8 +2068,8 @@ shaka.hls.HlsParser = class { /** @type {!Array.} */ const references = []; - const enumerate = (it) => shaka.util.Iterables.enumerate(it); - for (const {i, item} of enumerate(hlsSegments)) { + for (let i = 0; i < hlsSegments.length; i++) { + const item = hlsSegments[i]; const previousReference = references[references.length - 1]; const startTime = (i == 0) ? firstStartTime : previousReference.endTime; diff --git a/lib/hls/manifest_text_parser.js b/lib/hls/manifest_text_parser.js index a0c9fbb654..15c487716b 100644 --- a/lib/hls/manifest_text_parser.js +++ b/lib/hls/manifest_text_parser.js @@ -13,7 +13,6 @@ goog.require('shaka.hls.Segment'); goog.require('shaka.hls.Tag'); goog.require('shaka.hls.Utils'); goog.require('shaka.util.Error'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.StringUtils'); goog.require('shaka.util.TextParser'); @@ -82,8 +81,9 @@ shaka.hls.ManifestTextParser = class { const tags = []; // Initialize to "true" to skip the first element. skip = true; - const enumerate = (it) => shaka.util.Iterables.enumerate(it); - for (const {i, item: line, next} of enumerate(lines)) { + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const next = lines[i + 1]; // Skip comments if (shaka.hls.Utils.isComment(line) || skip) { skip = false; diff --git a/lib/media/adaptation_set.js b/lib/media/adaptation_set.js index 25cda09ccb..b4cf472e1b 100644 --- a/lib/media/adaptation_set.js +++ b/lib/media/adaptation_set.js @@ -8,7 +8,6 @@ goog.provide('shaka.media.AdaptationSet'); goog.require('goog.asserts'); goog.require('shaka.log'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.MimeUtils'); @@ -215,7 +214,7 @@ shaka.media.AdaptationSet = class { codecsA.sort(); codecsB.sort(); - for (const i of shaka.util.Iterables.range(codecsA.length)) { + for (let i = 0; i < codecsA.length; i++) { if (codecsA[i] != codecsB[i]) { return false; } diff --git a/lib/media/mp4_segment_index_parser.js b/lib/media/mp4_segment_index_parser.js index e684605045..f231b32bab 100644 --- a/lib/media/mp4_segment_index_parser.js +++ b/lib/media/mp4_segment_index_parser.js @@ -11,8 +11,6 @@ goog.require('shaka.log'); goog.require('shaka.media.InitSegmentReference'); goog.require('shaka.media.SegmentReference'); goog.require('shaka.util.Error'); -goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.Mp4Parser'); @@ -123,8 +121,7 @@ shaka.media.Mp4SegmentIndexParser = class { let unscaledStartTime = earliestPresentationTime; let startByte = sidxOffset + box.size + firstOffset; - for (const _ of shaka.util.Iterables.range(referenceCount)) { - shaka.util.Functional.ignored(_); + for (let i = 0; i < referenceCount; i++) { // |chunk| is 1 bit for |referenceType|, and 31 bits for |referenceSize|. const chunk = box.reader.readUint32(); const referenceType = (chunk & 0x80000000) >>> 31; diff --git a/lib/media/time_ranges_utils.js b/lib/media/time_ranges_utils.js index db38e4317b..7718389ed0 100644 --- a/lib/media/time_ranges_utils.js +++ b/lib/media/time_ranges_utils.js @@ -6,8 +6,6 @@ goog.provide('shaka.media.TimeRangesUtils'); -goog.require('shaka.util.Iterables'); - /** * @summary A set of utility functions for dealing with TimeRanges objects. @@ -157,7 +155,7 @@ shaka.media.TimeRangesUtils = class { return []; } const ret = []; - for (const i of shaka.util.Iterables.range(b.length)) { + for (let i = 0; i < b.length; i++) { ret.push({start: b.start(i), end: b.end(i)}); } return ret; diff --git a/lib/polyfill/all.js b/lib/polyfill/all.js index e5ad6bb420..a0337db699 100644 --- a/lib/polyfill/all.js +++ b/lib/polyfill/all.js @@ -7,7 +7,6 @@ goog.provide('shaka.polyfill'); goog.require('shaka.log'); -goog.require('shaka.util.Iterables'); /** @@ -40,8 +39,8 @@ shaka.polyfill = class { */ static register(polyfill, priority) { const newItem = {priority: priority || 0, callback: polyfill}; - const enumerate = (it) => shaka.util.Iterables.enumerate(it); - for (const {i, item} of enumerate(shaka.polyfill.polyfills_)) { + for (let i = 0; i < shaka.polyfill.polyfills_.length; i++) { + const item = shaka.polyfill.polyfills_[i]; if (item.priority < newItem.priority) { shaka.polyfill.polyfills_.splice(i, 0, newItem); return; diff --git a/lib/util/buffer_utils.js b/lib/util/buffer_utils.js index 141e8dd5c3..36540afb4a 100644 --- a/lib/util/buffer_utils.js +++ b/lib/util/buffer_utils.js @@ -6,8 +6,6 @@ goog.provide('shaka.util.BufferUtils'); -goog.require('shaka.util.Iterables'); - /** * @summary A set of BufferSource utility functions. @@ -45,7 +43,7 @@ shaka.util.BufferUtils = class { const uint8A = shaka.util.BufferUtils.toUint8(arr1); const uint8B = shaka.util.BufferUtils.toUint8(arr2); - for (const i of shaka.util.Iterables.range(arr1.byteLength)) { + for (let i = 0; i < arr1.byteLength; i++) { if (uint8A[i] != uint8B[i]) { return false; } diff --git a/lib/util/ebml_parser.js b/lib/util/ebml_parser.js index 5475532259..d9184c64d6 100644 --- a/lib/util/ebml_parser.js +++ b/lib/util/ebml_parser.js @@ -11,7 +11,6 @@ goog.require('goog.asserts'); goog.require('shaka.util.BufferUtils'); goog.require('shaka.util.DataViewReader'); goog.require('shaka.util.Error'); -goog.require('shaka.util.Iterables'); /** @@ -157,7 +156,8 @@ shaka.util.EbmlParser = class { } let value = 0; - for (const {item, i} of shaka.util.Iterables.enumerate(vint)) { + for (let i = 0; i < vint.length; i++) { + const item = vint[i]; if (i == 0) { // Mask out the first few bits of |vint|'s first byte to get the most // significant bits of |vint|'s value. If |vint| is 8 bytes wide then @@ -267,7 +267,7 @@ shaka.util.EbmlElement = class { let value = 0; - for (const i of shaka.util.Iterables.range(this.dataView_.byteLength)) { + for (let i = 0; i < this.dataView_.byteLength; i++) { const chunk = this.dataView_.getUint8(i); value = (256 * value) + chunk; } diff --git a/lib/util/iterables.js b/lib/util/iterables.js index 706434dff6..77f2812548 100644 --- a/lib/util/iterables.js +++ b/lib/util/iterables.js @@ -75,50 +75,4 @@ shaka.util.Iterables = class { } return out; } - - /** - * Returns an iterable that contains numbers in the range [0, end). - * - * @param {number} end The exclusive end of the list. - * @return {!Iterable.} - */ - static* range(end) { - for (let i = 0; i < end; i++) { - yield i; - } - } - - /** - * Iterates over an iterable object and includes additional info about each - * item: - * - The zero-based index of the element. - * - The next item in the list, if it exists. - * - The previous item in the list, if it exists. - * - * @param {!Iterable.} iterable - * @return {!Iterable.< - * {i: number, item: T, prev: (T|undefined), next: (T|undefined)}>} - * @template T - */ - static* enumerate(iterable) { - // Since we want the "next" item, we need to skip the first item and return - // elements one in the past. So as we iterate, we are getting the "next" - // element and yielding the one from the previous iteration. - let i = -1; - let prev = undefined; - let item = undefined; - for (const next of iterable) { - if (i >= 0) { - yield {i, item, prev, next}; - } - i++; - prev = item; - item = next; - } - if (i != -1) { - // If it's still -1, there were no items. Otherwise we need to yield - // the last item. - yield {i, prev, item, next: undefined}; - } - } }; diff --git a/lib/util/mp4_box_parsers.js b/lib/util/mp4_box_parsers.js index 6479ba01f1..a9a6bfac48 100644 --- a/lib/util/mp4_box_parsers.js +++ b/lib/util/mp4_box_parsers.js @@ -7,8 +7,6 @@ goog.provide('shaka.util.Mp4BoxParsers'); goog.require('shaka.util.DataViewReader'); -goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); shaka.util.Mp4BoxParsers = class { /** @@ -125,8 +123,7 @@ shaka.util.Mp4BoxParsers = class { reader.skip(4); } - for (const _ of shaka.util.Iterables.range(sampleCount)) { - shaka.util.Functional.ignored(_); + for (let i = 0; i < sampleCount; i++) { /** @type {shaka.util.ParsedTRUNSample} */ const sample = { sampleDuration: null, diff --git a/lib/util/mp4_parser.js b/lib/util/mp4_parser.js index 8a0475c791..7d0ebf0818 100644 --- a/lib/util/mp4_parser.js +++ b/lib/util/mp4_parser.js @@ -9,8 +9,6 @@ goog.provide('shaka.util.Mp4Parser'); goog.require('goog.asserts'); goog.require('shaka.log'); goog.require('shaka.util.DataViewReader'); -goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); /** @@ -229,8 +227,7 @@ shaka.util.Mp4Parser = class { // start position. The header size varies. const headerSize = shaka.util.Mp4Parser.headerSize(box); const count = box.reader.readUint32(); - for (const _ of shaka.util.Iterables.range(count)) { - shaka.util.Functional.ignored(_); + for (let i = 0; i < count; i++) { box.parser.parseNext(box.start + headerSize, box.reader, box.partialOkay); if (box.parser.done_) { break; diff --git a/lib/util/periods.js b/lib/util/periods.js index ac1a9bee41..9f41b98162 100644 --- a/lib/util/periods.js +++ b/lib/util/periods.js @@ -14,7 +14,6 @@ goog.require('shaka.media.SegmentIndex'); goog.require('shaka.util.ArrayUtils'); goog.require('shaka.util.Error'); goog.require('shaka.util.IReleasable'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.LanguageUtils'); goog.require('shaka.util.ManifestParserUtils'); goog.require('shaka.util.MapUtils'); @@ -98,7 +97,6 @@ shaka.util.PeriodCombiner = class { */ async combinePeriods(periods, isDynamic) { const ContentType = shaka.util.ManifestParserUtils.ContentType; - const Iterables = shaka.util.Iterables; shaka.util.PeriodCombiner.filterOutAudioStreamDuplicates_(periods); shaka.util.PeriodCombiner.filterOutVideoStreamDuplicates_(periods); @@ -118,7 +116,8 @@ shaka.util.PeriodCombiner = class { // Find the first period we haven't seen before. Tag all the periods we // see now as "used". let firstNewPeriodIndex = -1; - for (const {i, item: period} of Iterables.enumerate(periods)) { + for (let i = 0; i < periods.length; i++) { + const period = periods[i]; if (this.usedPeriodIds_.has(period.id)) { // This isn't new. } else { @@ -511,13 +510,12 @@ shaka.util.PeriodCombiner = class { static async combine_( outputStreams, streamsPerPeriod, firstNewPeriodIndex, clone, concat) { const ContentType = shaka.util.ManifestParserUtils.ContentType; - const Iterables = shaka.util.Iterables; const unusedStreamsPerPeriod = []; - for (const {i, item: streams} of Iterables.enumerate(streamsPerPeriod)) { + for (let i = 0; i < streamsPerPeriod.length; i++) { if (i >= firstNewPeriodIndex) { // This periods streams are all new. - unusedStreamsPerPeriod.push(new Set(streams)); + unusedStreamsPerPeriod.push(new Set(streamsPerPeriod[i])); } else { // This period's streams have all been used already. unusedStreamsPerPeriod.push(new Set()); @@ -669,12 +667,12 @@ shaka.util.PeriodCombiner = class { // Concatenate the new matches onto the stream, starting at the first new // period. - const Iterables = shaka.util.Iterables; // Satisfy the compiler about the type. // Also checks if the segmentIndex is still valid after the async // operations, to make sure we stop if the active stream has changed. if (outputStream.segmentIndex instanceof shaka.media.MetaSegmentIndex) { - for (const {i, item: match} of Iterables.enumerate(streams)) { + for (let i = 0; i < streams.length; i++) { + const match = streams[i]; if (match.segmentIndex && i >= firstNewPeriodIndex) { goog.asserts.assert(match.segmentIndex, 'stream should have a segmentIndex.'); @@ -769,9 +767,9 @@ shaka.util.PeriodCombiner = class { // Concatenate the new matches onto the stream, starting at the first new // period. - const Iterables = shaka.util.Iterables; - for (const {i, item: match} of Iterables.enumerate(matches)) { + for (let i = 0; i < matches.length; i++) { if (i >= firstNewPeriodIndex) { + const match = matches[i]; concat(outputStream, match); // We only consider an audio stream "used" if its language is related to diff --git a/lib/util/pssh.js b/lib/util/pssh.js index e967fa93db..0f829fb09d 100644 --- a/lib/util/pssh.js +++ b/lib/util/pssh.js @@ -9,8 +9,6 @@ goog.provide('shaka.util.Pssh'); goog.require('goog.asserts'); goog.require('shaka.log'); goog.require('shaka.util.BufferUtils'); -goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.Mp4Parser'); goog.require('shaka.util.Uint8ArrayUtils'); @@ -83,8 +81,7 @@ shaka.util.Pssh = class { shaka.util.Uint8ArrayUtils.toHex(box.reader.readBytes(16))); if (box.version > 0) { const numKeyIds = box.reader.readUint32(); - for (const _ of shaka.util.Iterables.range(numKeyIds)) { - shaka.util.Functional.ignored(_); + for (let i = 0; i < numKeyIds; i++) { const keyId = shaka.util.Uint8ArrayUtils.toHex(box.reader.readBytes(16)); this.cencKeyIds.push(keyId); diff --git a/lib/util/string_utils.js b/lib/util/string_utils.js index 76f9f834ee..895fd08358 100644 --- a/lib/util/string_utils.js +++ b/lib/util/string_utils.js @@ -10,7 +10,6 @@ goog.require('goog.asserts'); goog.require('shaka.log'); goog.require('shaka.util.BufferUtils'); goog.require('shaka.util.Error'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.Lazy'); @@ -81,7 +80,7 @@ shaka.util.StringUtils = class { const length = Math.floor(data.byteLength / 2); const arr = new Uint16Array(length); const dataView = shaka.util.BufferUtils.toDataView(data); - for (const i of shaka.util.Iterables.range(length)) { + for (let i = 0; i < length; i++) { arr[i] = dataView.getUint16(i * 2, littleEndian); } return shaka.util.StringUtils.fromCharCode(arr); diff --git a/lib/util/uint8array_utils.js b/lib/util/uint8array_utils.js index 0ddcdd1a43..b0b8c02061 100644 --- a/lib/util/uint8array_utils.js +++ b/lib/util/uint8array_utils.js @@ -8,7 +8,6 @@ goog.provide('shaka.util.Uint8ArrayUtils'); goog.require('shaka.Deprecate'); goog.require('shaka.util.BufferUtils'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.StringUtils'); @@ -90,7 +89,7 @@ shaka.util.Uint8ArrayUtils = class { static fromHex(str) { const size = str.length / 2; const arr = new Uint8Array(size); - for (const i of shaka.util.Iterables.range(size)) { + for (let i = 0; i < size; i++) { arr[i] = window.parseInt(str.substr(i * 2, 2), 16); } return arr; diff --git a/test/cast/cast_receiver_integration.js b/test/cast/cast_receiver_integration.js index f7eeb53b31..d1512e2de8 100644 --- a/test/cast/cast_receiver_integration.js +++ b/test/cast/cast_receiver_integration.js @@ -15,8 +15,6 @@ goog.require('shaka.net.NetworkingEngine'); goog.require('shaka.test.TestScheme'); goog.require('shaka.test.UiUtils'); goog.require('shaka.util.EventManager'); -goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.Platform'); goog.require('shaka.util.PublicPromise'); @@ -198,8 +196,7 @@ filterDescribe('CastReceiver', castReceiverIntegrationSupport, () => { // the average length is expected to be lower than the length of the first // update message. let totalLength = 0; - for (const _ of shaka.util.Iterables.range(50)) { - shaka.util.Functional.ignored(_); + for (let i = 0; i < 50; i++) { // eslint-disable-next-line no-await-in-loop const message = await waitForUpdateMessage(); totalLength += message.length; diff --git a/test/dash/dash_parser_content_protection_unit.js b/test/dash/dash_parser_content_protection_unit.js index 093512f74b..8e004ef267 100644 --- a/test/dash/dash_parser_content_protection_unit.js +++ b/test/dash/dash_parser_content_protection_unit.js @@ -9,7 +9,6 @@ goog.require('shaka.dash.DashParser'); goog.require('shaka.test.Dash'); goog.require('shaka.test.FakeNetworkingEngine'); goog.require('shaka.util.Error'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.PlayerConfiguration'); goog.require('shaka.util.Uint8ArrayUtils'); @@ -142,7 +141,7 @@ describe('DashParser ContentProtection', () => { const variants = []; const numVariants = 2; - for (const i of shaka.util.Iterables.range(numVariants)) { + for (let i = 0; i < numVariants; i++) { const variant = jasmine.objectContaining({ video: jasmine.objectContaining({ keyIds: new Set(keyIds[i] ? [keyIds[i]] : []), diff --git a/test/dash/mpd_utils_unit.js b/test/dash/mpd_utils_unit.js index 06536294a8..fc00cf1be9 100644 --- a/test/dash/mpd_utils_unit.js +++ b/test/dash/mpd_utils_unit.js @@ -9,7 +9,6 @@ goog.require('shaka.net.NetworkingEngine'); goog.require('shaka.test.FakeNetworkingEngine'); goog.require('shaka.test.Util'); goog.require('shaka.util.Error'); -goog.require('shaka.util.Iterables'); goog.requireType('shaka.util.PublicPromise'); describe('MpdUtils', () => { @@ -536,7 +535,7 @@ describe('MpdUtils', () => { ''); // Create a large but finite number of links, so this won't // infinitely recurse if there isn't a depth limit. - for (const i of shaka.util.Iterables.range(20)) { + for (let i = 0; i < 20; i++) { const key = 'https://xlink' + i; const value = makeRecursiveXMLString(0, 'https://xlink' + (i + 1)); @@ -659,7 +658,7 @@ describe('MpdUtils', () => { ''); // Create a few links. This is few enough that it would succeed if we // didn't abort it. - for (const i of shaka.util.Iterables.range(4)) { + for (let i = 0; i < 4; i++) { const key = 'https://xlink' + i; const value = makeRecursiveXMLString(0, 'https://xlink' + (i + 1)); diff --git a/test/hls/hls_live_unit.js b/test/hls/hls_live_unit.js index a9ee408d66..97e80a406a 100644 --- a/test/hls/hls_live_unit.js +++ b/test/hls/hls_live_unit.js @@ -9,8 +9,6 @@ goog.require('shaka.net.NetworkingEngine'); goog.require('shaka.test.FakeNetworkingEngine'); goog.require('shaka.test.ManifestParser'); goog.require('shaka.test.Util'); -goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.PlayerConfiguration'); goog.require('shaka.util.Uint8ArrayUtils'); goog.requireType('shaka.util.PublicPromise'); @@ -394,8 +392,8 @@ describe('HlsParser live', () => { '#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n', '#EXT-X-MEDIA-SEQUENCE:0\n', ].join(''); - for (const _ of shaka.util.Iterables.range(1000)) { - shaka.util.Functional.ignored(_); + + for (let i = 0; i < 1000; i++) { mediaWithManySegments += '#EXTINF:2,\n'; mediaWithManySegments += 'main.mp4\n'; } diff --git a/test/media/buffering_observer_unit.js b/test/media/buffering_observer_unit.js index 40188320bb..21f7b37c77 100644 --- a/test/media/buffering_observer_unit.js +++ b/test/media/buffering_observer_unit.js @@ -5,7 +5,6 @@ */ goog.require('shaka.media.BufferingObserver'); -goog.require('shaka.util.Iterables'); describe('BufferingObserver', () => { const BufferingObserver = shaka.media.BufferingObserver; @@ -115,7 +114,7 @@ describe('BufferingObserver', () => { /** @type {boolean} */ let changed; - for (const lead of shaka.util.Iterables.range(5)) { + for (let lead = 0; lead < 5; lead++) { changed = controller.update(lead, /* toEnd= */ false); expect(changed).toBeFalsy(); } diff --git a/test/media/streaming_engine_unit.js b/test/media/streaming_engine_unit.js index 713f765bab..55e7dac165 100644 --- a/test/media/streaming_engine_unit.js +++ b/test/media/streaming_engine_unit.js @@ -18,7 +18,6 @@ goog.require('shaka.test.StreamingEngineUtil'); goog.require('shaka.test.Util'); goog.require('shaka.util.AbortableOperation'); goog.require('shaka.util.Error'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.ManifestParserUtils'); goog.require('shaka.util.MimeUtils'); goog.require('shaka.util.PlayerConfiguration'); @@ -284,7 +283,7 @@ describe('StreamingEngine', () => { }; const segmentsInFirstPeriod = 12; - for (const i of shaka.util.Iterables.range(segmentsInFirstPeriod)) { + for (let i = 0; i < segmentsInFirstPeriod; i++) { segmentData[ContentType.AUDIO].segments.push( makeBuffer(segmentSizes[ContentType.AUDIO])); segmentData[ContentType.VIDEO].segments.push( @@ -298,7 +297,7 @@ describe('StreamingEngine', () => { } const segmentsInSecondPeriod = 2; - for (const i of shaka.util.Iterables.range(segmentsInSecondPeriod)) { + for (let i = 0; i < segmentsInSecondPeriod; i++) { segmentData[ContentType.AUDIO].segments.push( makeBuffer(segmentSizes[ContentType.AUDIO])); segmentData[ContentType.VIDEO].segments.push( @@ -652,7 +651,7 @@ describe('StreamingEngine', () => { // should be buffered. Those segment numbers are 1-based, and this array // is 0-based, so we expect i >= 9 to be downloaded. const segments = mediaSourceEngine.segments; - for (const i of shaka.util.Iterables.range(14)) { + for (let i = 0; i < 14; i++) { expect(segments[ContentType.AUDIO][i]).withContext(i).toBe(i >= 9); expect(segments[ContentType.VIDEO][i]).withContext(i).toBe(i >= 9); expect(segments[ContentType.TEXT][i]).withContext(i).toBe(i >= 9); @@ -1801,7 +1800,7 @@ describe('StreamingEngine', () => { // Since we performed an unbuffered seek into the second Period, the // first 12 segments should not be buffered. - for (const i of shaka.util.Iterables.range(14)) { + for (let i = 0; i < 14; i++) { expect(mediaSourceEngine.segments[ContentType.AUDIO][i]).toBe(i >= 12); expect(mediaSourceEngine.segments[ContentType.VIDEO][i]).toBe(i >= 12); expect(mediaSourceEngine.segments[ContentType.TEXT][i]).toBe(i >= 12); @@ -2603,7 +2602,7 @@ describe('StreamingEngine', () => { // should be buffered. Those segment numbers are 1-based, and this array // is 0-based, so we expect i >= 9 to be downloaded. const segments = mediaSourceEngine.segments; - for (const i of shaka.util.Iterables.range(14)) { + for (let i = 0; i < 14; i++) { expect(segments[ContentType.AUDIO][i]).withContext(i).toBe(i >= 9); expect(segments[ContentType.VIDEO][i]).withContext(i).toBe(i >= 9); expect(segments[ContentType.TEXT][i]).withContext(i).toBe(i >= 9); diff --git a/test/player_integration.js b/test/player_integration.js index 33254fd77b..fa9bba8939 100644 --- a/test/player_integration.js +++ b/test/player_integration.js @@ -17,8 +17,6 @@ goog.require('shaka.test.UiUtils'); goog.require('shaka.test.Util'); goog.require('shaka.test.Waiter'); goog.require('shaka.util.EventManager'); -goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); describe('Player', () => { /** @type {!jasmine.Spy} */ @@ -931,8 +929,7 @@ describe('Player', () => { } async function waitUntilBuffered(amount) { - for (const _ of shaka.util.Iterables.range(25)) { - shaka.util.Functional.ignored(_); + for (let i = 0; i < 25; i++) { // We buffer from an internal segment, so this shouldn't take long to // buffer. await Util.delay(0.1); // eslint-disable-line no-await-in-loop diff --git a/test/player_unit.js b/test/player_unit.js index 2375e010db..805b47e7fc 100644 --- a/test/player_unit.js +++ b/test/player_unit.js @@ -24,7 +24,6 @@ goog.require('shaka.test.ManifestGenerator'); goog.require('shaka.test.Util'); goog.require('shaka.util.ConfigUtils'); goog.require('shaka.util.Error'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.ManifestParserUtils'); goog.requireType('shaka.media.Playhead'); @@ -2177,8 +2176,8 @@ describe('Player', () => { async function runTest(languages, preference, expectedIndex) { // A manifest we can use to test language selection. manifest = shaka.test.ManifestGenerator.generate((manifest) => { - const enumerate = (it) => shaka.util.Iterables.enumerate(it); - for (const {i, item: lang} of enumerate(languages)) { + for (let i = 0; i < languages.length; i++) { + const lang = languages[i]; if (lang.charAt(0) == '*') { manifest.addVariant(i, (variant) => { variant.primary = true; diff --git a/test/test/util/indexeddb_utils.js b/test/test/util/indexeddb_utils.js index 33d5fdd909..b2d60c498e 100644 --- a/test/test/util/indexeddb_utils.js +++ b/test/test/util/indexeddb_utils.js @@ -7,8 +7,6 @@ goog.provide('shaka.test.IndexedDBUtils'); goog.require('shaka.test.Util'); -goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.PublicPromise'); @@ -41,8 +39,7 @@ shaka.test.IndexedDBUtils = class { // connection after 5 attempts (with delays in between), just give // up. let lastError; - for (const _ of shaka.util.Iterables.range(5)) { - shaka.util.Functional.ignored(_); + for (let i = 0; i < 5; i++) { try { return await tryOpen(); // eslint-disable-line no-await-in-loop } catch (e) { // eslint-disable-line no-restricted-syntax diff --git a/test/test/util/manifest_generator.js b/test/test/util/manifest_generator.js index 4906842ac4..f505786dcb 100644 --- a/test/test/util/manifest_generator.js +++ b/test/test/util/manifest_generator.js @@ -8,7 +8,6 @@ goog.provide('shaka.test.ManifestGenerator'); goog.require('goog.asserts'); goog.require('shaka.test.Util'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.ManifestParserUtils'); goog.require('shaka.util.Uint8ArrayUtils'); goog.requireType('shaka.media.InitSegmentReference'); @@ -621,7 +620,7 @@ shaka.test.ManifestGenerator.Stream = class { const segmentCount = totalDuration / segmentDuration; const references = []; - for (const index of shaka.util.Iterables.range(segmentCount)) { + for (let index = 0; index < segmentCount; index++) { const getUris = () => [sprintf(template, index)]; const start = index * segmentDuration; const end = Math.min(totalDuration, (index + 1) * segmentDuration); diff --git a/test/test/util/util.js b/test/test/util/util.js index 1586d1303c..47c4c5876b 100644 --- a/test/test/util/util.js +++ b/test/test/util/util.js @@ -10,8 +10,6 @@ goog.provide('shaka.test.Util'); goog.require('goog.asserts'); goog.require('shaka.media.InitSegmentReference'); goog.require('shaka.media.SegmentReference'); -goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); goog.require('shaka.util.StringUtils'); goog.require('shaka.util.XmlUtils'); goog.requireType('shaka.util.Error'); @@ -52,10 +50,9 @@ shaka.test.Util = class { */ static async fakeEventLoop(duration, onTick) { // Run this synchronously: - for (const time of shaka.util.Iterables.range(duration)) { + for (let time = 0; time < duration; time++) { // We shouldn't need more than 6 rounds. - for (const _ of shaka.util.Iterables.range(6)) { - shaka.util.Functional.ignored(_); + for (let i = 0; i < 6; i++) { jasmine.clock().tick(0); await Promise.resolve(); // eslint-disable-line no-await-in-loop } @@ -203,7 +200,7 @@ shaka.test.Util = class { if (actual.childNodes.length != expected.childNodes.length) { return prospectiveDiff + 'Different child node list length.'; } - for (const i of shaka.util.Iterables.range(actual.childNodes.length)) { + for (let i = 0; i < actual.childNodes.length; i++) { const aNode = actual.childNodes[i]; const eNode = expected.childNodes[i]; const diff = diff --git a/test/ui/ui_unit.js b/test/ui/ui_unit.js index d05de14c13..1bf150f06e 100644 --- a/test/ui/ui_unit.js +++ b/test/ui/ui_unit.js @@ -12,8 +12,7 @@ goog.require('shaka.test.UiUtils'); goog.require('shaka.test.Util'); goog.require('shaka.ui.OverflowMenu'); goog.require('shaka.ui.ResolutionSelection'); -goog.require('shaka.util.Functional'); -goog.require('shaka.util.Iterables'); +goog.require('shaka.util.Platform'); goog.require('shaka.util.Platform'); goog.requireType('shaka.Player'); goog.requireType('shaka.ui.Controls'); @@ -137,8 +136,7 @@ describe('UI', () => { // Four is just a random number I (ismena) came up with to test a // multi-video use case. It could be replaces with any other // (reasonable) number. - for (const _ of shaka.util.Iterables.range(4)) { - shaka.util.Functional.ignored(_); + for (let i = 0; i < 4; i++) { const video = /** @type {!HTMLVideoElement} */ (document.createElement('video')); diff --git a/test/util/iterables_unit.js b/test/util/iterables_unit.js index b4096cbced..5907f5a747 100644 --- a/test/util/iterables_unit.js +++ b/test/util/iterables_unit.js @@ -67,66 +67,4 @@ describe('Iterables', () => { expect(Iterables.filter(input, (x) => x < 0)).toEqual([]); }); }); - - describe('enumerate', () => { - function enumerate(it) { - return Array.from(Iterables.enumerate(it)); - } - - it('works with no items', () => { - expect(enumerate([])).toEqual([]); - }); - - it('works with one item', () => { - expect(enumerate([999])) - .toEqual([{i: 0, item: 999, prev: undefined, next: undefined}]); - }); - - it('works with special values', () => { - expect(enumerate([[]])) - .toEqual([{i: 0, item: [], prev: undefined, next: undefined}]); - expect(enumerate([0])) - .toEqual([{i: 0, item: 0, prev: undefined, next: undefined}]); - expect(enumerate([null])) - .toEqual([{i: 0, item: null, prev: undefined, next: undefined}]); - expect(enumerate([undefined])) - .toEqual([{i: 0, item: undefined, prev: undefined, next: undefined}]); - }); - - it('works with two items', () => { - expect(enumerate([888, 999])) - .toEqual([ - {i: 0, item: 888, prev: undefined, next: 999}, - {i: 1, item: 999, prev: 888, next: undefined}, - ]); - }); - - it('works with three items', () => { - expect(enumerate([777, 888, 999])) - .toEqual([ - {i: 0, item: 777, prev: undefined, next: 888}, - {i: 1, item: 888, prev: 777, next: 999}, - {i: 2, item: 999, prev: 888, next: undefined}, - ]); - }); - - it('keeps references', () => { - const expected = [ - {a: 'x'}, - {b: 'y'}, - {c: 'z'}, - ]; - const actual = enumerate(expected); - - expect(actual[0].item).toBe(expected[0]); - expect(actual[0].next).toBe(expected[1]); - - expect(actual[1].prev).toBe(expected[0]); - expect(actual[1].item).toBe(expected[1]); - expect(actual[1].next).toBe(expected[2]); - - expect(actual[2].prev).toBe(expected[1]); - expect(actual[2].item).toBe(expected[2]); - }); - }); });