import {Stats} from "./stats.js"; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } const KB = 1024; const MB = 1024 * KB; const GB = 1024 * MB; function formatTime(t) { let value; let unit; let precision; if (t < 1) { value = t * 1e3; unit = "\u03BCs"; precision = 0; } else if (t < 1e3) { value = t; unit = "ms"; precision = 2; } else { value = t / 1e3; unit = "s"; precision = 2; } return "".concat(value.toFixed(precision)).concat(unit); } function formatMemory(b) { let value; let unit; let precision; if (b < KB) { value = b; unit = " bytes"; precision = 0; } else if (b < MB) { value = b / KB; unit = "kB"; precision = 2; } else if (b < GB) { value = b / MB; unit = "MB"; precision = 2; } else { value = b / GB; unit = "GB"; precision = 2; } return "".concat(value.toFixed(precision)).concat(unit); } const RIGHT_ARROW = "\u25B6"; const DOWN_ARROW = "\u2B07"; const DEFAULT_CSS = { css: { position: "fixed", zIndex: 1e4, color: "#ccc", background: "#000", fontFamily: "Helvetica,Arial,sans-serif", padding: "8px", fontSize: "12px", lineSpacing: 6 }, headerCSS: { fontSize: "16px", cursor: "pointer" }, itemCSS: { paddingLeft: "8px" } }; const DEFAULT_FORMATTERS = { count: (stat) => "".concat(stat.name, ": ").concat(stat.count), averageTime: (stat) => "".concat(stat.name, ": ").concat(formatTime(stat.getAverageTime())), totalTime: (stat) => "".concat(stat.name, ": ").concat(formatTime(stat.time)), fps: (stat) => "".concat(stat.name, ": ").concat(Math.round(stat.getHz()), "fps"), memory: (stat) => "".concat(stat.name, ": ").concat(formatMemory(stat.count)) }; class StatsWidget { constructor(stats2, options) { _defineProperty(this, "stats", void 0); _defineProperty(this, "title", void 0); _defineProperty(this, "collapsed", false); _defineProperty(this, "_framesPerUpdate", void 0); _defineProperty(this, "_formatters", DEFAULT_FORMATTERS); _defineProperty(this, "_css", void 0); _defineProperty(this, "_headerCSS", void 0); _defineProperty(this, "_itemCSS", void 0); _defineProperty(this, "_container", null); _defineProperty(this, "_innerContainer", null); _defineProperty(this, "_statsContainer", null); _defineProperty(this, "_header", null); _defineProperty(this, "_resetOnUpdate", {}); _defineProperty(this, "_counter", 0); _defineProperty(this, "_items", {}); _defineProperty(this, "_added", false); this.stats = stats2; this.title = options === null || options === void 0 ? void 0 : options.title; this._framesPerUpdate = Math.round(Math.max((options === null || options === void 0 ? void 0 : options.framesPerUpdate) || 1, 1)); this._initializeFormatters(options); this._initializeUpdateConfigs(options); this._css = Object.assign({}, DEFAULT_CSS.css, options === null || options === void 0 ? void 0 : options.css); this._headerCSS = Object.assign({}, DEFAULT_CSS.headerCSS, this._css.header); this._itemCSS = Object.assign({}, DEFAULT_CSS.itemCSS, this._css.item); delete this._css.header; delete this._css.item; this._createDOM(options === null || options === void 0 ? void 0 : options.container); this._createDOMStats(); } setStats(stats2) { this.stats = stats2; this._createDOMStats(); this._setHeaderContent(); this.update(); } update() { const stats2 = this.stats && this.stats.stats; if (!stats2 || Object.keys(stats2).length === 0) { return; } if (this._counter++ % this._framesPerUpdate !== 0) { return; } this._update(); } remove() { this._container.removeChild(this._innerContainer); } setCollapsed(collapsed) { this.collapsed = collapsed; if (this._statsContainer) { this._statsContainer.style.display = this.collapsed ? "none" : "block"; } this._setHeaderContent(); } _update() { this.stats.forEach((stat) => { this._createDOMItem(stat.name); this._items[stat.name].innerHTML = this._getLines(stat).join("
"); if (this._resetOnUpdate[stat.name]) { stat.reset(); } }); } _initializeFormatters(options) { if (options !== null && options !== void 0 && options.formatters) { for (const name in options.formatters) { let formatter = options.formatters[name]; if (typeof formatter === "string") { formatter = DEFAULT_FORMATTERS[formatter]; } this._formatters[name] = formatter; } } } _initializeUpdateConfigs(options) { if (options !== null && options !== void 0 && options.resetOnUpdate) { for (const name in options.resetOnUpdate) { this._resetOnUpdate[name] = options.resetOnUpdate[name]; } } } _createDOM(container) { if (typeof document === "undefined" || !document) { return; } this._container = container; if (!this._container) { this._container = document.createElement("div"); for (const name in this._css) { this._container.style[name] = this._css[name]; } document.body.appendChild(this._container); } this._innerContainer = document.createElement("div"); this._container.appendChild(this._innerContainer); this._createDOMHeader(); this._statsContainer = document.createElement("div"); this._statsContainer.style.display = "block"; this._innerContainer.appendChild(this._statsContainer); } _createDOMHeader() { if (!this._header) { this._header = document.createElement("div"); for (const name in this._headerCSS) { this._header.style[name] = this._headerCSS[name]; } this._header.onclick = this._toggleCollapsed.bind(this); this._innerContainer.appendChild(this._header); } this._setHeaderContent(); } _setHeaderContent() { if (this._header) { const collapsedState = this.collapsed ? RIGHT_ARROW : DOWN_ARROW; const title = this.title || this.stats && this.stats.id || "Stats"; this._header.innerText = "".concat(collapsedState, " ").concat(title); } } _toggleCollapsed() { this.setCollapsed(!this.collapsed); } _createDOMStats() { if (this.stats instanceof Stats) { this.stats.forEach((stat) => { this._createDOMItem(stat.name); }); } } _createDOMItem(statName) { if (!this._statsContainer) { return; } if (this._items[statName]) { return; } this._items[statName] = document.createElement("div"); for (const name in this._itemCSS) { this._items[statName].style[name] = this._itemCSS[name]; } this._statsContainer.appendChild(this._items[statName]); } _getLines(stat) { const formatter = this._formatters[stat.name] || this._formatters[stat.type] || DEFAULT_FORMATTERS.count; return formatter(this.stats.get(stat.name)).split("\n"); } } export default StatsWidget; export {StatsWidget};