diff --git a/examples/jsm/loaders/TaskManager.d.ts b/examples/jsm/loaders/TaskManager.d.ts new file mode 100644 index 00000000000000..228030ef316c80 --- /dev/null +++ b/examples/jsm/loaders/TaskManager.d.ts @@ -0,0 +1,86 @@ +export class TaskManager { + constructor(maxParallelExecutions?: number); + taskTypes: Map; + verbose: boolean; + maxParallelExecutions: number; + actualExecutionCount: number; + storedExecutions: StoredExecution[]; + setVerbose(verbose: boolean): TaskManager; + setMaxParallelExecutions(maxParallelExecutions: number): TaskManager; + getMaxParallelExecutions(): number; + supportsTaskType(taskType: string): boolean; + registerTaskType(taskType: string, initFunction: Function, executeFunction: Function, comRoutingFunction: Function, fallback: boolean, dependencyUrls?: string[]): TaskManager; + registerTaskTypeModule(taskType: string, workerModuleUrl: string): TaskManager; + initTaskType(taskType: string, config: object, transferables?: Transferable[]): Promise; + enqueueForExecution(taskType: string, config: object, transferables?: Transferable[]): Promise; + _kickExecutions(): void; + dispose(): TaskManager; +} +declare class WorkerTypeDefinition { + constructor(taskType: string, maximumCount: number, fallback: boolean, verbose?: boolean); + taskType: string; + fallback: boolean; + verbose: boolean; + functions: { + init: { + ref: Function; + code: string; + }; + execute: { + ref: Function; + code: string; + }; + comRouting: { + ref: Function; + code: string; + }; + dependencies: { + urls: URL[]; + code: string[]; + }; + workerModuleUrl: URL; + }; + workers: { + code: string[]; + instances: TaskWorker[] | MockedTaskWorker[]; + available: TaskWorker[] | MockedTaskWorker[]; + }; + getTaskType(): string; + setFunctions(initFunction: Function, executeFunction: Function, comRoutingFunction?: Function): void; + setDependencyUrls(dependencyUrls: string[]): void; + setWorkerModule(workerModuleUrl: string): void; + isWorkerModule(): boolean; + loadDependencies(): Promise; + generateWorkerCode(dependencies: ArrayBuffer[]): Promise; + createWorkers(code: string): Promise; + createWorkerModules(): Promise; + initWorkers(instances: TaskWorker[] | MockedTaskWorker[], config: object, transferables: Transferable[]): Promise; + getAvailableTask(): TaskWorker | MockedTaskWorker | undefined; + hasTask(): boolean; + returnAvailableTask(taskWorker: TaskWorker | MockedTaskWorker): void; + dispose(): void; +} +declare class StoredExecution { + constructor(taskType: string, config: object, resolve: Function, reject: Function, transferables?: Transferable[]); + taskType: string; + config: any; + resolve: Function; + reject: Function; + transferables: Transferable[]; +} +declare class TaskWorker extends Worker { + constructor(id: number, aURL: string, options?: object); + id: number; + getId(): number; +} +declare class MockedTaskWorker { + constructor(id: number, initFunction: Function, executeFunction: Function); + id: number; + functions: { + init: Function; + execute: Function; + }; + getId(): number; + postMessage(message: string, transfer?: Transferable[]): void; +} +export {}; diff --git a/examples/jsm/loaders/TaskManager.js b/examples/jsm/loaders/TaskManager.js index 5c608eb7920380..f626ed173dbeee 100644 --- a/examples/jsm/loaders/TaskManager.js +++ b/examples/jsm/loaders/TaskManager.js @@ -18,11 +18,17 @@ class TaskManager { */ constructor ( maxParallelExecutions ) { + /** + * @type {Map} + */ this.taskTypes = new Map(); this.verbose = false; this.maxParallelExecutions = maxParallelExecutions ? maxParallelExecutions : 4; this.actualExecutionCount = 0; - this.storedPromises = []; + /** + * @type {StoredExecution[]} + */ + this.storedExecutions = []; } @@ -150,30 +156,22 @@ class TaskManager { let localPromise = new Promise( ( resolveUser, rejectUser ) => { - this.storedPromises.push( { - taskType: taskType, - config: config, - transferables: transferables, - resolve: resolveUser, - reject: rejectUser - } ); - - } ) + this.storedExecutions.push( new StoredExecution( taskType, config, resolveUser, rejectUser, transferables ) ); + } ); this._kickExecutions(); - return localPromise; } _kickExecutions () { - while ( this.actualExecutionCount < this.maxParallelExecutions && this.storedPromises.length > 0 ) { + while ( this.actualExecutionCount < this.maxParallelExecutions && this.storedExecutions.length > 0 ) { - let storedExec = this.storedPromises.shift(); - if ( storedExec ) { + let storedExecution = this.storedExecutions.shift(); + if ( storedExecution ) { - let workerTypeDefinition = this.taskTypes.get( storedExec.taskType ); + let workerTypeDefinition = this.taskTypes.get( storedExecution.taskType ); if ( workerTypeDefinition.hasTask() ) { let taskWorker = workerTypeDefinition.getAvailableTask(); @@ -186,20 +184,20 @@ class TaskManager { taskWorker.postMessage( { cmd: "execute", id: taskWorker.getId(), - config: storedExec.config - }, storedExec.transferables ); + config: storedExecution.config + }, storedExecution.transferables ); } ); promiseWorker.then( ( e ) => { workerTypeDefinition.returnAvailableTask( taskWorker ); - storedExec.resolve( e.data ); + storedExecution.resolve( e.data ); this.actualExecutionCount --; this._kickExecutions(); } ).catch( ( e ) => { - storedExec.reject( "Execution error: " + e ); + storedExecution.reject( "Execution error: " + e ); } ); @@ -207,7 +205,7 @@ class TaskManager { else { // try later again, add at the end for now - this.storedPromises.push( storedExec ); + this.storedExecutions.push( storedExecution ); } @@ -241,13 +239,10 @@ class WorkerTypeDefinition { /** * Creates a new instance of {@link WorkerTypeDefinition}. * - * @param {string} type The name of the registered task type. + * @param {string} taskType The name of the registered task type. * @param {Number} maximumCount Maximum worker count * @param {boolean} fallback Set to true if execution should be performed in main * @param {boolean} [verbose] Set if logging should be verbose - */ - /** - */ constructor ( taskType, maximumCount, fallback, verbose ) { this.taskType = taskType; @@ -255,19 +250,27 @@ class WorkerTypeDefinition { this.verbose = verbose === true; this.functions = { init: { + /** @type {function} */ ref: null, + /** @type {string} */ code: null }, execute: { + /** @type {function} */ ref: null, + /** @type {string} */ code: null }, comRouting: { + /** @type {function} */ ref: null, + /** @type {string} */ code: null }, dependencies: { + /** @type {URL[]} */ urls: [], + /** @type {string[]} */ code: [] }, /** @@ -278,8 +281,11 @@ class WorkerTypeDefinition { this.workers = { + /** @type {string[]} */ code: [], + /** @type {TaskWorker[]|MockedTaskWorker[]} */ instances: new Array ( maximumCount ), + /** @type {TaskWorker[]|MockedTaskWorker[]} */ available: [] }; @@ -383,6 +389,7 @@ class WorkerTypeDefinition { } /** + * Uses the configured values for init, execute and comRouting and embeds it in necessary glue code. * * @param {ArrayBuffer[]} dependencies * @return {Promise} @@ -406,6 +413,7 @@ class WorkerTypeDefinition { } /** + * Creates workers based on the configured function and dependency strings. * * @param {string} code * @return {Promise} @@ -440,6 +448,7 @@ class WorkerTypeDefinition { } /** + * Creates module workers. * * @return {Promise} */ @@ -456,6 +465,7 @@ class WorkerTypeDefinition { } /** + * Initialises all workers with common configuration data. * * @param {TaskWorker[]|MockedTaskWorker[]} instances * @param {object} config @@ -533,6 +543,32 @@ class WorkerTypeDefinition { } +/** + * Contains all things required for later executions of Worker. + */ +class StoredExecution { + + /** + * Creates a new instance. + * + * @param {string} taskType + * @param {object} config + * @param {Function} resolve + * @param {Function} reject + * @param {Transferable[]} [transferables] + */ + constructor( taskType, config, resolve, reject, transferables ) { + + this.taskType = taskType; + this.config = config; + this.resolve = resolve; + this.reject = reject; + this.transferables = transferables; + + } + +} + /** * Extends the {@link Worker} with an id. */ @@ -553,8 +589,8 @@ class TaskWorker extends Worker { } /** - * - * @return {*} + * Returns the id. + * @return {number} */ getId() { @@ -588,8 +624,8 @@ class MockedTaskWorker { } /** - * - * @return {*} + * Returns the id. + * @return {number} */ getId() { @@ -599,9 +635,10 @@ class MockedTaskWorker { /** * Delegates the message to the registered functions - * @param message + * @param {String} message + * @param {Transferable[]} [transfer] */ - postMessage( message ) { + postMessage( message, transfer ) { let scope = this; let comRouting = function ( message ) { @@ -627,6 +664,11 @@ class MockedTaskWorker { } + /** + * Mocking termination + */ + terminate () {} + } diff --git a/examples/jsm/loaders/obj2/utils/ResourceDescriptor.d.ts b/examples/jsm/loaders/obj2/utils/ResourceDescriptor.d.ts new file mode 100644 index 00000000000000..c5068a97bc5456 --- /dev/null +++ b/examples/jsm/loaders/obj2/utils/ResourceDescriptor.d.ts @@ -0,0 +1,21 @@ +export class ResourceDescriptor { + constructor(url: string); + url: URL; + path: string; + filename: string; + extension: string; + buffer: ArrayBuffer; + needStringOutput: boolean; + compressed: boolean; + getUrl(): URL; + getPath(): string; + getFilename(): string; + getExtension(): null | string; + setNeedStringOutput(needStringOutput: boolean): ResourceDescriptor; + isNeedStringOutput(): boolean; + setCompressed(compressed: boolean): ResourceDescriptor; + isCompressed(): boolean; + setBuffer(buffer: ArrayBuffer): ResourceDescriptor; + getBuffer(): ArrayBuffer; + getBufferAsString(): string; +} diff --git a/examples/jsm/loaders/obj2/utils/ResourceDescriptor.js b/examples/jsm/loaders/obj2/utils/ResourceDescriptor.js index 8695fc325ebb0e..0f27de33b0f98e 100644 --- a/examples/jsm/loaders/obj2/utils/ResourceDescriptor.js +++ b/examples/jsm/loaders/obj2/utils/ResourceDescriptor.js @@ -34,6 +34,7 @@ class ResourceDescriptor { let filenameParts = this.filename.split( '.' ); if ( filenameParts.length > 1 ) this.extension = filenameParts[ filenameParts.length - 1 ]; + /** @type {ArrayBuffer} */ this.buffer = null; this.needStringOutput = false; this.compressed = false; diff --git a/examples/jsm/loaders/obj2/utils/TransferableUtils.d.ts b/examples/jsm/loaders/obj2/utils/TransferableUtils.d.ts new file mode 100644 index 00000000000000..6b00520f43878a --- /dev/null +++ b/examples/jsm/loaders/obj2/utils/TransferableUtils.d.ts @@ -0,0 +1,46 @@ +export class TransferableUtils { + static walkMesh(rootNode: Object3D, callback: Function): void; + static packageBufferGeometry(bufferGeometry: BufferGeometry, meshName: string, geometryType: number, materialNames?: string[]): MeshMessageStructure; +} +export class MeshMessageStructure { + static cloneMessageStructure(input: object | MeshMessageStructure): MeshMessageStructure; + static copyTypedArray(arrayIn: ArrayBuffer, arrayOut: ArrayBuffer): void; + constructor(cmd: string, meshName: string); + main: { + cmd: string; + type: string; + meshName: string; + progress: { + numericalValue: number; + }; + params: { + geometryType: number; + }; + materials: { + multiMaterial: boolean; + materialNames: string[]; + materialGroups: object[]; + }; + buffers: { + vertices: ArrayBuffer; + indices: ArrayBuffer; + colors: ArrayBuffer; + normals: ArrayBuffer; + uvs: ArrayBuffer; + skinIndex: ArrayBuffer; + skinWeight: ArrayBuffer; + }; + }; + transferables: { + vertex: ArrayBuffer[]; + index: ArrayBuffer[]; + color: ArrayBuffer[]; + normal: ArrayBuffer[]; + uv: ArrayBuffer[]; + skinIndex: ArrayBuffer[]; + skinWeight: ArrayBuffer[]; + }; + postMessage(postMessageImpl: object): void; +} +import { Object3D } from "../../../../../build/three.module.js"; +import { BufferGeometry } from "../../../../../build/three.module.js"; diff --git a/examples/jsm/loaders/obj2/utils/TransferableUtils.js b/examples/jsm/loaders/obj2/utils/TransferableUtils.js index b6f4b0b5da9c6f..aa69000da1fc1c 100644 --- a/examples/jsm/loaders/obj2/utils/TransferableUtils.js +++ b/examples/jsm/loaders/obj2/utils/TransferableUtils.js @@ -4,7 +4,8 @@ */ import { - BufferGeometry + BufferGeometry, + Object3D } from "../../../../../build/three.module.js"; /** @@ -32,26 +33,42 @@ class MeshMessageStructure { }, materials: { multiMaterial: false, + /** @type {string[]} */ materialNames: [], + /** @type {object[]} */ materialGroups: [] }, buffers: { + /** @type {ArrayBuffer} */ vertices: null, + /** @type {ArrayBuffer} */ indices: null, + /** @type {ArrayBuffer} */ colors: null, + /** @type {ArrayBuffer} */ normals: null, + /** @type {ArrayBuffer} */ uvs: null, + /** @type {ArrayBuffer} */ skinIndex: null, + /** @type {ArrayBuffer} */ skinWeight: null } }; this.transferables = { + /** @type {ArrayBuffer[]} */ vertex: null, + /** @type {ArrayBuffer[]} */ index: null, + /** @type {ArrayBuffer[]} */ color: null, + /** @type {ArrayBuffer[]} */ normal: null, + /** @type {ArrayBuffer[]} */ uv: null, + /** @type {ArrayBuffer[]} */ skinIndex: null, + /** @type {ArrayBuffer[]} */ skinWeight: null }; @@ -167,7 +184,7 @@ class TransferableUtils { * Walk a mesh and on ever geometry call the callback function. * * @param {Object3D} rootNode - * @param {function} callback + * @param {Function} callback */ static walkMesh( rootNode, callback ) { let scope = this;