diff --git a/app.js b/app.js index 1aba7743..c184f9b1 100644 --- a/app.js +++ b/app.js @@ -253,6 +253,7 @@ const script = { "moto/load-svg", "moto/load-url", "moto/load-file", + "moto/broker", "moto/db", "kiri/ui", "kiri/do", @@ -308,6 +309,7 @@ const script = { "geo/gyroid", "geo/mesh", "moto/pack", + "moto/broker", "kiri/slice", "kiri/slicer", "kiri/slicer2", @@ -378,6 +380,7 @@ const script = { "geo/polygon", "geo/polygons", "moto/kv", + "moto/broker", "moto/load-obj", "moto/load-stl", "kiri/conf", diff --git a/src/kiri/main.js b/src/kiri/main.js index 0104172d..de66101c 100644 --- a/src/kiri/main.js +++ b/src/kiri/main.js @@ -16,6 +16,7 @@ SETUP = parseOpt(LOC.search.substring(1)), SECURE = isSecure(LOC.protocol), LOCAL = self.debug && !SETUP.remote, + EVENT = new Broker(), SDB = MOTO.KV, ODB = KIRI.odb = new MOTO.Storage(SETUP.d ? SETUP.d[0] : 'kiri'), // K3DB = KIRI.wdb = new MOTO.Storage('kiri3', { stores:["file","work"] }).init(), @@ -40,7 +41,6 @@ STACKS = KIRI.stacks, DRIVER = undefined, complete = {}, - onEvent = {}, selectedMeshes = [], localFilterKey ='kiri-gcode-filters', localFilters = js2o(SDB.getItem(localFilterKey)) || [], @@ -654,22 +654,12 @@ return showFavorites; } - function sendOnEvent(name, data) { - if (name && onEvent[name]) { - onEvent[name].forEach(function(fn) { - fn(data, name); - }); - } + function sendOnEvent(name, data, options) { + EVENT.publish(name, data, options); } function addOnEvent(name, handler) { - if (Array.isArray(name)) { - return name.forEach(n => addOnEvent(n, handler)); - } - if (name && typeof(name) === 'string' && typeof(handler) === 'function') { - onEvent[name] = onEvent[name] || []; - onEvent[name].push(handler); - } + EVENT.subscribe(name, handler); return API.event; } diff --git a/src/moto/broker.js b/src/moto/broker.js new file mode 100644 index 00000000..d58b21c6 --- /dev/null +++ b/src/moto/broker.js @@ -0,0 +1,49 @@ +class Broker { + constructor() { + this.topics = {}; + } + + topics() { + return Object.keys(this.topics); + } + + subscribe(topic, listener) { + let topics = this.topics; + let channel = topics[topic]; + if (!channel) { + channel = topics[topic] = []; + } + if (channel.indexOf(listener) < 0) { + channel.push(listener); + this.publish(".topic.add", topic); + } + } + + unsubscribe(topic, listener) { + let channel = this.topics[topic]; + if (!channel) { + return; + } + let index = channel.indexOf(listener); + if (index < 0) { + return; + } + channel.splice(index,1); + if (channel.length === 0) { + delete this.topics[topic]; + this.publish(".topic.remove", topic); + } + } + + publish(topic, message, options = {}) { + if (topic !== ".topic.publish") { + this.publish(".topic.publish", {topic, message, options}); + } + let channel = this.topics[topic]; + if (channel && channel.length) { + for (let listener of channel) { + listener(message, topic, options); + } + } + } +}