Compare commits
	
		
			3 Commits
		
	
	
		
			conductor-
			...
			open1337
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 9d9d1b1de2 | ||
|   | 311e221af5 | ||
|   | 6281b67e47 | 
| @@ -92,7 +92,10 @@ define([ | ||||
|                     "features": "creation", | ||||
|                     "model": { | ||||
|                         "telemetry": { | ||||
|                             "period": 10 | ||||
|                             "period": 10, | ||||
|                             "amplitude": 1, | ||||
|                             "offset": 0, | ||||
|                             "dataRateInHz": 1 | ||||
|                         } | ||||
|                     }, | ||||
|                     "telemetry": { | ||||
| @@ -135,6 +138,42 @@ define([ | ||||
|                                 "period" | ||||
|                             ], | ||||
|                             "pattern": "^\\d*(\\.\\d*)?$" | ||||
|                         }, | ||||
|                         { | ||||
|                             "name": "Amplitude", | ||||
|                             "control": "textfield", | ||||
|                             "cssclass": "l-input-sm l-numeric", | ||||
|                             "key": "amplitude", | ||||
|                             "required": true, | ||||
|                             "property": [ | ||||
|                                 "telemetry", | ||||
|                                 "amplitude" | ||||
|                             ], | ||||
|                             "pattern": "^\\d*(\\.\\d*)?$" | ||||
|                         }, | ||||
|                         { | ||||
|                             "name": "Offset", | ||||
|                             "control": "textfield", | ||||
|                             "cssclass": "l-input-sm l-numeric", | ||||
|                             "key": "offset", | ||||
|                             "required": true, | ||||
|                             "property": [ | ||||
|                                 "telemetry", | ||||
|                                 "offset" | ||||
|                             ], | ||||
|                             "pattern": "^\\d*(\\.\\d*)?$" | ||||
|                         }, | ||||
|                         { | ||||
|                             "name": "Data Rate (hz)", | ||||
|                             "control": "textfield", | ||||
|                             "cssclass": "l-input-sm l-numeric", | ||||
|                             "key": "dataRateInHz", | ||||
|                             "required": true, | ||||
|                             "property": [ | ||||
|                                 "telemetry", | ||||
|                                 "dataRateInHz" | ||||
|                             ], | ||||
|                             "pattern": "^\\d*(\\.\\d*)?$" | ||||
|                         } | ||||
|                     ] | ||||
|                 } | ||||
|   | ||||
							
								
								
									
										83
									
								
								example/generator/src/GeneratorProvider.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								example/generator/src/GeneratorProvider.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     './WorkerInterface' | ||||
| ], function ( | ||||
|     WorkerInterface | ||||
| ) { | ||||
|  | ||||
|     var REQUEST_DEFAULTS = { | ||||
|         amplitude: 1, | ||||
|         period: 10, | ||||
|         offset: 0, | ||||
|         dataRateInHz: 1 | ||||
|     }; | ||||
|  | ||||
|     function GeneratorProvider() { | ||||
|         this.workerInterface = new WorkerInterface(); | ||||
|     } | ||||
|  | ||||
|     GeneratorProvider.prototype.canProvideTelemetry = function (domainObject) { | ||||
|         return domainObject.type === 'generator'; | ||||
|     }; | ||||
|  | ||||
|     GeneratorProvider.prototype.makeWorkerRequest = function (domainObject, request) { | ||||
|         var props = [ | ||||
|             'amplitude', | ||||
|             'period', | ||||
|             'offset', | ||||
|             'dataRateInHz' | ||||
|         ]; | ||||
|  | ||||
|         var workerRequest = {}; | ||||
|  | ||||
|         props.forEach(function (prop) { | ||||
|             if (domainObject.telemetry && domainObject.telemetry.hasOwnProperty(prop)) { | ||||
|                 workerRequest[prop] = domainObject.telemetry[prop]; | ||||
|             } | ||||
|             if (request.hasOwnProperty(prop)) { | ||||
|                 workerRequest[prop] = request[prop]; | ||||
|             } | ||||
|             if (!workerRequest[prop]) { | ||||
|                 workerRequest[prop] = REQUEST_DEFAULTS[prop]; | ||||
|             } | ||||
|             workerRequest[prop] = Number(workerRequest[prop]); | ||||
|         }); | ||||
|  | ||||
|         return workerRequest; | ||||
|     }; | ||||
|  | ||||
|     GeneratorProvider.prototype.request = function (domainObject, request) { | ||||
|         var workerRequest = this.makeWorkerRequest(domainObject, request); | ||||
|         workerRequest.start = request.start; | ||||
|         workerRequest.end = request.end; | ||||
|         return this.workerInterface.request(workerRequest); | ||||
|     }; | ||||
|  | ||||
|     GeneratorProvider.prototype.subscribe = function (domainObject, callback, request) { | ||||
|         var workerRequest = this.makeWorkerRequest(domainObject, request); | ||||
|         return this.workerInterface.subscribe(workerRequest, callback); | ||||
|     }; | ||||
|  | ||||
|     return GeneratorProvider; | ||||
| }); | ||||
| @@ -24,96 +24,47 @@ | ||||
| /** | ||||
|  * Module defining SinewaveTelemetryProvider. Created by vwoeltje on 11/12/14. | ||||
|  */ | ||||
| define( | ||||
|     ["./SinewaveTelemetrySeries"], | ||||
|     function (SinewaveTelemetrySeries) { | ||||
|         "use strict"; | ||||
| define([ | ||||
|     "./SinewaveTelemetrySeries", | ||||
|     "./GeneratorProvider" | ||||
| ], function ( | ||||
|     SinewaveTelemetrySeries, | ||||
|     GeneratorProvider | ||||
| ) { | ||||
|  | ||||
|         /** | ||||
|          * | ||||
|          * @constructor | ||||
|          */ | ||||
|         function SinewaveTelemetryProvider($q, $timeout) { | ||||
|             var subscriptions = [], | ||||
|                 generating = false; | ||||
|     function SinewaveTelemetryProvider() { | ||||
|         this.provider = new GeneratorProvider(); | ||||
|     } | ||||
|  | ||||
|             // | ||||
|             function matchesSource(request) { | ||||
|                 return request.source === "generator"; | ||||
|             } | ||||
|  | ||||
|             // Used internally; this will be repacked by doPackage | ||||
|             function generateData(request) { | ||||
|                 return { | ||||
|                     key: request.key, | ||||
|                     telemetry: new SinewaveTelemetrySeries(request) | ||||
|     SinewaveTelemetryProvider.prototype.requestTelemetry = function (requests) { | ||||
|         if (requests[0].source !== 'generator') { | ||||
|             return Promise.resolve({}); | ||||
|         } | ||||
|         return this.provider.request({}, requests[0]) | ||||
|             .then(function (data) { | ||||
|                 var res = { | ||||
|                     generator: {} | ||||
|                 }; | ||||
|             } | ||||
|                 res.generator[requests[0].key] = new SinewaveTelemetrySeries(data); | ||||
|                 return res; | ||||
|             }); | ||||
|     }; | ||||
|  | ||||
|             // | ||||
|             function doPackage(results) { | ||||
|                 var packaged = {}; | ||||
|                 results.forEach(function (result) { | ||||
|                     packaged[result.key] = result.telemetry; | ||||
|                 }); | ||||
|                 // Format as expected (sources -> keys -> telemetry) | ||||
|                 return { generator: packaged }; | ||||
|             } | ||||
|  | ||||
|             function requestTelemetry(requests) { | ||||
|                 return $timeout(function () { | ||||
|                     return doPackage(requests.filter(matchesSource).map(generateData)); | ||||
|                 }, 0); | ||||
|             } | ||||
|  | ||||
|             function handleSubscriptions() { | ||||
|                 subscriptions.forEach(function (subscription) { | ||||
|                     var requests = subscription.requests; | ||||
|                     subscription.callback(doPackage( | ||||
|                         requests.filter(matchesSource).map(generateData) | ||||
|                     )); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             function startGenerating() { | ||||
|                 generating = true; | ||||
|                 $timeout(function () { | ||||
|                     handleSubscriptions(); | ||||
|                     if (generating && subscriptions.length > 0) { | ||||
|                         startGenerating(); | ||||
|                     } else { | ||||
|                         generating = false; | ||||
|                     } | ||||
|                 }, 1000); | ||||
|             } | ||||
|  | ||||
|             function subscribe(callback, requests) { | ||||
|                 var subscription = { | ||||
|                     callback: callback, | ||||
|                     requests: requests | ||||
|                 }; | ||||
|  | ||||
|                 function unsubscribe() { | ||||
|                     subscriptions = subscriptions.filter(function (s) { | ||||
|                         return s !== subscription; | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|                 subscriptions.push(subscription); | ||||
|  | ||||
|                 if (!generating) { | ||||
|                     startGenerating(); | ||||
|                 } | ||||
|  | ||||
|                 return unsubscribe; | ||||
|             } | ||||
|  | ||||
|             return { | ||||
|                 requestTelemetry: requestTelemetry, | ||||
|                 subscribe: subscribe | ||||
|             }; | ||||
|     SinewaveTelemetryProvider.prototype.subscribe = function (callback, requests) { | ||||
|         if (requests[0].source !== 'generator') { | ||||
|             return function unsubscribe() {}; | ||||
|         } | ||||
|  | ||||
|         return SinewaveTelemetryProvider; | ||||
|     } | ||||
| ); | ||||
|         function wrapper(data) { | ||||
|             var res = { | ||||
|                 generator: {} | ||||
|             }; | ||||
|             res.generator[requests[0].key] = new SinewaveTelemetrySeries(data); | ||||
|             callback(res); | ||||
|         } | ||||
|  | ||||
|         return this.provider.subscribe({}, wrapper, requests[0]); | ||||
|     }; | ||||
|  | ||||
|     return SinewaveTelemetryProvider; | ||||
| }); | ||||
|   | ||||
| @@ -24,55 +24,52 @@ | ||||
| /** | ||||
|  * Module defining SinewaveTelemetry. Created by vwoeltje on 11/12/14. | ||||
|  */ | ||||
| define( | ||||
|     ['./SinewaveConstants'], | ||||
|     function (SinewaveConstants) { | ||||
| define([ | ||||
|  | ||||
| ], function ( | ||||
|  | ||||
| ) { | ||||
|         "use strict"; | ||||
|  | ||||
|         var ONE_DAY = 60 * 60 * 24, | ||||
|             firstObservedTime = Math.floor(SinewaveConstants.START_TIME / 1000); | ||||
|  | ||||
|         /** | ||||
|          * | ||||
|          * @constructor | ||||
|          */ | ||||
|         function SinewaveTelemetrySeries(request) { | ||||
|             var timeOffset = (request.domain === 'yesterday') ? ONE_DAY : 0, | ||||
|                 latestTime = Math.floor(Date.now() / 1000) - timeOffset, | ||||
|                 firstTime = firstObservedTime - timeOffset, | ||||
|                 endTime = (request.end !== undefined) ? | ||||
|                         Math.floor(request.end / 1000) : latestTime, | ||||
|                 count = Math.min(endTime, latestTime) - firstTime, | ||||
|                 period = +request.period || 30, | ||||
|                 generatorData = {}, | ||||
|                 requestStart = (request.start === undefined) ? firstTime : | ||||
|                         Math.max(Math.floor(request.start / 1000), firstTime), | ||||
|                 offset = requestStart - firstTime; | ||||
|  | ||||
|             if (request.size !== undefined) { | ||||
|                 offset = Math.max(offset, count - request.size); | ||||
|         function SinewaveTelemetrySeries(data) { | ||||
|             if (!Array.isArray(data)) { | ||||
|                 data = [data]; | ||||
|             } | ||||
|  | ||||
|             generatorData.getPointCount = function () { | ||||
|                 return count - offset; | ||||
|             }; | ||||
|  | ||||
|             generatorData.getDomainValue = function (i, domain) { | ||||
|                 // delta uses the same numeric values as the default domain, | ||||
|                 // so it's not checked for here, just formatted for display | ||||
|                 // differently. | ||||
|                 return (i + offset) * 1000 + firstTime * 1000 - | ||||
|                     (domain === 'yesterday' ? (ONE_DAY * 1000) : 0); | ||||
|             }; | ||||
|  | ||||
|             generatorData.getRangeValue = function (i, range) { | ||||
|                 range = range || "sin"; | ||||
|                 return Math[range]((i + offset) * Math.PI * 2 / period); | ||||
|             }; | ||||
|  | ||||
|             return generatorData; | ||||
|             this.data = data; | ||||
|         } | ||||
|  | ||||
|         SinewaveTelemetrySeries.prototype.getPointCount = function () { | ||||
|             return this.data.length; | ||||
|         }; | ||||
|  | ||||
|  | ||||
|         SinewaveTelemetrySeries.prototype.getDomainValue = function ( | ||||
|             index, | ||||
|             domain | ||||
|         ) { | ||||
|             domain = domain || 'time'; | ||||
|  | ||||
|             return this.getDatum(index)[domain]; | ||||
|         }; | ||||
|  | ||||
|         SinewaveTelemetrySeries.prototype.getRangeValue = function ( | ||||
|             index, | ||||
|             range | ||||
|         ) { | ||||
|             range = range || 'sin'; | ||||
|             return this.getDatum(index)[range]; | ||||
|         }; | ||||
|  | ||||
|         SinewaveTelemetrySeries.prototype.getDatum = function (index) { | ||||
|             if (index > this.data.length || index < 0) { | ||||
|                 throw new Error('IndexOutOfRange: index not available in series.'); | ||||
|             } | ||||
|             return this.data[index]; | ||||
|         }; | ||||
|  | ||||
|         SinewaveTelemetrySeries.prototype.getData = function () { | ||||
|             return this.data; | ||||
|         }; | ||||
|  | ||||
|         return SinewaveTelemetrySeries; | ||||
|     } | ||||
| ); | ||||
| }); | ||||
|   | ||||
							
								
								
									
										115
									
								
								example/generator/src/WorkerInterface.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								example/generator/src/WorkerInterface.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     'text!./generatorWorker.js', | ||||
|     'uuid' | ||||
| ], function ( | ||||
|     workerText, | ||||
|     uuid | ||||
| ) { | ||||
|  | ||||
|     var workerBlob = new Blob( | ||||
|         [workerText], | ||||
|         {type: 'application/javascript'} | ||||
|     ); | ||||
|     var workerUrl = URL.createObjectURL(workerBlob); | ||||
|  | ||||
|     function WorkerInterface() { | ||||
|         this.worker = new Worker(workerUrl); | ||||
|         this.worker.onmessage = this.onMessage.bind(this); | ||||
|         this.callbacks = {}; | ||||
|     } | ||||
|  | ||||
|     WorkerInterface.prototype.onMessage = function (message) { | ||||
|         message = message.data; | ||||
|         var callback = this.callbacks[message.id]; | ||||
|         if (callback) { | ||||
|             if (callback(message)) { | ||||
|                 delete this.callbacks[message.id]; | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     WorkerInterface.prototype.dispatch = function (request, data, callback) { | ||||
|         var message = { | ||||
|             request: request, | ||||
|             data: data, | ||||
|             id: uuid() | ||||
|         }; | ||||
|  | ||||
|         if (callback) { | ||||
|             this.callbacks[message.id] = callback; | ||||
|         } | ||||
|  | ||||
|         this.worker.postMessage(message); | ||||
|  | ||||
|         return message.id; | ||||
|     }; | ||||
|  | ||||
|     WorkerInterface.prototype.request = function (request) { | ||||
|         var deferred = {}; | ||||
|         var promise = new Promise(function (resolve, reject) { | ||||
|             deferred.resolve = resolve; | ||||
|             deferred.reject = reject; | ||||
|         }); | ||||
|  | ||||
|         function callback(message) { | ||||
|             if (message.error) { | ||||
|                 deferred.reject(message.error); | ||||
|             } else { | ||||
|                 deferred.resolve(message.data); | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         this.dispatch('request', request, callback); | ||||
|  | ||||
|         return promise; | ||||
|     }; | ||||
|  | ||||
|     WorkerInterface.prototype.subscribe = function (request, cb) { | ||||
|         var isCancelled = false; | ||||
|  | ||||
|         var callback = function (message) { | ||||
|             if (isCancelled) { | ||||
|                 return true; | ||||
|             } | ||||
|             cb(message.data); | ||||
|         }; | ||||
|  | ||||
|         var messageId = this.dispatch('subscribe', request, callback) | ||||
|  | ||||
|         return function () { | ||||
|             isCancelled = true; | ||||
|             this.dispatch('unsubscribe', { | ||||
|                 id: messageId | ||||
|             }); | ||||
|         }.bind(this); | ||||
|  | ||||
|     }; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     return WorkerInterface; | ||||
| }); | ||||
							
								
								
									
										150
									
								
								example/generator/src/generatorWorker.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								example/generator/src/generatorWorker.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,150 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /*global self*/ | ||||
|  | ||||
| (function () { | ||||
|  | ||||
|  | ||||
|     var handlers = { | ||||
|         subscribe: onSubscribe, | ||||
|         unsubscribe: onUnsubscribe, | ||||
|         request: onRequest | ||||
|     }; | ||||
|  | ||||
|     var subscriptions = {}; | ||||
|  | ||||
|     function workSubscriptions(timestamp) { | ||||
|         var now = Date.now(); | ||||
|         var nextWork = Math.min.apply(Math, Object.values(subscriptions).map(function (subscription) { | ||||
|             return subscription(now); | ||||
|         })); | ||||
|         var wait = nextWork - now; | ||||
|         if (wait < 0) { | ||||
|             wait = 0; | ||||
|         } | ||||
|  | ||||
|         if (Number.isFinite(wait)) { | ||||
|             setTimeout(workSubscriptions, wait); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function onSubscribe(message) { | ||||
|         var data = message.data; | ||||
|  | ||||
|         var start = Date.now(); | ||||
|         var step = 1000 / data.dataRateInHz; | ||||
|         var nextStep = start - (start % step) + step; | ||||
|  | ||||
|         function work(now) { | ||||
|             while (nextStep < now) { | ||||
|                 self.postMessage({ | ||||
|                     id: message.id, | ||||
|                     data: { | ||||
|                         utc: nextStep, | ||||
|                         yesterday: nextStep - 60*60*24*1000, | ||||
|                         delta: 60*60*24*1000, | ||||
|                         sin: sin(nextStep, data.period, data.amplitude, data.offset), | ||||
|                         cos: cos(nextStep, data.period, data.amplitude, data.offset) | ||||
|                     } | ||||
|                 }); | ||||
|                 nextStep += step; | ||||
|             } | ||||
|             return nextStep; | ||||
|         } | ||||
|  | ||||
|         subscriptions[message.id] = work; | ||||
|         workSubscriptions(); | ||||
|     } | ||||
|  | ||||
|     function onUnsubscribe(message) { | ||||
|         delete subscriptions[message.data.id]; | ||||
|     } | ||||
|  | ||||
|     function onRequest(message) { | ||||
|         var data = message.data; | ||||
|         if (!data.start || !data.end) { | ||||
|             throw new Error('missing start and end!'); | ||||
|         } | ||||
|  | ||||
|         var now = Date.now(); | ||||
|         var start = data.start; | ||||
|         var end = data.end > now ? now : data.end; | ||||
|         var amplitude = data.amplitude; | ||||
|         var period = data.period; | ||||
|         var offset = data.offset; | ||||
|         var dataRateInHz = data.dataRateInHz; | ||||
|  | ||||
|         var step = 1000 / dataRateInHz; | ||||
|         var nextStep = start - (start % step) + step; | ||||
|  | ||||
|         var data = []; | ||||
|  | ||||
|         for (; nextStep < end; nextStep += step) { | ||||
|             data.push({ | ||||
|                 utc: nextStep, | ||||
|                 yesterday: nextStep - 60*60*24*1000, | ||||
|                 delta: 60*60*24*1000, | ||||
|                 sin: sin(nextStep, period, amplitude, offset), | ||||
|                 cos: cos(nextStep, period, amplitude, offset) | ||||
|             }); | ||||
|         } | ||||
|         self.postMessage({ | ||||
|             id: message.id, | ||||
|             data: data | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function cos(timestamp, period, amplitude, offset) { | ||||
|         return amplitude * | ||||
|             Math.cos(timestamp / period / 1000 * Math.PI * 2) + offset; | ||||
|     } | ||||
|  | ||||
|     function sin(timestamp, period, amplitude, offset) { | ||||
|         return amplitude * | ||||
|             Math.sin(timestamp / period / 1000 * Math.PI * 2) + offset; | ||||
|     } | ||||
|  | ||||
|     function sendError(error, message) { | ||||
|         self.postMessage({ | ||||
|             error: error.name + ': ' + error.message, | ||||
|             message: message, | ||||
|             id: message.id | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     self.onmessage = function handleMessage(event) { | ||||
|         var message = event.data; | ||||
|         var handler = handlers[message.request]; | ||||
|  | ||||
|         if (!handler) { | ||||
|             sendError(new Error('unknown message type'), message); | ||||
|         } else { | ||||
|             try { | ||||
|                 handler(message); | ||||
|             } catch (e) { | ||||
|                 sendError(e, message); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| }()); | ||||
		Reference in New Issue
	
	Block a user