UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

166 lines (128 loc) 3.9 kB
import { Cache } from "../../../core/cache/Cache.js"; import { KeyValuePair } from "../../../core/collection/KeyValuePair.js"; import { noop } from "../../../core/function/noop.js"; import { invokeObjectEquals } from "../../../core/model/object/invokeObjectEquals.js"; import { invokeObjectHash } from "../../../core/model/object/invokeObjectHash.js"; import { ObjectPoolFactory } from "../../../core/model/object/ObjectPoolFactory.js"; import { HTMLElementCacheKey } from "../../common/HTMLElementCacheKey.js"; import View from "../../View.js"; /** * * @type {Cache<HTMLElementCacheKey, HTMLElement[]>} */ const cache = new Cache({ maxWeight: 100, keyHashFunction: invokeObjectHash, keyEqualityFunction: invokeObjectEquals }); /** * * @type {ObjectPoolFactory<HTMLElementCacheKey>} */ const pool = new ObjectPoolFactory( () => new HTMLElementCacheKey(), noop, key => { key.reset(); } ); /** * * @param {HTMLElementCacheKey} key * @return {HTMLElement} */ function obtainElement(key) { const elements = cache.get(key); if (elements !== null) { // console.log('Re-using image from cache', key.toJSON()); let element; if (elements.length === 1) { element = elements[0]; cache.remove(key); } else { element = elements.pop(); } return element; } else { return key.createElement(); } } export class VideoView extends View { /** * * @param {String|ObservedString} url * @param {String[]} classList * @param {*} [attributes] */ constructor(url, { classList = [], attributes = {} } = {}) { super(); /** * @type {string} */ let src; if (typeof url === "string") { src = url; } else if (typeof url === "object" && typeof url.getValue === "function") { src = url.getValue(); if (url.onChanged !== undefined) { this.bindSignal(url.onChanged, this.__setSource, this); } } const cacheKey = pool.create(); cacheKey.tag = "video"; cacheKey.attributes = [ new KeyValuePair('src', src), new KeyValuePair('class', classList.join(' ')) ]; for (const attributesKey in attributes) { const attributeValue = String(attributes[attributesKey]); const attribute = new KeyValuePair(attributesKey, attributeValue); cacheKey.attributes.push(attribute); } cacheKey.update(); this.el = obtainElement(cacheKey); pool.release(cacheKey); const classListSize = classList.length; for (let i = 0; i < classListSize; i++) { const c = classList[i]; this.addClass(c); } this.size.onChanged.add(this.__setSize, this); } destroy() { super.destroy(); const key = pool.create(); key.initializeFromElement(this.el); let elements = cache.get(key); if (elements === null) { elements = [this.el]; cache.put(key, elements); } else if (elements.length < 100) { elements.push(this.el); pool.release(key); } } /** * * @param {number} x * @param {number} y * @private */ __setSize(x, y) { this.el.setAttribute('width', x); this.el.setAttribute('height', y); } /** * * @param {string} url * @private */ __setSource(url) { this.el.setAttribute('src', url); } } /** * @readonly * @type {boolean} */ VideoView.prototype.isVideoView = true;