From e79e15992153ae890f3ad38b49dd711c77373779 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Sun, 15 Dec 2019 23:42:15 +0100 Subject: [PATCH] added ability to add message listeners to broadcasts --- HISTORY.md | 2 ++ snap.html | 2 +- src/gui.js | 24 +++++++++++++++++++++++- src/objects.js | 5 ++++- src/threads.js | 3 +++ 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6be264a5..5a935313 100755 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,6 +6,7 @@ * export pen trails as SVG * access pen trails as SVG_Costume: new "pen vectors" reporter variant of "pen trails" * new Snap! API: programmatically broadcast messages and optionally wait from outside Snap! + * new Snap! API: programmatically add message listeners to get notified and react to broadcasts from outside Snap! * new Snap! API: programmatically get and set global variables from outside Snap! * **Notable Changes:** * when creating a costume from pen trails (raster or vector) make its rotation center the position of the sprite @@ -18,6 +19,7 @@ ### 2019-12-15 * gui, threads: new Snap! API: programmatically broadcast messages and optionally wait from outside Snap! * gui: added global variable access methods to the new Snap! API +* gui, objects: added ability to add message listeners to broadcasts ### 2019-12-13 * added direct relabelling option to pen trails blocks' context menus diff --git a/snap.html b/snap.html index 75668b5a..547e3ae9 100755 --- a/snap.html +++ b/snap.html @@ -8,7 +8,7 @@ - + diff --git a/src/gui.js b/src/gui.js index 43dc021a..cf7b2804 100644 --- a/src/gui.js +++ b/src/gui.js @@ -6061,6 +6061,8 @@ IDE_Morph.prototype.isIE = function () { // IDE_Morph external communication API - experimental /* programmatically trigger scripts from outside of Snap! + add message listeners to Snap! broadcasts and access + global variables */ IDE_Morph.prototype.broadcast = function(message, callback) { @@ -6069,7 +6071,7 @@ IDE_Morph.prototype.broadcast = function(message, callback) { // if a callback is supplied wait for all processes to terminate // then call the callback, same as using the "broadcast and wait" block - var rcvrs = this.stage.children.concat(this.stage), + var rcvrs = this.sprites.contents.concat(this.stage), myself = this, procs = []; @@ -6100,6 +6102,26 @@ IDE_Morph.prototype.broadcast = function(message, callback) { )); }); }); + (this.stage.messageCallbacks[message] || []).forEach(function (callback) { + callback(); + }); +}; + +IDE_Morph.prototype.addMessageListener = function (message, callback) { + // associate a callback function with a broadcast message, + // whenever the message is broadcast, the callback is executed, + // you can add multiple callbacks to a message, they will be + // executed in the order you added them + var funcs; + if (!isString(message)) { + throw new Error('message must be a String'); + } + funcs = this.stage.messageCallbacks[message]; + if (funcs instanceof Array) { + funcs.push(callback); + } else { + this.stage.messageCallbacks[message] = [callback]; + } }; IDE_Morph.prototype.getVarNames = function () { diff --git a/src/objects.js b/src/objects.js index 4a7dfbd0..dcbeb9e3 100644 --- a/src/objects.js +++ b/src/objects.js @@ -84,7 +84,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, BooleanSlotMorph, localize, TableMorph, TableFrameMorph, normalizeCanvas, VectorPaintEditorMorph, HandleMorph, AlignmentMorph, Process, XML_Element, WorldMap, copyCanvas*/ -modules.objects = '2019-December-13'; +modules.objects = '2019-December-15'; var SpriteMorph; var StageMorph; @@ -7486,6 +7486,9 @@ StageMorph.prototype.init = function (globals) { // world map client - experimental, transient this.worldMap = new WorldMap(); + // Snap! API event listeners - experimental, transient + this.messageCallbacks = {}; // name : [functions] + StageMorph.uber.init.call(this); this.cachedHSV = this.color.hsv(); diff --git a/src/threads.js b/src/threads.js index cf753327..1a4496d9 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3180,6 +3180,9 @@ Process.prototype.doBroadcast = function (message) { }); } }); + (stage.messageCallbacks[msg] || []).forEach(function (callback) { + callback(); + }); } return procs; };