-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
Copy pathactor.js
72 lines (65 loc) · 2.26 KB
/
actor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
'use strict';
module.exports = Actor;
/**
* An implementation of the [Actor design pattern](http://en.wikipedia.org/wiki/Actor_model)
* that maintains the relationship between asynchronous tasks and the objects
* that spin them off - in this case, tasks like parsing parts of styles,
* owned by the styles
*
* @param {WebWorker} target
* @param {WebWorker} parent
* @param {string|undefined} parentId
* @private
*/
function Actor(target, parent, parentId) {
this.target = target;
this.parent = parent;
this.parentId = parentId;
this.callbacks = {};
this.callbackID = 0;
this.receive = this.receive.bind(this);
this.target.addEventListener('message', this.receive, false);
}
Actor.prototype.receive = function(message) {
var data = message.data,
id = data.id,
callback;
if (data.type === '<response>') {
callback = this.callbacks[data.id];
delete this.callbacks[data.id];
if (callback) callback(data.error || null, data.data);
} else if (typeof data.id !== 'undefined' && this.parent[data.type]) {
// data.type == 'load tile', 'remove tile', etc.
this.parent[data.type](data.parentId, data.data, done.bind(this));
} else if (typeof data.id !== 'undefined' && this.parent.workerSources) {
// data.type == sourcetype.method
var keys = data.type.split('.');
this.parent.workerSources[keys[0]][keys[1]](data.parentId, data.data, done.bind(this));
} else {
this.parent[data.type](data.data);
}
function done(err, data, buffers) {
this.postMessage({
type: '<response>',
id: String(id),
error: err ? String(err) : null,
data: data
}, buffers);
}
};
Actor.prototype.send = function(type, data, callback, buffers) {
var id = null;
if (callback) this.callbacks[id = this.callbackID++] = callback;
this.postMessage({ parentId: this.parentId, type: type, id: String(id), data: data }, buffers);
};
/**
* Wrapped postMessage API that abstracts around IE's lack of
* `transferList` support.
*
* @param {Object} message
* @param {Object} transferList
* @private
*/
Actor.prototype.postMessage = function(message, transferList) {
this.target.postMessage(message, transferList);
};