241 lines
6.8 KiB
JavaScript
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);
|