kopia lustrzana https://github.com/backface/turtlestitch
new DEFINE BLOCK primitive
rodzic
e41dd6c281
commit
4252c1bef0
|
@ -49,6 +49,7 @@
|
|||
* blocks, threads: programmatically change the type of unused custom blocks
|
||||
* blocks, threads: new "scope" choice in block menu dropdown
|
||||
* blocks, threads: programmatically change the scope of unused custom blocks
|
||||
* blocks, objects, threads: new DEFINE BLOCK primitive
|
||||
|
||||
### 2022-05-01
|
||||
* byob: programmatically reduce the number of inputs in a custom block
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<script src="src/widgets.js?version=2021-17-09"></script>
|
||||
<script src="src/blocks.js?version=2022-05-02"></script>
|
||||
<script src="src/threads.js?version=2022-05-02"></script>
|
||||
<script src="src/objects.js?version=2022-04-28"></script>
|
||||
<script src="src/objects.js?version=2022-05-02"></script>
|
||||
<script src="src/scenes.js?version=2022-03-03"></script>
|
||||
<script src="src/gui.js?version=2022-04-26"></script>
|
||||
<script src="src/paint.js?version=2021-07-05"></script>
|
||||
|
|
31
src/byob.js
31
src/byob.js
|
@ -111,7 +111,7 @@ ArgLabelMorph*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.byob = '2022-May-01';
|
||||
modules.byob = '2022-May-02';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -564,25 +564,29 @@ CustomBlockDefinition.prototype.setBlockLabel = function (abstractSpec) {
|
|||
CustomBlockDefinition.prototype.setBlockDefinition = function (aContext) {
|
||||
// private - only to be called from a Process that also does housekeeping
|
||||
var oldInputs = this.inputNames(),
|
||||
newInputs = aContext.inputs,
|
||||
newInputs = aContext.inputs,
|
||||
declarations = this.declarations,
|
||||
parts = [],
|
||||
suffix = [],
|
||||
body = aContext,
|
||||
reportBlock,
|
||||
spec;
|
||||
|
||||
|
||||
// remove excess inputs or add missing ones
|
||||
this.addInputs(newInputs.length - oldInputs.length);
|
||||
spec = this.abstractBlockSpec();
|
||||
oldInputs = this.inputNames();
|
||||
|
||||
// change the input names in the spec to those of the given context
|
||||
if (spec.startsWith('_ ')) {
|
||||
while (spec.startsWith('_ ')) {
|
||||
parts.push('');
|
||||
spec = spec.slice(2);
|
||||
}
|
||||
if (spec.endsWith(' _')) {
|
||||
while (spec.endsWith(' _')) {
|
||||
spec = spec.slice(0, -2);
|
||||
suffix.push('');
|
||||
}
|
||||
parts = parts.concat(spec.split(' _ '));
|
||||
parts = parts.concat(spec.split(' _ ')).concat(suffix);
|
||||
spec = '';
|
||||
parts.forEach((part, i) =>
|
||||
spec += (part + (
|
||||
|
@ -599,7 +603,20 @@ CustomBlockDefinition.prototype.setBlockDefinition = function (aContext) {
|
|||
}
|
||||
|
||||
// replace the definition body with the given context
|
||||
this.body = aContext;
|
||||
if (body.expression instanceof Array) {
|
||||
this.body = null;
|
||||
return;
|
||||
} else if (body.expression instanceof ReporterBlockMorph) {
|
||||
// turn reporter epressions into a command stack with "report"
|
||||
body = copy(aContext);
|
||||
reportBlock = SpriteMorph.prototype.blockForSelector('doReport');
|
||||
reportBlock.replaceInput(
|
||||
reportBlock.inputs()[0],
|
||||
body.expression.fullCopy()
|
||||
);
|
||||
body.expression = reportBlock;
|
||||
}
|
||||
this.body = body;
|
||||
};
|
||||
|
||||
CustomBlockDefinition.prototype.addInputs = function (count) {
|
||||
|
|
|
@ -94,7 +94,7 @@ embedMetadataPNG*/
|
|||
|
||||
/*jshint esversion: 6*/
|
||||
|
||||
modules.objects = '2022-April-28';
|
||||
modules.objects = '2022-May-02';
|
||||
|
||||
var SpriteMorph;
|
||||
var StageMorph;
|
||||
|
@ -1105,6 +1105,11 @@ SpriteMorph.prototype.initBlocks = function () {
|
|||
spec: 'set %byob of block %repRing to %s',
|
||||
defaults: [['definition']]
|
||||
},
|
||||
reportDefineBlock: {
|
||||
type: 'reporter',
|
||||
category: 'sensing',
|
||||
spec: 'define block %s %repRing'
|
||||
},
|
||||
|
||||
// Operators
|
||||
reifyScript: {
|
||||
|
@ -2698,6 +2703,7 @@ SpriteMorph.prototype.blockTemplates = function (
|
|||
blocks.push(block('reportDate'));
|
||||
blocks.push(block('reportBlockAttribute'));
|
||||
blocks.push(block('doSetBlockAttribute'));
|
||||
blocks.push(block('reportDefineBlock'));
|
||||
|
||||
// for debugging: ///////////////
|
||||
if (devMode) {
|
||||
|
@ -9166,6 +9172,7 @@ StageMorph.prototype.blockTemplates = function (
|
|||
blocks.push(block('reportDate'));
|
||||
blocks.push(block('reportBlockAttribute'));
|
||||
blocks.push(block('doSetBlockAttribute'));
|
||||
blocks.push(block('reportDefineBlock'));
|
||||
|
||||
// for debugging: ///////////////
|
||||
if (this.world().isDevMode) {
|
||||
|
|
|
@ -61,7 +61,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy, Map,
|
|||
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, BLACK,
|
||||
TableFrameMorph, ColorSlotMorph, isSnapObject, newCanvas, Symbol, SVG_Costume,
|
||||
SnapExtensions, AlignmentMorph, TextMorph, Cloud, HatBlockMorph,
|
||||
StagePickerMorph*/
|
||||
StagePickerMorph, CustomBlockDefinition*/
|
||||
|
||||
/*jshint esversion: 11, bitwise: false, evil: true*/
|
||||
|
||||
|
@ -5636,7 +5636,6 @@ Process.prototype.doSetBlockAttribute = function (attribute, block, val) {
|
|||
rcvr = this.blockReceiver(),
|
||||
ide = rcvr.parentThatIsA(IDE_Morph),
|
||||
types = ['command', 'reporter', 'predicate'],
|
||||
count = 1,
|
||||
oldSpec,
|
||||
expr,
|
||||
def,
|
||||
|
@ -5672,7 +5671,7 @@ Process.prototype.doSetBlockAttribute = function (attribute, block, val) {
|
|||
def.setBlockLabel(val);
|
||||
break;
|
||||
case 'definition':
|
||||
this.assertType(val, 'command');
|
||||
this.assertType(val, types);
|
||||
def.setBlockDefinition(val);
|
||||
break;
|
||||
case 'category':
|
||||
|
@ -5726,8 +5725,7 @@ Process.prototype.doSetBlockAttribute = function (attribute, block, val) {
|
|||
|
||||
// make sure the spec is unique
|
||||
while (rcvr.doubleDefinitionsFor(def).length > 0) {
|
||||
count += 1;
|
||||
def.spec += (' (' + count + ')');
|
||||
def.spec += (' (2)');
|
||||
}
|
||||
|
||||
// update all block instances:
|
||||
|
@ -5752,6 +5750,38 @@ Process.prototype.doSetBlockAttribute = function (attribute, block, val) {
|
|||
ide.recordUnsavedChanges();
|
||||
};
|
||||
|
||||
Process.prototype.reportDefineBlock = function (label, context) {
|
||||
// highly experimental & under construction
|
||||
var rcvr = this.blockReceiver(),
|
||||
ide = rcvr.parentThatIsA(IDE_Morph),
|
||||
def;
|
||||
|
||||
this.assertType(label, 'text');
|
||||
if (label === '') {return ''; }
|
||||
this.assertType(context, ['command', 'reporter', 'predicate']);
|
||||
|
||||
// make a new custom block definition
|
||||
def = new CustomBlockDefinition('BYOB'); // haha!
|
||||
def.type = this.reportTypeOf(context);
|
||||
def.category = 'other';
|
||||
def.isGlobal = true;
|
||||
def.setBlockDefinition(context);
|
||||
def.setBlockLabel(label);
|
||||
ide.stage.globalBlocks.push(def);
|
||||
|
||||
// make sure the spec is unique
|
||||
while (rcvr.doubleDefinitionsFor(def).length > 0) {
|
||||
def.spec += (' (2)');
|
||||
}
|
||||
|
||||
// update the IDE
|
||||
ide.flushPaletteCache();
|
||||
ide.categories.refreshEmpty();
|
||||
ide.refreshPalette();
|
||||
ide.recordUnsavedChanges();
|
||||
return def.blockInstance().reify();
|
||||
};
|
||||
|
||||
Process.prototype.reportAttributeOf = function (attribute, name) {
|
||||
// hyper-dyadic
|
||||
// note: specifying strings in the left input only accesses
|
||||
|
|
Ładowanie…
Reference in New Issue