Skip to content

Commit

Permalink
Enable Worker to do work for multiple map instances
Browse files Browse the repository at this point in the history
  • Loading branch information
Anand Thakker committed Aug 6, 2016
1 parent 1aa4f4f commit 494590a
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 44 deletions.
85 changes: 50 additions & 35 deletions js/source/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,28 @@ function Worker(self) {
this.self = self;
this.actor = new Actor(self, this);

// simple accessor object for passing to WorkerSources
var styleLayers = {
getLayers: function () { return this.layers; }.bind(this),
getLayerFamilies: function () { return this.layerFamilies; }.bind(this)
};
this.layers = {};
this.layerFamilies = {};

this.workerSources = {
vector: new VectorTileWorkerSource(this.actor, styleLayers),
geojson: new GeoJSONWorkerSource(this.actor, styleLayers)
this.workerSourceTypes = {
vector: VectorTileWorkerSource,
geojson: GeoJSONWorkerSource
};

// [mapId][sourceType] => worker source instance
this.workerSources = {};

this.self.registerWorkerSource = function (name, WorkerSource) {
if (this.workerSources[name]) {
if (this.workerSourceTypes[name]) {
throw new Error('Worker source with name "' + name + '" already registered.');
}
this.workerSources[name] = new WorkerSource(this.actor, styleLayers);
this.workerSourceTypes[name] = WorkerSource;
}.bind(this);
}

util.extend(Worker.prototype, {
'set layers': function(layers) {
this.layers = {};
var that = this;
'set layers': function(mapId, layers) {
var styleLayers = this.layers[mapId] = {};

// Filter layers and create an id -> layer map
var childLayerIndicies = [];
Expand All @@ -60,20 +59,21 @@ util.extend(Worker.prototype, {
function setLayer(serializedLayer) {
var styleLayer = StyleLayer.create(
serializedLayer,
serializedLayer.ref && that.layers[serializedLayer.ref]
serializedLayer.ref && styleLayers[serializedLayer.ref]
);
styleLayer.updatePaintTransitions({}, {transition: false});
that.layers[styleLayer.id] = styleLayer;
styleLayers[styleLayer.id] = styleLayer;
}

this.layerFamilies = createLayerFamilies(this.layers);
this.layerFamilies[mapId] = createLayerFamilies(this.layers[mapId]);
},

'update layers': function(layers) {
var that = this;
'update layers': function(mapId, layers) {
var id;
var layer;

var styleLayers = this.layers[mapId];

// Update ref parents
for (id in layers) {
layer = layers[id];
Expand All @@ -87,41 +87,41 @@ util.extend(Worker.prototype, {
}

function updateLayer(layer) {
var refLayer = that.layers[layer.ref];
if (that.layers[layer.id]) {
that.layers[layer.id].set(layer, refLayer);
var refLayer = styleLayers[layer.ref];
if (styleLayers[layer.id]) {
styleLayers[layer.id].set(layer, refLayer);
} else {
that.layers[layer.id] = StyleLayer.create(layer, refLayer);
styleLayers[layer.id] = StyleLayer.create(layer, refLayer);
}
that.layers[layer.id].updatePaintTransitions({}, {transition: false});
styleLayers[layer.id].updatePaintTransitions({}, {transition: false});
}

this.layerFamilies = createLayerFamilies(this.layers);
this.layerFamilies[mapId] = createLayerFamilies(this.layers[mapId]);
},

'load tile': function(params, callback) {
'load tile': function(mapId, params, callback) {
var type = params.type || 'vector';
this.workerSources[type].loadTile(params, callback);
this.getWorkerSource(mapId, type).loadTile(params, callback);
},

'reload tile': function(params, callback) {
'reload tile': function(mapId, params, callback) {
var type = params.type || 'vector';
this.workerSources[type].reloadTile(params, callback);
this.getWorkerSource(mapId, type).reloadTile(params, callback);
},

'abort tile': function(params) {
'abort tile': function(mapId, params) {
var type = params.type || 'vector';
this.workerSources[type].abortTile(params);
this.getWorkerSource(mapId, type).abortTile(params);
},

'remove tile': function(params) {
'remove tile': function(mapId, params) {
var type = params.type || 'vector';
this.workerSources[type].removeTile(params);
this.getWorkerSource(mapId, type).removeTile(params);
},

'redo placement': function(params, callback) {
'redo placement': function(mapId, params, callback) {
var type = params.type || 'vector';
this.workerSources[type].redoPlacement(params, callback);
this.getWorkerSource(mapId, type).redoPlacement(params, callback);
},

/**
Expand All @@ -130,13 +130,28 @@ util.extend(Worker.prototype, {
* function taking `(name, workerSourceObject)`.
* @private
*/
'load worker source': function(params, callback) {
'load worker source': function(map, params, callback) {
try {
this.self.importScripts(params.url);
callback();
} catch (e) {
callback(e);
}
},

getWorkerSource: function(mapId, type) {
if (!this.workerSources[mapId])
this.workerSources[mapId] = {};
if (!this.workerSources[mapId][type]) {
// simple accessor object for passing to WorkerSources
var styleLayers = {
getLayers: function () { return this.layers[mapId]; }.bind(this),
getLayerFamilies: function () { return this.layerFamilies[mapId]; }.bind(this)
};
this.workerSources[mapId][type] = new this.workerSourceTypes[type](this.actor, styleLayers);
}

return this.workerSources[mapId][type];
}
});

Expand Down
6 changes: 3 additions & 3 deletions js/style/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ Style.prototype = util.inherit(Evented, {

// Callbacks from web workers

'get sprite json': function(params, callback) {
'get sprite json': function(_, params, callback) {
var sprite = this.sprite;
if (sprite.loaded()) {
callback(null, { sprite: sprite.data, retina: sprite.retina });
Expand All @@ -742,7 +742,7 @@ Style.prototype = util.inherit(Evented, {
}
},

'get icons': function(params, callback) {
'get icons': function(_, params, callback) {
var sprite = this.sprite;
var spriteAtlas = this.spriteAtlas;
if (sprite.loaded()) {
Expand All @@ -756,7 +756,7 @@ Style.prototype = util.inherit(Evented, {
}
},

'get glyphs': function(params, callback) {
'get glyphs': function(_, params, callback) {
var stacks = params.stacks,
remaining = Object.keys(stacks).length,
allGlyphs = {};
Expand Down
14 changes: 9 additions & 5 deletions js/util/actor.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ module.exports = Actor;
*
* @param {WebWorker} target
* @param {WebWorker} parent
* @param {string|number} mapId A unique identifier for the Map instance using this Actor.
* @private
*/
function Actor(target, parent) {
function Actor(target, parent, mapId) {
this.target = target;
this.parent = parent;
this.mapId = mapId;
this.callbacks = {};
this.callbackID = 0;
this.receive = this.receive.bind(this);
Expand All @@ -32,17 +34,19 @@ Actor.prototype.receive = function(message) {
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.data, done.bind(this));
} else if (typeof data.id !== 'undefined' && this.parent.workerSources) {
this.parent[data.type](data.mapId, data.data, done.bind(this));
} else if (typeof data.id !== 'undefined' && this.parent.getWorkerSource) {
// data.type == sourcetype.method
var keys = data.type.split('.');
this.parent.workerSources[keys[0]][keys[1]](data.data, done.bind(this));
var workerSource = this.parent.getWorkerSource(data.mapId, keys[0]);
workerSource[keys[1]](data.data, done.bind(this));
} else {
this.parent[data.type](data.data);
}

function done(err, data, buffers) {
this.postMessage({
mapId: this.mapId,
type: '<response>',
id: String(id),
error: err ? String(err) : null,
Expand All @@ -54,7 +58,7 @@ Actor.prototype.receive = function(message) {
Actor.prototype.send = function(type, data, callback, buffers) {
var id = null;
if (callback) this.callbacks[id = this.callbackID++] = callback;
this.postMessage({ type: type, id: String(id), data: data }, buffers);
this.postMessage({ mapId: this.mapId, type: type, id: String(id), data: data }, buffers);
};

/**
Expand Down
3 changes: 2 additions & 1 deletion js/util/dispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ module.exports = Dispatcher;
function Dispatcher(length, parent) {
this.actors = [];
this.currentActor = 0;
this.id = util.uniqueId();
for (var i = 0; i < length; i++) {
var worker = new WebWorker();
var actor = new Actor(worker, parent);
var actor = new Actor(worker, parent, this.id);
actor.name = "Worker " + i;
this.actors.push(actor);
}
Expand Down

0 comments on commit 494590a

Please sign in to comment.