Files
openlayers/float-no-zero/closure-library/closure/goog/gears/workerpool.js
2014-03-07 10:55:12 +01:00

241 lines
6.8 KiB
JavaScript

// Copyright 2007 The Closure Library Authors. All Rights Reserved.
//
// 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.
/**
* @fileoverview This file implements a wrapper around the Gears WorkerPool
* with some extra features.
*
* @author arv@google.com (Erik Arvidsson)
*/
goog.provide('goog.gears.WorkerPool');
goog.provide('goog.gears.WorkerPool.Event');
goog.provide('goog.gears.WorkerPool.EventType');
goog.require('goog.events.Event');
goog.require('goog.events.EventTarget');
goog.require('goog.gears');
goog.require('goog.gears.Worker');
/**
* This class implements a wrapper around the Gears Worker Pool.
*
* @constructor
* @extends {goog.events.EventTarget}
*/
goog.gears.WorkerPool = function() {
goog.events.EventTarget.call(this);
/**
* Map from thread id to worker object
* @type {Object}
* @private
*/
this.workers_ = {};
// If we are in a worker thread we get the global google.gears.workerPool,
// otherwise we create a new Gears WorkerPool using the factory
var workerPool = /** @type {GearsWorkerPool} */
(goog.getObjectByName('google.gears.workerPool'));
if (workerPool) {
this.workerPool_ = workerPool;
} else {
// use a protected method to let the sub class override
this.workerPool_ = this.getGearsWorkerPool();
}
this.workerPool_.onmessage = goog.bind(this.handleMessage_, this);
};
goog.inherits(goog.gears.WorkerPool, goog.events.EventTarget);
/**
* Enum for event types fired by the WorkerPool.
* @enum {string}
*/
goog.gears.WorkerPool.EventType = {
UNKNOWN_WORKER: 'uknown_worker'
};
/**
* The Gears WorkerPool object.
* @type {GearsWorkerPool}
* @private
*/
goog.gears.WorkerPool.prototype.workerPool_ = null;
/**
* @return {GearsWorkerPool} A Gears WorkerPool object.
* @protected
*/
goog.gears.WorkerPool.prototype.getGearsWorkerPool = function() {
var factory = goog.gears.getFactory();
return factory.create('beta.workerpool');
};
/**
* Sets a last-chance error handler for a worker pool.
* WARNING: This will only succeed from inside a worker thread. In main thread,
* use window.onerror handler.
* @param {function(!GearsErrorObject):boolean} fn An error handler function
* that gets passed an error object with message and line number attributes.
* Returns whether the error was handled. If true stops propagation.
* @param {Object=} opt_handler This object for the function.
*/
goog.gears.WorkerPool.prototype.setErrorHandler = function(fn, opt_handler) {
this.workerPool_.onerror = goog.bind(fn, opt_handler);
};
/**
* Creates a new worker.
* @param {string} code The code to execute inside the worker.
* @return {goog.gears.Worker} The worker that was just created.
*/
goog.gears.WorkerPool.prototype.createWorker = function(code) {
var workerId = this.workerPool_.createWorker(code);
var worker = new goog.gears.Worker(this, workerId);
this.registerWorker(worker);
return worker;
};
/**
* Creates a new worker from a URL.
* @param {string} url URL from which to get the code to execute inside the
* worker.
* @return {goog.gears.Worker} The worker that was just created.
*/
goog.gears.WorkerPool.prototype.createWorkerFromUrl = function(url) {
var workerId = this.workerPool_.createWorkerFromUrl(url);
var worker = new goog.gears.Worker(this, workerId);
this.registerWorker(worker);
return worker;
};
/**
* Allows the worker who calls this to be used cross origin.
*/
goog.gears.WorkerPool.prototype.allowCrossOrigin = function() {
this.workerPool_.allowCrossOrigin();
};
/**
* Sends a message to a given worker.
* @param {*} message The message to send to the worker.
* @param {goog.gears.Worker} worker The worker to send the message to.
*/
goog.gears.WorkerPool.prototype.sendMessage = function(message, worker) {
this.workerPool_.sendMessage(message, worker.getId());
};
/**
* Callback when this worker recieves a message.
* @param {string} message The message that was sent.
* @param {number} senderId The ID of the worker that sent the message.
* @param {GearsMessageObject} messageObject An object containing all
* information about the message.
* @private
*/
goog.gears.WorkerPool.prototype.handleMessage_ = function(message,
senderId,
messageObject) {
if (!this.isDisposed()) {
var workers = this.workers_;
if (!workers[senderId]) {
// If the worker is unknown, dispatch an event giving users of the class
// the change to register the worker.
this.dispatchEvent(new goog.gears.WorkerPool.Event(
goog.gears.WorkerPool.EventType.UNKNOWN_WORKER,
senderId,
messageObject));
}
var worker = workers[senderId];
if (worker) {
worker.handleMessage(messageObject);
}
}
};
/**
* Registers a worker object.
* @param {goog.gears.Worker} worker The worker to register.
*/
goog.gears.WorkerPool.prototype.registerWorker = function(worker) {
this.workers_[worker.getId()] = worker;
};
/**
* Unregisters a worker object.
* @param {goog.gears.Worker} worker The worker to unregister.
*/
goog.gears.WorkerPool.prototype.unregisterWorker = function(worker) {
delete this.workers_[worker.getId()];
};
/** @override */
goog.gears.WorkerPool.prototype.disposeInternal = function() {
goog.gears.WorkerPool.superClass_.disposeInternal.call(this);
this.workerPool_ = null;
delete this.workers_;
};
/**
* Event used when the workerpool recieves a message
* @param {string} type The type of event.
* @param {number} senderId The id of the sender of the message.
* @param {GearsMessageObject} messageObject The message object.
*
* @constructor
* @extends {goog.events.Event}
*/
goog.gears.WorkerPool.Event = function(
type, senderId, messageObject) {
goog.events.Event.call(this, type);
/**
* The id of the sender of the message.
* @type {number}
*/
this.senderId = senderId;
/**
* The message sent from the worker. This is the same as the
* messageObject.body field and is here for convenience.
* @type {*}
*/
this.message = messageObject.body;
/**
* The object containing all information about the message.
* @type {GearsMessageObject}
*/
this.messageObject = messageObject;
};
goog.inherits(goog.gears.WorkerPool.Event, goog.events.Event);