@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
166 lines (128 loc) • 3.9 kB
JavaScript
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;