UNPKG

@thewtex/vtk.js-esm

Version:

Visualization Toolkit for the Web

359 lines (286 loc) 11.8 kB
import _defineProperty from '@babel/runtime/helpers/defineProperty'; import { event, get, newInstance as newInstance$1, chain, newTypedArray, traverseInstanceTree } from '../../macro.js'; import Base64 from '../../Common/Core/Base64.js'; import vtkRenderWindow from '../Core/RenderWindow.js'; import vtkObjectManager from './SynchronizableRenderWindow/vtkObjectManager.js'; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var SYNCHRONIZER_CONTEXTS = {}; // ---------------------------------------------------------------------------- // Static methods // ---------------------------------------------------------------------------- function createArrayHandler() { var dataArrayCache = {}; var arrayFetcher = null; function setFetchArrayFunction(fetcher) { arrayFetcher = fetcher; } function getArray(sha, dataType, context) { var arrayEntry = dataArrayCache[sha]; if (arrayEntry) { arrayEntry.mtimes[context.getActiveViewId()] = context.getMTime(); return new Promise(function (resolve, reject) { resolve(arrayEntry.array); }); } if (!arrayFetcher) { return Promise.reject(new Error('No array fetcher found, please use "setArrayFetcher" to provide one')); } return new Promise(function (resolve, reject) { arrayFetcher(sha).then(function (data) { var buffer = data; if (typeof data === 'string') { buffer = Base64.toArrayBuffer(data); } if (buffer instanceof Blob) { var fileReader = new FileReader(); fileReader.onload = function () { var array = newTypedArray(dataType, fileReader.result); var mtimes = _defineProperty({}, context.getActiveViewId(), context.getMTime()); dataArrayCache[sha] = { mtimes: mtimes, array: array }; resolve(array); }; fileReader.readAsArrayBuffer(buffer); } else { var array = newTypedArray(dataType, buffer); var mtimes = _defineProperty({}, context.getActiveViewId(), context.getMTime()); dataArrayCache[sha] = { mtimes: mtimes, array: array }; resolve(array); } }, function (error) { console.log('Error getting data array:'); console.log(error); reject(error); }); }); } function emptyCachedArrays() { Object.keys(dataArrayCache).forEach(function (key) { delete dataArrayCache[key]; }); } function freeOldArrays(threshold, context) { var mtimeThreshold = context.getMTime() - threshold; Object.keys(dataArrayCache).filter(function (key) { return dataArrayCache[key].mtimes[context.getActiveViewId()]; }).filter(function (key) { return dataArrayCache[key].mtimes[context.getActiveViewId()] < mtimeThreshold; }).forEach(function (key) { delete dataArrayCache[key]; }); } return { setFetchArrayFunction: setFetchArrayFunction, getArray: getArray, emptyCachedArrays: emptyCachedArrays, freeOldArrays: freeOldArrays }; } // ---------------------------------------------------------------------------- function createInstanceMap() { var instances = {}; function getInstance(id) { return instances[id]; } function getInstanceId(instance) { var instanceId = null; Object.keys(instances).forEach(function (id) { if (instance === instances[id]) { instanceId = id; } }); return instanceId; } function registerInstance(id, instance) { instances[id] = instance; } function unregisterInstance(id) { delete instances[id]; } function emptyCachedInstances() { Object.keys(instances).forEach(function (key) { delete instances[key]; }); } return { getInstance: getInstance, getInstanceId: getInstanceId, registerInstance: registerInstance, unregisterInstance: unregisterInstance, emptyCachedInstances: emptyCachedInstances }; } // ---------------------------------------------------------------------------- function createProgressHandler() { var readyCount = 0; var publicAPI = { start: function start() { readyCount += 1; publicAPI.invokeProgressEvent(readyCount); }, end: function end() { readyCount -= 1; publicAPI.invokeProgressEvent(readyCount); if (readyCount === 0) { publicAPI.invokeProgressDone(); } }, resetProgress: function resetProgress() { readyCount = 0; } }; var model = {}; event(publicAPI, model, 'progressEvent'); event(publicAPI, model, 'progressDone'); return publicAPI; } // ---------------------------------------------------------------------------- function createSceneMtimeHandler() { var mtimes = {}; var activeViewId = 'default'; function getMTime(viewId) { var key = viewId || activeViewId; return mtimes[key] || 1; } function incrementMTime(viewId) { var key = viewId || activeViewId; if (!mtimes[key]) { mtimes[key] = 1; } mtimes[key] += 1; } function setActiveViewId(viewId) { activeViewId = viewId; } function getActiveViewId() { return activeViewId; } return { getMTime: getMTime, incrementMTime: incrementMTime, setActiveViewId: setActiveViewId, getActiveViewId: getActiveViewId }; } // ---------------------------------------------------------------------------- function getSynchronizerContext() { var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'default'; var ctx = SYNCHRONIZER_CONTEXTS[name]; if (!ctx) { ctx = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, createArrayHandler()), createInstanceMap()), createProgressHandler()), createSceneMtimeHandler()); SYNCHRONIZER_CONTEXTS[name] = ctx; } return ctx; } // ---------------------------------------------------------------------------- function setSynchronizerContext(name, ctx) { SYNCHRONIZER_CONTEXTS[name] = ctx; } // ---------------------------------------------------------------------------- function createSyncFunction(renderWindow, synchronizerContext) { var lastMtime = -1; var gcThreshold = 100; var getManagedInstanceId = function getManagedInstanceId(instance) { return instance.get('managedInstanceId').managedInstanceId; }; var getManagedInstanceIds = function getManagedInstanceIds() { return traverseInstanceTree(renderWindow, getManagedInstanceId); }; function clearOneTimeUpdaters() { vtkObjectManager.clearOneTimeUpdaters(getManagedInstanceIds()); } function setSynchronizedViewId(synchronizedViewId) { renderWindow.set({ synchronizedViewId: synchronizedViewId }, true, true); } function getSynchronizedViewId() { return renderWindow.get('synchronizedViewId').synchronizedViewId; } function updateGarbageCollectorThreshold(v) { gcThreshold = v; } function synchronize(state) { if (!getSynchronizedViewId()) { setSynchronizedViewId(state.id); } var mtime = state.mtime || 0; if (getSynchronizedViewId() === state.id && lastMtime < mtime) { return new Promise(function (resolve, reject) { var subscription = synchronizerContext.onProgressDone(function () { subscription.unsubscribe(); renderWindow.render(); resolve(true); }); lastMtime = mtime; synchronizerContext.setActiveViewId(state.id); synchronizerContext.incrementMTime(); vtkObjectManager.updateRenderWindow(renderWindow, state, synchronizerContext); synchronizerContext.freeOldArrays(gcThreshold, synchronizerContext); }); } return Promise.resolve(false); } return { synchronize: synchronize, setSynchronizedViewId: setSynchronizedViewId, getSynchronizedViewId: getSynchronizedViewId, updateGarbageCollectorThreshold: updateGarbageCollectorThreshold, getManagedInstanceIds: getManagedInstanceIds, clearOneTimeUpdaters: clearOneTimeUpdaters }; } // ---------------------------------------------------------------------------- // vtkSynchronizableRenderWindow methods // ---------------------------------------------------------------------------- function vtkSynchronizableRenderWindow(publicAPI, model) { // Set our className model.classHierarchy.push('vtkSynchronizableRenderWindow'); if (!model.synchronizerContext) { model.synchronizerContext = getSynchronizerContext(model.synchronizerContextName); } var addOn = createSyncFunction(publicAPI, model.synchronizerContext); Object.keys(addOn).forEach(function (methodName) { if (publicAPI[methodName]) { publicAPI[methodName] = chain(publicAPI[methodName], addOn[methodName]); } else { publicAPI[methodName] = addOn[methodName]; } }); } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- var DEFAULT_VALUES = { synchronizerContextName: 'default', synchronizerContext: null, synchronizedViewId: null }; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; Object.assign(model, DEFAULT_VALUES, initialValues); // Build VTK API vtkRenderWindow.extend(publicAPI, model); get(publicAPI, model, ['synchronizerContext']); // Object methods vtkSynchronizableRenderWindow(publicAPI, model); } // ---------------------------------------------------------------------------- var newInstance = newInstance$1(extend, 'vtkSynchronizableRenderWindow'); // ---------------------------------------------------------------------------- // More Static methods // ---------------------------------------------------------------------------- function decorate(renderWindow) { var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'default'; var addOn = createSyncFunction(renderWindow, getSynchronizerContext(name)); return _objectSpread(_objectSpread(_objectSpread({}, addOn), renderWindow), {}, { delete: chain(renderWindow.delete, addOn.delete) }); } // ---------------------------------------------------------------------------- var vtkSynchronizableRenderWindow$1 = { newInstance: newInstance, extend: extend, getSynchronizerContext: getSynchronizerContext, setSynchronizerContext: setSynchronizerContext, decorate: decorate, createInstanceMap: createInstanceMap, createArrayHandler: createArrayHandler, createProgressHandler: createProgressHandler, createSceneMtimeHandler: createSceneMtimeHandler, vtkObjectManager: vtkObjectManager }; export default vtkSynchronizableRenderWindow$1; export { DEFAULT_VALUES, extend, newInstance };