import Monologue from 'monologue.js'; import MouseHandler from 'paraviewweb/src/Interaction/Core/MouseHandler'; import VtkWebMouseListener from 'paraviewweb/src/Interaction/Core/VtkWebMouseListener'; import SizeHelper from 'paraviewweb/src/Common/Misc/SizeHelper';
const IMAGE_READY_TOPIC = 'image-ready'; const IMAGE_LOADED_TOPIC = 'image-loaded';
export default class RemoteRenderer { constructor(pvwClient, container = null, id = -1, statRenderer = null) { this.client = pvwClient; this.setQuality(); this.stats = { renderCount: 0, staleRenderCount: 0, deltaT: [], roundTrip: [], workTime: [], }; this.lastError = null; this.quality = 100; this.renderPending = false; this.renderCount = 0; this.staleRenderCount = 0;
this.statContainer = document.createElement('div'); this.statContainer.setAttribute( 'style', 'position: absolute; top: 0; right: 0; bottom: 0; left: 0;' ); this.statRenderer = statRenderer; this.showStats = false;
this.canvas = document.createElement('canvas');
this.imageDecoder = new Image(); this.imageDecoder.addEventListener('load', () => { this.canvas.setAttribute('width', this.imageDecoder.width); this.canvas.setAttribute('height', this.imageDecoder.height); const ctx = this.canvas.getContext('2d'); ctx.drawImage(this.imageDecoder, 0, 0); this.emit(IMAGE_LOADED_TOPIC, this); });
this.container = null; this.options = { view: id, size: [400, 400], mtime: 0, quality: 100, localTime: 0, };
this.renderOnIdle = (force = false) => { if (this.__timeout === null) { this.__timeout = setTimeout(() => { if (!this.render(force)) { this.renderOnIdle(force); } }, 250); } };
this.mouseListener = new VtkWebMouseListener(pvwClient, 100, 100, id); this.mouseListener.setInteractionDoneCallback((interact) => { this.quality = interact ? this.interactiveQuality : this.stillQuality; if (!this.render(!interact)) { this.renderOnIdle(!interact); } });
this.setContainer(container); }
setQuality(interactive = 50, still = 100) { this.stillQuality = still; this.interactiveQuality = interactive; }
setView(id) { this.options.view = id; }
setContainer(container = null) { if (this.container && this.container !== container) { this.container.removeChild(this.canvas); this.mouseHandler.destroy();
this.container = null; this.mouseHandler = null; this.size = null;
if (this.statRenderer) { this.statRenderer.setContainer(null); } }
if (container && this.container !== container) { this.container = container; this.mouseHandler = new MouseHandler(container); this.mouseHandler.attach(this.mouseListener.getListeners()); this.container.appendChild(this.canvas);
this.size = SizeHelper.getSize(container);
if (this.statRenderer) { this.container.appendChild(this.statContainer); this.statRenderer.setContainer(this.statContainer); }
this.render(true); } }
pushStats(serverResponse) { const localTime = +new Date(); this.stats.workTime.push(serverResponse.workTime); this.stats.roundTrip.push( localTime - serverResponse.localTime - serverResponse.workTime ); this.stats.deltaT.push(localTime - serverResponse.localTime);
[this.stats.workTime, this.stats.roundTrip, this.stats.deltaT].forEach( (list) => { while (list.length > 100) { list.shift(); } } ); }
render(force = false) { if (this.size && this.size.clientWidth === 0) { return true; }
if (this.renderPending) { this.renderOnIdle(force); return false; }
if (this.__timeout !== null) { clearTimeout(this.__timeout); this.__timeout = null; }
if (this.client && this.size && this.container) { this.renderPending = true; this.stats.renderCount += 1;
this.options.size[0] = this.size.clientWidth; this.options.size[1] = this.size.clientHeight; this.options.quality = this.quality; this.options.localTime = +new Date(); this.options.clearCache = !!force; if (force) { this.options.mtime = 0; } this.mouseListener.updateSize(this.options.size[0], this.options.size[1]);
this.client.ViewPortImageDelivery.stillRender(this.options).then( (resp) => { this.renderPending = false;
this.pushStats(resp);
this.options.mtime = resp.mtime; this.view = resp.global_id;
if (resp.image) { this.imageDecoder.src = `data:image/${resp.format},${resp.image}`; }
if (resp.stale) { this.stats.staleRenderCount += 1; this.renderOnIdle(false); } else { this.emit(IMAGE_READY_TOPIC, this); }
if (this.statRenderer) { this.statRenderer.updateData(this.stats, this.showStats); this.statRenderer.render(); } }, (err) => { this.renderPending = false; this.lastError = err; } ); return true; } return false; }
showRenderStats(show) { this.showStats = show; }
resize() { if (this.container) { this.size = SizeHelper.getSize(this.container); this.render(true); if (this.statRenderer) { this.statRenderer.resize(); } } }
onImageReady(callback) { return this.on(IMAGE_READY_TOPIC, callback); }
onImageLoaded(callback) { return this.on(IMAGE_LOADED_TOPIC, callback); }
destroy() { this.off(); this.setContainer(null); if (this.mouseListener) { this.mouseListener.destroy(); this.mouseListener = null; } this.client = null; this.imageDecoder = null; this.canvas = null; if (this.statRenderer) { this.statRenderer.destroy(); this.statRenderer = null; } } }
Monologue.mixInto(RemoteRenderer);
|