diff --git a/HISTORY.md b/HISTORY.md index 446aa31f..cf31750f 100755 --- a/HISTORY.md +++ b/HISTORY.md @@ -49,6 +49,9 @@ * **Translation Updates:** * German +### 2022-05-25 +* threads: update programmatic custom block-type changes in data references + ### 2022-05-23 * blocks: fixed block label color when expanding or inserting variadic infix slots diff --git a/snap.html b/snap.html index 14afaf8b..15b12113 100755 --- a/snap.html +++ b/snap.html @@ -17,7 +17,7 @@ - + diff --git a/src/threads.js b/src/threads.js index 5a3e073a..2e642b3d 100644 --- a/src/threads.js +++ b/src/threads.js @@ -65,7 +65,7 @@ StagePickerMorph, CustomBlockDefinition*/ /*jshint esversion: 11, bitwise: false, evil: true*/ -modules.threads = '2022-May-20'; +modules.threads = '2022-May-25'; var ThreadManager; var Process; @@ -5640,6 +5640,7 @@ Process.prototype.doSetBlockAttribute = function (attribute, block, val) { expr, def, template, + oldType, type; this.assertType(block, types); @@ -5666,6 +5667,12 @@ Process.prototype.doSetBlockAttribute = function (attribute, block, val) { } } + function isMajorTypeChange() { + var rep = ['reporter', 'predicate']; + return (type === 'command' && rep.includes(oldType)) || + (oldType == 'command' && rep.includes(type)); + } + switch (choice) { case 'label': def.setBlockLabel(val); @@ -5698,10 +5705,27 @@ Process.prototype.doSetBlockAttribute = function (attribute, block, val) { if (rcvr.allBlockInstances(def).every(block => block.isChangeableTo(type)) ) { + oldType = def.type; def.type = type; } else { throw new Error('cannot change this\nfor a block that is in use'); } + if (isMajorTypeChange()) { + // since we've already scanned all contexts we know that those + // that contain block instances only contain single, unattached + // ones. Therefore we can simply replace them with new ones. + if (def.isGlobal) { + ide.stage.allContextsUsing(def).forEach(context => + context.expression = def.blockInstance() + ); + } else { + ide.stage.allContextsInvoking(def.blockSpec(), rcvr).forEach( + context => context.expression = def.blockInstance() + ); + } + } + + break; case 'scope': if (isInUse()) {