add generic worker infrastructure
This commit is contained in:
parent
3cedb3bef6
commit
0696022218
6 changed files with 208 additions and 254 deletions
|
|
@ -59,12 +59,17 @@ exports.launch = function(env) {
|
||||||
var emacs = require("ace/keyboard/keybinding/emacs").Emacs;
|
var emacs = require("ace/keyboard/keybinding/emacs").Emacs;
|
||||||
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
|
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
|
||||||
|
|
||||||
|
var WorkerClient = require("ace/worker/WorkerClient").WorkerClient;
|
||||||
|
|
||||||
var docs = {};
|
var docs = {};
|
||||||
|
|
||||||
docs.js = new Document(document.getElementById("jstext").innerHTML);
|
docs.js = new Document(document.getElementById("jstext").innerHTML);
|
||||||
docs.js.setMode(new JavaScriptMode());
|
docs.js.setMode(new JavaScriptMode());
|
||||||
docs.js.setUndoManager(new UndoManager());
|
docs.js.setUndoManager(new UndoManager());
|
||||||
|
|
||||||
|
var worker = new WorkerClient("../..", ["ace", "pilot"], "ace/worker/demo", "Demo");
|
||||||
|
|
||||||
|
|
||||||
docs.css = new Document(document.getElementById("csstext").innerHTML);
|
docs.css = new Document(document.getElementById("csstext").innerHTML);
|
||||||
docs.css.setMode(new CssMode());
|
docs.css.setMode(new CssMode());
|
||||||
docs.css.setUndoManager(new UndoManager());
|
docs.css.setUndoManager(new UndoManager());
|
||||||
|
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
/**
|
|
||||||
* Ajax.org Code Editor (ACE)
|
|
||||||
*
|
|
||||||
* @copyright 2010, Ajax.org Services B.V.
|
|
||||||
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
|
|
||||||
* @author Fabian Jakobs <fabian AT ajax DOT org>
|
|
||||||
*/
|
|
||||||
require.def("ace/WorkerTokenizer", ["ace/lib/oop", "ace/MEventEmitter"], function(oop, MEventEmitter) {
|
|
||||||
|
|
||||||
var WorkerTokenizer = function(tokenizer) {
|
|
||||||
var workerUrl = require.nameToUrl("ace/worker", null, "_");
|
|
||||||
this.$worker = new Worker(workerUrl);
|
|
||||||
|
|
||||||
this.callbackId = 1;
|
|
||||||
this.callbacks = {};
|
|
||||||
|
|
||||||
var _self = this;
|
|
||||||
this.$worker.onerror = function(e) {
|
|
||||||
throw e;
|
|
||||||
};
|
|
||||||
this.$worker.onmessage = function(e) {
|
|
||||||
var msg = e.data;
|
|
||||||
//console.log("rec", msg)
|
|
||||||
switch(msg.type) {
|
|
||||||
case "log":
|
|
||||||
console.log(msg.data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "event":
|
|
||||||
_self.$dispatchEvent(msg.name, {data: msg.data});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "call":
|
|
||||||
var callback = _self.callbacks[msg.id];
|
|
||||||
if (callback) {
|
|
||||||
callback(msg.data);
|
|
||||||
delete _self.callbacks[msg.id];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
oop.implement(this, MEventEmitter);
|
|
||||||
|
|
||||||
this.$send = function(cmd, args) {
|
|
||||||
this.$worker.postMessage({command: cmd, args: args});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$call = function(cmd, args, callback) {
|
|
||||||
var id = this.callbackId++;
|
|
||||||
this.callbacks[id] = callback;
|
|
||||||
args.push(id);
|
|
||||||
this.$send(cmd, args);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setTokenizer = function(tokenizer) {
|
|
||||||
this.$send("setRules", ["ace/mode/JavaScriptHighlightRules"]);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setLines = function(textLines) {
|
|
||||||
this.lines = textLines;
|
|
||||||
this.$send("setLines", [textLines]);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.start = function(startRow) {
|
|
||||||
// TODO don't send all lines on each update!!
|
|
||||||
this.$send("setLines", [this.lines]);
|
|
||||||
this.$send("start", [startRow])
|
|
||||||
};
|
|
||||||
|
|
||||||
this.stop = function() {
|
|
||||||
this.$send("stop", [])
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getTokens = function(firstRow, lastRow, callback) {
|
|
||||||
this.$call("getTokens", [firstRow, lastRow], function(tokens) {
|
|
||||||
callback(tokens)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getState = function(row, callback) {
|
|
||||||
this.$call("getState", [row], callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
}).call(WorkerTokenizer.prototype);
|
|
||||||
|
|
||||||
return WorkerTokenizer;
|
|
||||||
});
|
|
||||||
|
|
@ -1,163 +0,0 @@
|
||||||
postMessage("Juhu Kinners");
|
|
||||||
|
|
||||||
var console = {
|
|
||||||
log: function(msg) {
|
|
||||||
postMessage({type: "log", data: msg});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var window = {
|
|
||||||
console: console
|
|
||||||
};
|
|
||||||
|
|
||||||
var require = function(name) {
|
|
||||||
if (require.modules[name])
|
|
||||||
return require.modules[name];
|
|
||||||
|
|
||||||
importScripts(require.baseUrl + "/" + name + ".js");
|
|
||||||
return require.modules[name];
|
|
||||||
};
|
|
||||||
|
|
||||||
require.def = function(name, deps, callback) {
|
|
||||||
if (!callback) {
|
|
||||||
callback = deps;
|
|
||||||
deps = [];
|
|
||||||
}
|
|
||||||
var modules = deps.map(function(dep) {
|
|
||||||
return require(dep);
|
|
||||||
});
|
|
||||||
require.modules[name] = callback.apply(this, modules);
|
|
||||||
};
|
|
||||||
|
|
||||||
require.baseUrl = "..";
|
|
||||||
require.modules = {};
|
|
||||||
|
|
||||||
var Tokenizer = require("ace/Tokenizer");
|
|
||||||
|
|
||||||
var bgtokenizer = {
|
|
||||||
running: false,
|
|
||||||
textLines: [],
|
|
||||||
lines: [],
|
|
||||||
currentLine: 0,
|
|
||||||
tokenizer: null,
|
|
||||||
|
|
||||||
init: function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.$worker = function() {
|
|
||||||
if (!self.running) { return; }
|
|
||||||
|
|
||||||
var workerStart = new Date();
|
|
||||||
var startLine = self.currentLine;
|
|
||||||
var textLines = self.textLines;
|
|
||||||
|
|
||||||
var processedLines = 0;
|
|
||||||
|
|
||||||
while (self.currentLine < textLines.length) {
|
|
||||||
self.lines[self.currentLine] = self.$tokenizeRows(self.currentLine, self.currentLine)[0];
|
|
||||||
self.currentLine++;
|
|
||||||
|
|
||||||
// only check every 5 lines
|
|
||||||
processedLines += 1;
|
|
||||||
if ((processedLines % 5 == 0) && (new Date() - workerStart) > 40) {
|
|
||||||
self.$event("update", {first: startLine, last: self.currentLine-1});
|
|
||||||
self.running = setTimeout(self.$worker, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.running = false;
|
|
||||||
self.$event("update", {first: startLine, last: textLines.length - 1});
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
setRules: function(rules) {
|
|
||||||
var Rules = require(rules);
|
|
||||||
this.tokenizer = new Tokenizer(new Rules().getRules());
|
|
||||||
this.lines = [];
|
|
||||||
|
|
||||||
this.start(0);
|
|
||||||
},
|
|
||||||
|
|
||||||
setLines: function(textLines) {
|
|
||||||
this.textLines = textLines;
|
|
||||||
this.lines = [];
|
|
||||||
|
|
||||||
this.stop();
|
|
||||||
},
|
|
||||||
|
|
||||||
start: function(startRow) {
|
|
||||||
this.currentLine = Math.min(startRow || 0, this.currentLine,
|
|
||||||
this.textLines.length);
|
|
||||||
|
|
||||||
// remove all cached items below this line
|
|
||||||
this.lines.splice(this.currentLine, this.lines.length);
|
|
||||||
|
|
||||||
this.stop();
|
|
||||||
this.running = setTimeout(this.$worker, 0);
|
|
||||||
},
|
|
||||||
|
|
||||||
stop: function() {
|
|
||||||
if (this.running)
|
|
||||||
clearTimeout(this.running);
|
|
||||||
|
|
||||||
this.running = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
getTokens: function(firstRow, lastRow, callbackId) {
|
|
||||||
this.$callback(this.$tokenizeRows(firstRow, lastRow), callbackId);
|
|
||||||
},
|
|
||||||
|
|
||||||
getState: function(row, callbackId) {
|
|
||||||
this.$callback(this.$tokenizeRows(row, row)[0].state, callbackId);
|
|
||||||
},
|
|
||||||
|
|
||||||
$tokenizeRows: function(firstRow, lastRow) {
|
|
||||||
var rows = [];
|
|
||||||
|
|
||||||
// determin start state
|
|
||||||
var state = "start";
|
|
||||||
var doCache = false;
|
|
||||||
if (firstRow > 0 && this.lines[firstRow - 1]) {
|
|
||||||
state = this.lines[firstRow - 1].state;
|
|
||||||
doCache = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var row=firstRow; row<=lastRow; row++) {
|
|
||||||
if (!this.lines[row]) {
|
|
||||||
var tokens = this.tokenizer.getLineTokens(this.textLines[row] || "", state);
|
|
||||||
var state = tokens.state;
|
|
||||||
rows.push(tokens);
|
|
||||||
|
|
||||||
if (doCache) {
|
|
||||||
this.lines[row] = tokens;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rows.push(this.lines[row]);
|
|
||||||
}
|
|
||||||
return rows;
|
|
||||||
},
|
|
||||||
|
|
||||||
$callback: function(data, callbackId) {
|
|
||||||
postMessage({
|
|
||||||
type: "call",
|
|
||||||
id: callbackId,
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
$event: function(name, data) {
|
|
||||||
postMessage({
|
|
||||||
type: "event",
|
|
||||||
name: name,
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bgtokenizer.init();
|
|
||||||
|
|
||||||
var onmessage = function(e) {
|
|
||||||
var msg = e.data;
|
|
||||||
bgtokenizer[msg.command].apply(bgtokenizer, msg.args);
|
|
||||||
};
|
|
||||||
16
lib/ace/worker/Demo.js
Normal file
16
lib/ace/worker/Demo.js
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
|
exports.Demo = function(sender) {
|
||||||
|
this.sender = sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
this.juhu = function() {
|
||||||
|
console.log("JUHU")
|
||||||
|
}
|
||||||
|
|
||||||
|
}).call(exports.Demot.prototype);
|
||||||
|
|
||||||
|
});
|
||||||
90
lib/ace/worker/WorkerClient.js
Normal file
90
lib/ace/worker/WorkerClient.js
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
/**
|
||||||
|
* Ajax.org Code Editor (ACE)
|
||||||
|
*
|
||||||
|
* @copyright 2010, Ajax.org Services B.V.
|
||||||
|
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
|
||||||
|
* @author Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
|
var oop = require("pilot/oop");
|
||||||
|
var EventEmitter = require("pilot/event_emitter").EventEmitter;
|
||||||
|
|
||||||
|
var WorkerClient = function(baseUrl, topLevelNamespaces, module, clazz) {
|
||||||
|
|
||||||
|
var workerUrl = require.nameToUrl("ace/worker/host", null, "_");
|
||||||
|
var worker = this.$worker = new Worker(workerUrl);
|
||||||
|
|
||||||
|
//context = s.contexts[contextName],
|
||||||
|
//config = context.config;
|
||||||
|
//debugger;
|
||||||
|
|
||||||
|
console.log(require.nameToUrl("ace", null, "_"))
|
||||||
|
console.log(require.nameToUrl("pilot", null, "_"))
|
||||||
|
|
||||||
|
var tlns = {};
|
||||||
|
for (var i=0; i<topLevelNamespaces.length; i++) {
|
||||||
|
var ns = topLevelNamespaces[i];
|
||||||
|
tlns[ns] = require.nameToUrl(ns, null, "_").replace(/.js$/, "").replace(require.config.baseUrl, "");
|
||||||
|
}
|
||||||
|
console.log(tlns)
|
||||||
|
|
||||||
|
this.$worker.postMessage({
|
||||||
|
init : true,
|
||||||
|
tlns: tlns,
|
||||||
|
base: baseUrl,
|
||||||
|
module: module,
|
||||||
|
clazz: clazz
|
||||||
|
});
|
||||||
|
|
||||||
|
this.callbackId = 1;
|
||||||
|
this.callbacks = {};
|
||||||
|
|
||||||
|
var _self = this;
|
||||||
|
this.$worker.onerror = function(e) {
|
||||||
|
throw e;
|
||||||
|
};
|
||||||
|
this.$worker.onmessage = function(e) {
|
||||||
|
var msg = e.data;
|
||||||
|
//console.log("rec", msg)
|
||||||
|
switch(msg.type) {
|
||||||
|
case "log":
|
||||||
|
console.log(msg.data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "event":
|
||||||
|
_self.$dispatchEvent(msg.name, {data: msg.data});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "call":
|
||||||
|
var callback = _self.callbacks[msg.id];
|
||||||
|
if (callback) {
|
||||||
|
callback(msg.data);
|
||||||
|
delete _self.callbacks[msg.id];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
oop.implement(this, EventEmitter);
|
||||||
|
|
||||||
|
this.send = function(cmd, args) {
|
||||||
|
this.$worker.postMessage({command: cmd, args: args});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.call = function(cmd, args, callback) {
|
||||||
|
var id = this.callbackId++;
|
||||||
|
this.callbacks[id] = callback;
|
||||||
|
args.push(id);
|
||||||
|
this.$send(cmd, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(WorkerClient.prototype);
|
||||||
|
|
||||||
|
exports.WorkerClient = WorkerClient;
|
||||||
|
|
||||||
|
});
|
||||||
97
lib/ace/worker/host.js
Normal file
97
lib/ace/worker/host.js
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
var console = {
|
||||||
|
log: function(msg) {
|
||||||
|
postMessage({type: "log", data: msg});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var window = {
|
||||||
|
console: console
|
||||||
|
};
|
||||||
|
|
||||||
|
var require = function(name) {
|
||||||
|
if (require.modules[name])
|
||||||
|
return require.modules[name].exports;
|
||||||
|
|
||||||
|
require.id = name;
|
||||||
|
|
||||||
|
var chunks = name.split("/");
|
||||||
|
chunks[0] = require.tlns[chunks[0]] || chunks[0];
|
||||||
|
name = chunks.join("/")
|
||||||
|
|
||||||
|
console.log(name)
|
||||||
|
console.log(require.baseUrl)
|
||||||
|
|
||||||
|
console.log(require.baseUrl + "/" + name + ".js");
|
||||||
|
importScripts(require.baseUrl + "/" + name + ".js");
|
||||||
|
return require.modules[name].exports;
|
||||||
|
};
|
||||||
|
require.modules = {};
|
||||||
|
require.tlns = {};
|
||||||
|
require.baseUrl;
|
||||||
|
|
||||||
|
var define = function(factory) {
|
||||||
|
var module = {
|
||||||
|
exports: {}
|
||||||
|
};
|
||||||
|
var returnExports = factory(require, module.exports, module);
|
||||||
|
if (returnExports) {
|
||||||
|
module.exports = exports;
|
||||||
|
}
|
||||||
|
|
||||||
|
require.modules[require.id] = module;
|
||||||
|
};
|
||||||
|
|
||||||
|
function initBaseUrls(baseUrl, topLevelNamespaces) {
|
||||||
|
require.baseUrl = baseUrl;
|
||||||
|
require.tlns = topLevelNamespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initSender() {
|
||||||
|
|
||||||
|
var EventEmitter = require("pilot/event_emitter").EventEmitter;
|
||||||
|
var oop = require("pilot/oop");
|
||||||
|
|
||||||
|
console.log("init sender")
|
||||||
|
|
||||||
|
var Sender = function() {}
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
oop.implement(this, EventEmitter);
|
||||||
|
|
||||||
|
this.callback = function(data, callbackId) {
|
||||||
|
postMessage({
|
||||||
|
type: "call",
|
||||||
|
id: callbackId,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
this.event = function(name, data) {
|
||||||
|
postMessage({
|
||||||
|
type: "event",
|
||||||
|
name: name,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).call(Sender.prototype);
|
||||||
|
|
||||||
|
return new Sender();
|
||||||
|
}
|
||||||
|
|
||||||
|
var main;
|
||||||
|
var sender;
|
||||||
|
|
||||||
|
onmessage = function(e) {
|
||||||
|
console.log(e.data)
|
||||||
|
var msg = e.data;
|
||||||
|
if (msg.command)
|
||||||
|
bgtokenizer[msg.command].apply(bgtokenizer, msg.args);
|
||||||
|
else if (msg.init) {
|
||||||
|
initBaseUrls(msg.base, msg.tlns);
|
||||||
|
sender = initSender();
|
||||||
|
var clazz = require(msg.module)[msg.classname];
|
||||||
|
main = new clazz(sender);
|
||||||
|
} else if (msg.event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue