dev@40: /** dev@40: * Created by lucas on 01/12/2016. dev@40: */ dev@40: dev@88: import {PiperVampService, ListRequest, ListResponse} from 'piper'; dev@72: import { dev@226: SimpleRequest dev@72: } from 'piper/HigherLevelUtilities'; dev@44: import { VampExamplePlugins } from 'piper/ext/VampExamplePluginsModule'; dev@72: import {AvailableLibraries} from "./feature-extraction.service"; dev@226: import { dev@226: DedicatedWorkerGlobalScope, dev@226: WebWorkerStreamingServer dev@226: } from "piper/servers/WebWorkerStreamingServer"; dev@226: import { dev@226: PiperStreamingService, dev@226: StreamingResponse, dev@226: StreamingService dev@226: } from "piper/StreamingService"; dev@226: import {Observable} from "rxjs/Observable"; dev@44: dev@40: dev@40: interface MessageEvent { dev@40: readonly data: any; dev@40: } dev@40: dev@72: type LibraryUri = string; dev@72: type LibraryKey = string; dev@72: dev@72: type RequireJs = (libs: string[], callback: (...libs: any[]) => void) => void; dev@72: dev@226: class AggregateStreamingService implements StreamingService { dev@226: private services: Map; dev@226: dev@226: constructor() { dev@226: this.services = new Map(); dev@226: this.services.set( dev@226: 'vamp-example-plugins', dev@226: new PiperStreamingService(new PiperVampService(VampExamplePlugins())) dev@226: ); dev@226: } dev@226: dev@226: addService(key: LibraryKey, service: PiperStreamingService): void { dev@226: this.services.set(key, service); dev@226: } dev@226: dev@226: list(request: ListRequest): Promise { dev@226: return Promise.all( dev@226: [...this.services.values()].map(client => client.list({})) dev@226: ).then(allAvailable => ({ dev@226: available: allAvailable.reduce( dev@226: (all, current) => all.concat(current.available), dev@226: [] dev@226: ) dev@226: }) dev@226: ); dev@226: } dev@226: dev@226: process(request: SimpleRequest): Observable { dev@226: return undefined; dev@226: } dev@226: dev@226: collect(request: SimpleRequest): Observable { dev@226: const key = request.key.split(':')[0]; dev@226: return this.services.has(key) ? dev@226: this.services.get(key).collect(request) : Observable.throw("Invalid key"); dev@226: } dev@226: } dev@226: dev@40: export default class FeatureExtractionWorker { dev@226: private workerScope: DedicatedWorkerGlobalScope; dev@226: private services: Map; dev@72: private remoteLibraries: Map; dev@226: private server: WebWorkerStreamingServer; dev@226: private service: AggregateStreamingService; dev@40: dev@226: constructor(workerScope: DedicatedWorkerGlobalScope, dev@226: private requireJs: RequireJs) { dev@40: this.workerScope = workerScope; dev@226: this.services = new Map(); dev@72: this.remoteLibraries = new Map(); dev@226: this.service = new AggregateStreamingService(); dev@226: this.setupImportLibraryListener(); dev@226: this.server = new WebWorkerStreamingServer( dev@226: this.workerScope, dev@226: this.service dev@72: ); dev@226: } dev@72: dev@226: private setupImportLibraryListener(): void { dev@44: this.workerScope.onmessage = (ev: MessageEvent) => { dev@64: const sendResponse = (result) => { dev@64: this.workerScope.postMessage({ dev@64: method: ev.data.method, dev@64: result: result dev@64: }); dev@64: }; dev@44: switch (ev.data.method) { dev@72: case 'import': dev@72: const key: LibraryKey = ev.data.params; dev@72: if (this.remoteLibraries.has(key)) { dev@72: this.requireJs([this.remoteLibraries.get(key)], (plugin) => { dev@226: this.services.set( dev@72: key, dev@226: new PiperStreamingService( dev@226: new PiperVampService(plugin.createLibrary()) dev@226: ) dev@72: ); // TODO won't always be an emscripten module dev@226: this.service.addService(key, this.services.get(key)); dev@226: this.service.list({}).then(sendResponse); dev@72: }); dev@72: } else { dev@72: console.error('Non registered library key.'); // TODO handle error dev@72: } dev@72: break; dev@72: case 'addRemoteLibraries': // TODO rename dev@72: const available: AvailableLibraries = ev.data.params; dev@72: Object.keys(available).forEach(key => { dev@72: this.remoteLibraries.set(key, available[key]); dev@72: }); dev@44: } dev@44: }; dev@40: } dev@40: }