Mercurial > hg > ugly-duckling
changeset 72:cb91d7e40068
Add a couple of methods to the worker for adding remote library repos (well, key value pairs of library keys and URIs to fetch the library from) - and one for actually importing the libraries (currently using RequireJS (<script> / importScripts(...) method tying into global AMD module registration) ). Also updated list method to concatenate the available outputs from all loaded libraries.
author | Lucas Thompson <dev@lucas.im> |
---|---|
date | Wed, 18 Jan 2017 10:18:10 +0000 |
parents | 0980eb001bde |
children | d3abd81e8ab6 |
files | src/app/services/feature-extraction/FeatureExtractionWorker.ts |
diffstat | 1 files changed, 82 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/app/services/feature-extraction/FeatureExtractionWorker.ts Wed Jan 18 10:14:05 2017 +0000 +++ b/src/app/services/feature-extraction/FeatureExtractionWorker.ts Wed Jan 18 10:18:10 2017 +0000 @@ -2,27 +2,49 @@ * Created by lucas on 01/12/2016. */ -import { EmscriptenProxy } from 'piper'; -import { PiperSimpleClient } from 'piper/HigherLevelUtilities'; +import {EmscriptenProxy, ListRequest, ListResponse} from 'piper'; +import { + PiperSimpleClient, SimpleRequest, + SimpleResponse +} from 'piper/HigherLevelUtilities'; import { VampExamplePlugins } from 'piper/ext/VampExamplePluginsModule'; +import {AvailableLibraries} from "./feature-extraction.service"; // TODO TypeScript has a .d.ts file for webworkers, but for some reason it clashes with the typings for dom and causes compiler errors interface WorkerGlobalScope { onmessage: (this: this, ev: MessageEvent) => any; postMessage(data: any): void; + importScripts(uri: string): void; } interface MessageEvent { readonly data: any; } +type LibraryUri = string; +type LibraryKey = string; + +interface Message { + method: string; + params: any; +} + +type RequireJs = (libs: string[], callback: (...libs: any[]) => void) => void; + export default class FeatureExtractionWorker { private workerScope: WorkerGlobalScope; - private piperClient: PiperSimpleClient; + private clients: Map<string, PiperSimpleClient>; + private remoteLibraries: Map<LibraryKey, LibraryUri>; - constructor(workerScope: WorkerGlobalScope) { + constructor(workerScope: WorkerGlobalScope, private requireJs: RequireJs) { this.workerScope = workerScope; - this.piperClient = new PiperSimpleClient(new EmscriptenProxy(VampExamplePlugins())); + this.clients = new Map<LibraryKey, PiperSimpleClient>(); + this.remoteLibraries = new Map<LibraryKey, LibraryUri>(); + this.clients.set( + 'vamp-example-plugins', + new PiperSimpleClient(new EmscriptenProxy(VampExamplePlugins())) + ); + this.workerScope.onmessage = (ev: MessageEvent) => { const sendResponse = (result) => { this.workerScope.postMessage({ @@ -32,15 +54,67 @@ }; switch (ev.data.method) { case 'list': - this.piperClient.list({}).then(sendResponse); + this.list(ev.data.params) + .then(sendResponse) + .catch(err => console.error(err)); // TODO handle error break; case 'process': - this.piperClient.process(ev.data.params).then(sendResponse); + this.process(ev.data.params) + .then(sendResponse) + .catch(err => console.error(err)); // TODO handle error break; case 'collect': - this.piperClient.collect(ev.data.params).then(sendResponse).catch(err => console.error(err)); + this.collect(ev.data.params) + .then(sendResponse) + .catch(err => console.error(err)); // TODO handle error + break; + case 'import': + // this.workerScope.importScripts(ev.data.params); + const key: LibraryKey = ev.data.params; + if (this.remoteLibraries.has(key)) { + this.requireJs([this.remoteLibraries.get(key)], (plugin) => { + this.clients.set( + key, + new PiperSimpleClient(new EmscriptenProxy(plugin.createLibrary())) + ); // TODO won't always be an emscripten module + this.list({}).then(sendResponse); + }); + } else { + console.error('Non registered library key.'); // TODO handle error + } + break; + case 'addRemoteLibraries': // TODO rename + const available: AvailableLibraries = ev.data.params; + Object.keys(available).forEach(key => { + this.remoteLibraries.set(key, available[key]); + }); } }; } + private list(request: ListRequest): Promise<ListResponse> { + // TODO actually pay attention to ListRequest + return Promise.all([...this.clients.values()].map(client => client.list({}))) + .then(allAvailable => { + return { + available: allAvailable.reduce( + (all, current) => all.concat(current.available), + [] + ) + }; + }); + } + + // TODO reduce dupe + private process(request: SimpleRequest): Promise<SimpleResponse> { + const key: LibraryKey = request.key.split(':')[0]; + const client: PiperSimpleClient = this.clients.get(key); + return client ? client.process(request) : Promise.reject("Invalid plugin library key."); + } + + private collect(request: SimpleRequest): Promise<SimpleResponse> { + const key: LibraryKey = request.key.split(':')[0]; + const client: PiperSimpleClient = this.clients.get(key); + return client ? client.collect(request) : Promise.reject("Invalid plugin library key."); + } }