kopia lustrzana https://github.com/backface/turtlestitch
roll-back double-pointer container cache for methods
rodzic
ab03c81423
commit
4db428b65c
60
blocks.js
60
blocks.js
|
@ -150,7 +150,7 @@ CustomCommandBlockMorph*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.blocks = '2017-February-16';
|
||||
modules.blocks = '2017-March-01';
|
||||
|
||||
var SyntaxElementMorph;
|
||||
var BlockMorph;
|
||||
|
@ -571,14 +571,14 @@ SyntaxElementMorph.prototype.revertToDefaultInput = function (arg, noValues) {
|
|||
if (deflt instanceof InputSlotMorph) {
|
||||
deflt.setChoices.apply(
|
||||
deflt,
|
||||
this.definition.value.inputOptionsOfIdx(inp)
|
||||
this.definition.inputOptionsOfIdx(inp)
|
||||
);
|
||||
}
|
||||
if (deflt instanceof InputSlotMorph ||
|
||||
(deflt instanceof BooleanSlotMorph)
|
||||
) {
|
||||
deflt.setContents(
|
||||
this.definition.value.defaultValueOfInputIdx(inp)
|
||||
this.definition.defaultValueOfInputIdx(inp)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -696,13 +696,10 @@ SyntaxElementMorph.prototype.refactorVarInStack = function (
|
|||
}
|
||||
|
||||
if (this instanceof CustomCommandBlockMorph
|
||||
&& this.definition.value.body
|
||||
&& isNil(this.definition.value.declarations[oldName])
|
||||
&& !contains(this.definition.value.variableNames, oldName)) {
|
||||
this.definition.value.body.expression.refactorVarInStack(
|
||||
oldName,
|
||||
newName
|
||||
);
|
||||
&& this.definition.body
|
||||
&& isNil(this.definition.declarations[oldName])
|
||||
&& !contains(this.definition.variableNames, oldName)) {
|
||||
this.definition.body.expression.refactorVarInStack(oldName, newName);
|
||||
}
|
||||
|
||||
this.inputs().forEach(function (input) {
|
||||
|
@ -1546,7 +1543,7 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
|
|||
// has issues when loading costumes (asynchronously)
|
||||
// commented out for now
|
||||
|
||||
var rcvr = this.definition.value.receiver || this.receiver(),
|
||||
var rcvr = this.definition.receiver || this.receiver(),
|
||||
id = spec.slice(1),
|
||||
cst;
|
||||
if (!rcvr) {return this.labelPart('%stop'); }
|
||||
|
@ -2303,7 +2300,7 @@ BlockMorph.prototype.setSpec = function (spec, silently) {
|
|||
if (part instanceof InputSlotMorph && myself.definition) {
|
||||
part.setChoices.apply(
|
||||
part,
|
||||
myself.definition.value.inputOptionsOfIdx(inputIdx)
|
||||
myself.definition.inputOptionsOfIdx(inputIdx)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -2887,7 +2884,7 @@ BlockMorph.prototype.showHelp = function () {
|
|||
block,
|
||||
isCustomBlock = this.selector === 'evaluateCustomBlock',
|
||||
spec = isCustomBlock ?
|
||||
this.definition.value.helpSpec() : this.selector,
|
||||
this.definition.helpSpec() : this.selector,
|
||||
ctx;
|
||||
|
||||
if (!ide) {
|
||||
|
@ -2909,10 +2906,10 @@ BlockMorph.prototype.showHelp = function () {
|
|||
);
|
||||
};
|
||||
|
||||
if (isCustomBlock && this.definition.value.comment) {
|
||||
if (isCustomBlock && this.definition.comment) {
|
||||
block = this.fullCopy();
|
||||
block.addShadow();
|
||||
comment = this.definition.value.comment.fullCopy();
|
||||
comment = this.definition.comment.fullCopy();
|
||||
comment.contents.parse();
|
||||
help = '';
|
||||
comment.contents.lines.forEach(function (line) {
|
||||
|
@ -2960,7 +2957,7 @@ BlockMorph.prototype.mapToHeader = function () {
|
|||
this,
|
||||
function (code) {
|
||||
if (key === 'evaluateCustomBlock') {
|
||||
myself.definition.value.codeHeader = code;
|
||||
myself.definition.codeHeader = code;
|
||||
} else {
|
||||
StageMorph.prototype.codeHeaders[key] = code;
|
||||
}
|
||||
|
@ -2968,7 +2965,7 @@ BlockMorph.prototype.mapToHeader = function () {
|
|||
this
|
||||
).promptCode(
|
||||
'Header mapping',
|
||||
key === 'evaluateCustomBlock' ? this.definition.value.codeHeader || ''
|
||||
key === 'evaluateCustomBlock' ? this.definition.codeHeader || ''
|
||||
: StageMorph.prototype.codeHeaders[key] || '',
|
||||
this.world(),
|
||||
pic,
|
||||
|
@ -2989,7 +2986,7 @@ BlockMorph.prototype.mapToCode = function () {
|
|||
this,
|
||||
function (code) {
|
||||
if (key === 'evaluateCustomBlock') {
|
||||
myself.definition.value.codeMapping = code;
|
||||
myself.definition.codeMapping = code;
|
||||
} else {
|
||||
StageMorph.prototype.codeMappings[key] = code;
|
||||
}
|
||||
|
@ -2997,7 +2994,7 @@ BlockMorph.prototype.mapToCode = function () {
|
|||
this
|
||||
).promptCode(
|
||||
'Code mapping',
|
||||
key === 'evaluateCustomBlock' ? this.definition.value.codeMapping || ''
|
||||
key === 'evaluateCustomBlock' ? this.definition.codeMapping || ''
|
||||
: StageMorph.prototype.codeMappings[key] || '',
|
||||
this.world(),
|
||||
pic,
|
||||
|
@ -3013,7 +3010,7 @@ BlockMorph.prototype.mapHeader = function (aString, key) {
|
|||
'reify' : this.selector;
|
||||
if (aString) {
|
||||
if (this.definition) { // custom block
|
||||
this.definition.value.codeHeader = aString;
|
||||
this.definition.codeHeader = aString;
|
||||
} else {
|
||||
StageMorph.prototype.codeHeaders[sel] = aString;
|
||||
}
|
||||
|
@ -3026,7 +3023,7 @@ BlockMorph.prototype.mapCode = function (aString, key) {
|
|||
'reify' : this.selector;
|
||||
if (aString) {
|
||||
if (this.definition) { // custom block
|
||||
this.definition.value.codeMapping = aString;
|
||||
this.definition.codeMapping = aString;
|
||||
} else {
|
||||
StageMorph.prototype.codeMappings[sel] = aString;
|
||||
}
|
||||
|
@ -3044,24 +3041,22 @@ BlockMorph.prototype.mappedCode = function (definitions) {
|
|||
headerLines,
|
||||
body,
|
||||
bodyLines,
|
||||
defKey = this.definition ? this.definition.value.spec : key,
|
||||
defKey = this.definition ? this.definition.spec : key,
|
||||
defs = definitions || {},
|
||||
parts = [];
|
||||
code = key === 'reportGetVar' ? this.blockSpec
|
||||
: this.definition ? this.definition.value.codeMapping || ''
|
||||
: this.definition ? this.definition.codeMapping || ''
|
||||
: StageMorph.prototype.codeMappings[key] || '';
|
||||
|
||||
// map header
|
||||
if (key !== 'reportGetVar' && !defs.hasOwnProperty(defKey)) {
|
||||
defs[defKey] = null; // create the property for recursive definitions
|
||||
if (this.definition) {
|
||||
header = this.definition.value.codeHeader || '';
|
||||
header = this.definition.codeHeader || '';
|
||||
if (header.indexOf('<body') !== -1) { // replace with def mapping
|
||||
body = '';
|
||||
if (this.definition.value.body) {
|
||||
body = this.definition.value.body.expression.mappedCode(
|
||||
defs
|
||||
);
|
||||
if (this.definition.body) {
|
||||
body = this.definition.body.expression.mappedCode(defs);
|
||||
}
|
||||
bodyLines = body.split('\n');
|
||||
headerLines = header.split('\n');
|
||||
|
@ -3133,9 +3128,8 @@ BlockMorph.prototype.mappedCode = function (definitions) {
|
|||
};
|
||||
|
||||
BlockMorph.prototype.codeDefinitionHeader = function () {
|
||||
var block = this.definition ?
|
||||
new PrototypeHatBlockMorph(this.definition.value)
|
||||
: SpriteMorph.prototype.blockForSelector(this.selector),
|
||||
var block = this.definition ? new PrototypeHatBlockMorph(this.definition)
|
||||
: SpriteMorph.prototype.blockForSelector(this.selector),
|
||||
hat = new HatBlockMorph(),
|
||||
count = 1;
|
||||
|
||||
|
@ -3156,7 +3150,7 @@ BlockMorph.prototype.codeDefinitionHeader = function () {
|
|||
};
|
||||
|
||||
BlockMorph.prototype.codeMappingHeader = function () {
|
||||
var block = this.definition ? this.definition.value.blockInstance()
|
||||
var block = this.definition ? this.definition.blockInstance()
|
||||
: SpriteMorph.prototype.blockForSelector(this.selector),
|
||||
hat = new HatBlockMorph(),
|
||||
count = 1;
|
||||
|
@ -3683,7 +3677,7 @@ BlockMorph.prototype.reactToTemplateCopy = function () {
|
|||
|
||||
BlockMorph.prototype.hasBlockVars = function () {
|
||||
return this.anyChild(function (any) {
|
||||
return any.definition && any.definition.value.variableNames.length;
|
||||
return any.definition && any.definition.variableNames.length;
|
||||
});
|
||||
};
|
||||
|
||||
|
|
65
byob.js
65
byob.js
|
@ -108,7 +108,7 @@ BooleanSlotMorph*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.byob = '2017-February-16';
|
||||
modules.byob = '2017-March-01';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -373,7 +373,7 @@ CustomBlockDefinition.prototype.isDirectlyRecursive = function () {
|
|||
function (morph) {
|
||||
return morph instanceof BlockMorph &&
|
||||
morph.definition &&
|
||||
morph.definition.value.spec === myspec;
|
||||
morph.definition.spec === myspec;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -445,7 +445,7 @@ function CustomCommandBlockMorph(definition, isProto) {
|
|||
}
|
||||
|
||||
CustomCommandBlockMorph.prototype.init = function (definition, isProto) {
|
||||
this.definition = new Variable(definition); // mandatory
|
||||
this.definition = definition; // mandatory
|
||||
this.isPrototype = isProto || false; // optional
|
||||
CustomCommandBlockMorph.uber.init.call(this, true); // silently
|
||||
this.category = definition.category;
|
||||
|
@ -460,7 +460,7 @@ CustomCommandBlockMorph.prototype.init = function (definition, isProto) {
|
|||
CustomCommandBlockMorph.prototype.initializeVariables = function (oldVars) {
|
||||
var myself = this;
|
||||
this.variables = new VariableFrame();
|
||||
this.definition.value.variableNames.forEach(function (name) {
|
||||
this.definition.variableNames.forEach(function (name) {
|
||||
var v = oldVars ? oldVars[name] : null;
|
||||
myself.variables.addVar(
|
||||
name,
|
||||
|
@ -470,7 +470,7 @@ CustomCommandBlockMorph.prototype.initializeVariables = function (oldVars) {
|
|||
};
|
||||
|
||||
CustomCommandBlockMorph.prototype.refresh = function (silently) {
|
||||
var def = this.definition.value,
|
||||
var def = this.definition,
|
||||
newSpec = this.isPrototype ?
|
||||
def.spec : def.blockSpec(),
|
||||
oldInputs;
|
||||
|
@ -547,9 +547,7 @@ CustomCommandBlockMorph.prototype.refreshDefaults = function () {
|
|||
|
||||
inputs.forEach(function (inp) {
|
||||
if (inp instanceof InputSlotMorph || inp instanceof BooleanSlotMorph) {
|
||||
inp.setContents(
|
||||
myself.definition.value.defaultValueOfInputIdx(idx)
|
||||
);
|
||||
inp.setContents(myself.definition.defaultValueOfInputIdx(idx));
|
||||
}
|
||||
idx += 1;
|
||||
});
|
||||
|
@ -578,7 +576,7 @@ CustomCommandBlockMorph.prototype.refreshPrototype = function () {
|
|||
if (part.fragment.type) { // marked as input, take label as is
|
||||
frags.push(part.fragment);
|
||||
} else { // not an input, devide into several non-input fragments
|
||||
words = myself.definition.value.parseSpec(
|
||||
words = myself.definition.parseSpec(
|
||||
part.fragment.labelString
|
||||
);
|
||||
words.forEach(function (word) {
|
||||
|
@ -599,7 +597,7 @@ CustomCommandBlockMorph.prototype.refreshPrototype = function () {
|
|||
if (this instanceof CustomCommandBlockMorph
|
||||
&& ((hat.type === 'reporter') || (hat.type === 'predicate'))) {
|
||||
myself = new CustomReporterBlockMorph(
|
||||
this.definition.value,
|
||||
this.definition,
|
||||
hat.type === 'predicate',
|
||||
true
|
||||
);
|
||||
|
@ -607,7 +605,7 @@ CustomCommandBlockMorph.prototype.refreshPrototype = function () {
|
|||
} else if (this instanceof CustomReporterBlockMorph) {
|
||||
if (hat.type === 'command') {
|
||||
myself = new CustomCommandBlockMorph(
|
||||
this.definition.value,
|
||||
this.definition,
|
||||
true
|
||||
);
|
||||
hat.silentReplaceInput(this, myself);
|
||||
|
@ -725,7 +723,7 @@ CustomCommandBlockMorph.prototype.parseSpec = function (spec) {
|
|||
if (!this.isPrototype) {
|
||||
return CustomCommandBlockMorph.uber.parseSpec.call(this, spec);
|
||||
}
|
||||
return this.definition.value.parseSpec.call(this, spec);
|
||||
return this.definition.parseSpec.call(this, spec);
|
||||
};
|
||||
|
||||
CustomCommandBlockMorph.prototype.mouseClickLeft = function () {
|
||||
|
@ -739,7 +737,7 @@ CustomCommandBlockMorph.prototype.edit = function () {
|
|||
var myself = this, editor, block, hat, rcvr;
|
||||
|
||||
if (this.isPrototype) {
|
||||
block = this.definition.value.blockInstance();
|
||||
block = this.definition.blockInstance();
|
||||
block.addShadow();
|
||||
hat = this.parentThatIsA(PrototypeHatBlockMorph);
|
||||
new BlockDialogMorph(
|
||||
|
@ -767,7 +765,7 @@ CustomCommandBlockMorph.prototype.edit = function () {
|
|||
/* // under construction, commented out for now
|
||||
if (rcvr && contains(
|
||||
Object.keys(rcvr.inheritedBlocks()),
|
||||
this.definition.value.blockSpec()
|
||||
this.definition.blockSpec()
|
||||
)
|
||||
) {
|
||||
this.duplicateBlockDefinition();
|
||||
|
@ -776,7 +774,7 @@ CustomCommandBlockMorph.prototype.edit = function () {
|
|||
*/
|
||||
|
||||
Morph.prototype.trackChanges = false;
|
||||
editor = new BlockEditorMorph(this.definition.value, rcvr);
|
||||
editor = new BlockEditorMorph(this.definition, rcvr);
|
||||
editor.popUp();
|
||||
Morph.prototype.trackChanges = true;
|
||||
editor.changed();
|
||||
|
@ -824,7 +822,7 @@ CustomCommandBlockMorph.prototype.attachTargets = function () {
|
|||
CustomCommandBlockMorph.prototype.isInUse = function () {
|
||||
// answer true if an instance of my definition is found
|
||||
// in any of my receiver's scripts or block definitions
|
||||
var def = this.definition.value,
|
||||
var def = this.definition,
|
||||
ide = this.receiver().parentThatIsA(IDE_Morph);
|
||||
if (def.isGlobal && ide) {
|
||||
return ide.sprites.asArray().concat([ide.stage]).some(
|
||||
|
@ -941,7 +939,7 @@ CustomCommandBlockMorph.prototype.userMenu = function () {
|
|||
};
|
||||
|
||||
CustomCommandBlockMorph.prototype.exportBlockDefinition = function () {
|
||||
var xml = new SnapSerializer().serialize(this.definition.value),
|
||||
var xml = new SnapSerializer().serialize(this.definition),
|
||||
ide = this.parentThatIsA(IDE_Morph);
|
||||
|
||||
ide.saveXMLAs(xml, this.spec);
|
||||
|
@ -949,9 +947,9 @@ CustomCommandBlockMorph.prototype.exportBlockDefinition = function () {
|
|||
|
||||
CustomCommandBlockMorph.prototype.duplicateBlockDefinition = function () {
|
||||
var rcvr = this.receiver(),
|
||||
dup = this.definition.value.copyAndBindTo(rcvr),
|
||||
dup = this.definition.copyAndBindTo(rcvr),
|
||||
ide = this.parentThatIsA(IDE_Morph);
|
||||
if (this.definition.value.isGlobal) {
|
||||
if (this.definition.isGlobal) {
|
||||
ide.stage.globalBlocks.push(dup);
|
||||
} else {
|
||||
rcvr.customBlocks.push(dup);
|
||||
|
@ -966,21 +964,21 @@ CustomCommandBlockMorph.prototype.deleteBlockDefinition = function () {
|
|||
if (this.isPrototype) {
|
||||
return null; // under construction...
|
||||
}
|
||||
block = myself.definition.value.blockInstance();
|
||||
block = myself.definition.blockInstance();
|
||||
block.addShadow();
|
||||
new DialogBoxMorph(
|
||||
this,
|
||||
function () {
|
||||
rcvr = myself.receiver();
|
||||
rcvr.deleteAllBlockInstances(myself.definition.value);
|
||||
if (myself.definition.value.isGlobal) {
|
||||
rcvr.deleteAllBlockInstances(myself.definition);
|
||||
if (myself.definition.isGlobal) {
|
||||
stage = rcvr.parentThatIsA(StageMorph);
|
||||
idx = stage.globalBlocks.indexOf(myself.definition.value);
|
||||
idx = stage.globalBlocks.indexOf(myself.definition);
|
||||
if (idx !== -1) {
|
||||
stage.globalBlocks.splice(idx, 1);
|
||||
}
|
||||
} else {
|
||||
idx = rcvr.customBlocks.indexOf(myself.definition.value);
|
||||
idx = rcvr.customBlocks.indexOf(myself.definition);
|
||||
if (idx !== -1) {
|
||||
rcvr.customBlocks.splice(idx, 1);
|
||||
}
|
||||
|
@ -1003,9 +1001,6 @@ CustomCommandBlockMorph.prototype.deleteBlockDefinition = function () {
|
|||
// CustomCommandBlockMorph relabelling
|
||||
|
||||
CustomCommandBlockMorph.prototype.relabel = function (alternatives) {
|
||||
// +++ this needs tweaking for block inheritance
|
||||
// +++ and also so embeded blocks do not get lost
|
||||
// +++ -Jens
|
||||
var menu = new MenuMorph(this),
|
||||
oldInputs = this.inputs().map(
|
||||
function (each) {return each.fullCopy(); }
|
||||
|
@ -1019,7 +1014,7 @@ CustomCommandBlockMorph.prototype.relabel = function (alternatives) {
|
|||
menu.addItem(
|
||||
block,
|
||||
function () {
|
||||
myself.definition.value = def; // +++ needs tweaking for inheritance
|
||||
myself.definition = def;
|
||||
myself.refresh();
|
||||
}
|
||||
);
|
||||
|
@ -1036,8 +1031,8 @@ CustomCommandBlockMorph.prototype.alternatives = function () {
|
|||
allDefs = rcvr.customBlocks.concat(stage.globalBlocks),
|
||||
myself = this;
|
||||
return allDefs.filter(function (each) {
|
||||
return each !== myself.definition.value &&
|
||||
each.type === myself.definition.value.type;
|
||||
return each !== myself.definition &&
|
||||
each.type === myself.definition.type;
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -1060,7 +1055,7 @@ CustomReporterBlockMorph.prototype.init = function (
|
|||
isPredicate,
|
||||
isProto
|
||||
) {
|
||||
this.definition = new Variable(definition); // mandatory
|
||||
this.definition = definition; // mandatory
|
||||
this.isPrototype = isProto || false; // optional
|
||||
CustomReporterBlockMorph.uber.init.call(this, isPredicate, true); // sil.
|
||||
this.category = definition.category;
|
||||
|
@ -1078,7 +1073,7 @@ CustomReporterBlockMorph.prototype.initializeVariables =
|
|||
CustomReporterBlockMorph.prototype.refresh = function () {
|
||||
CustomCommandBlockMorph.prototype.refresh.call(this, true);
|
||||
if (!this.isPrototype) {
|
||||
this.isPredicate = (this.definition.value.type === 'predicate');
|
||||
this.isPredicate = (this.definition.type === 'predicate');
|
||||
}
|
||||
if (this.parent instanceof SyntaxElementMorph) {
|
||||
this.parent.cachedInputs = null;
|
||||
|
@ -1950,13 +1945,11 @@ BlockEditorMorph.prototype.close = function () {
|
|||
block = detect(
|
||||
this.body.contents.allChildren(),
|
||||
function (morph) {
|
||||
return morph.definition &&
|
||||
morph.definition.value && // exclude the prototype
|
||||
!morph.definition.value.isGlobal;
|
||||
return morph.definition && !morph.definition.isGlobal;
|
||||
}
|
||||
);
|
||||
if (block) {
|
||||
block = block.definition.value.blockInstance();
|
||||
block = block.definition.blockInstance();
|
||||
block.addShadow();
|
||||
new DialogBoxMorph().inform(
|
||||
'Local Block(s) in Global Definition',
|
||||
|
|
4
gui.js
4
gui.js
|
@ -74,7 +74,7 @@ isRetinaSupported, SliderMorph, Animation, BooleanSlotMorph*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.gui = '2017-February-16';
|
||||
modules.gui = '2017-March-01';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -6972,7 +6972,7 @@ SpriteIconMorph.prototype.copyStack = function (block) {
|
|||
// delete all custom blocks pointing to local definitions
|
||||
// under construction...
|
||||
dup.allChildren().forEach(function (morph) {
|
||||
if (morph.definition && !morph.definition.value.isGlobal) {
|
||||
if (morph.definition && !morph.definition.isGlobal) {
|
||||
morph.deleteBlock();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -3384,3 +3384,4 @@ Fixes:
|
|||
170301
|
||||
------
|
||||
* Objects: experiment with new dynamic method (cache) updating
|
||||
* Objects, Blocks, BYOB, Store, Threads, GUI: roll-back double-pointer container cache for methods
|
||||
|
|
86
objects.js
86
objects.js
|
@ -80,7 +80,7 @@ document, isNaN, isString, newCanvas, nop, parseFloat, radians, window,
|
|||
modules, IDE_Morph, VariableDialogMorph, HTMLCanvasElement, Context, List,
|
||||
SpeechBubbleMorph, RingMorph, isNil, FileReader, TableDialogMorph,
|
||||
BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
|
||||
TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, Variable*/
|
||||
TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph*/
|
||||
|
||||
modules.objects = '2017-March-01';
|
||||
|
||||
|
@ -1375,7 +1375,6 @@ SpriteMorph.prototype.init = function (globals) {
|
|||
|
||||
// sprite inheritance
|
||||
this.exemplar = null;
|
||||
this.methods = {}; // not to be serialized, blockSpec: Variable[definition]
|
||||
|
||||
SpriteMorph.uber.init.call(this);
|
||||
|
||||
|
@ -1409,7 +1408,7 @@ SpriteMorph.prototype.fullCopy = function (forClone) {
|
|||
cb = def.copyAndBindTo(c);
|
||||
c.customBlocks.push(cb);
|
||||
c.allBlockInstances(def).forEach(function (block) {
|
||||
block.definition.value = cb; // +++ might have to be tweaked, -Jens
|
||||
block.definition = cb;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -4638,7 +4637,7 @@ SpriteMorph.prototype.allBlockInstances = function (definition) {
|
|||
stage.globalBlocks.forEach(function (def) {
|
||||
if (def.body) {
|
||||
def.body.expression.allChildren().forEach(function (c) {
|
||||
if (c.definition && (c.definition.value === definition)) {
|
||||
if (c.definition && (c.definition === definition)) {
|
||||
inDefinitions.push(c);
|
||||
}
|
||||
});
|
||||
|
@ -4653,14 +4652,14 @@ SpriteMorph.prototype.allLocalBlockInstances = function (definition) {
|
|||
var inScripts, inDefinitions, inBlockEditors, inPalette, result;
|
||||
|
||||
inScripts = this.scripts.allChildren().filter(function (c) {
|
||||
return c.definition && (c.definition.value === definition);
|
||||
return c.definition && (c.definition === definition);
|
||||
});
|
||||
|
||||
inDefinitions = [];
|
||||
this.customBlocks.forEach(function (def) {
|
||||
if (def.body) {
|
||||
def.body.expression.allChildren().forEach(function (c) {
|
||||
if (c.definition && (c.definition.value === definition)) {
|
||||
if (c.definition && (c.definition === definition)) {
|
||||
inDefinitions.push(c);
|
||||
}
|
||||
});
|
||||
|
@ -4688,8 +4687,7 @@ SpriteMorph.prototype.allEditorBlockInstances = function (definition) {
|
|||
morph.body.contents.allChildren().forEach(function (block) {
|
||||
if (!block.isPrototype
|
||||
&& !(block instanceof PrototypeHatBlockMorph)
|
||||
&& block.definition
|
||||
&& (block.definition.value === definition)) {
|
||||
&& (block.definition === definition)) {
|
||||
inBlockEditors.push(block);
|
||||
}
|
||||
});
|
||||
|
@ -4705,8 +4703,7 @@ SpriteMorph.prototype.paletteBlockInstance = function (definition) {
|
|||
return detect(
|
||||
ide.palette.contents.children,
|
||||
function (block) {
|
||||
return block.definition &&
|
||||
(block.definition.value === definition);
|
||||
return block.definition === definition;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -4721,7 +4718,7 @@ SpriteMorph.prototype.usesBlockInstance = function (
|
|||
inScripts = detect(
|
||||
this.scripts.allChildren(),
|
||||
function (c) {
|
||||
return c.definition && (c.definition.value === definition);
|
||||
return c.definition && (c.definition === definition);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -4735,9 +4732,7 @@ SpriteMorph.prototype.usesBlockInstance = function (
|
|||
if (skipBlocks && contains(skipBlocks, def)) {return; }
|
||||
if (def.body) {
|
||||
def.body.expression.allChildren().forEach(function (c) {
|
||||
if (c.definition &&
|
||||
(c.definition.value === definition)
|
||||
) {
|
||||
if (c.definition && (c.definition === definition)) {
|
||||
inDefinitions.push(c);
|
||||
}
|
||||
});
|
||||
|
@ -4751,7 +4746,7 @@ SpriteMorph.prototype.usesBlockInstance = function (
|
|||
this.customBlocks.forEach(function (def) {
|
||||
if (def.body) {
|
||||
def.body.expression.allChildren().forEach(function (c) {
|
||||
if (c.definition && (c.definition.value === definition)) {
|
||||
if (c.definition && (c.definition === definition)) {
|
||||
inDefinitions.push(c);
|
||||
}
|
||||
});
|
||||
|
@ -4787,7 +4782,7 @@ SpriteMorph.prototype.replaceDoubleDefinitionsFor = function (definition) {
|
|||
ide;
|
||||
doubles.forEach(function (double) {
|
||||
myself.allBlockInstances(double).forEach(function (block) {
|
||||
block.definition.value = definition; // might have to be tweaked +++
|
||||
block.definition = definition;
|
||||
block.refresh();
|
||||
});
|
||||
});
|
||||
|
@ -4936,52 +4931,18 @@ SpriteMorph.prototype.hasSpriteVariable = function (varName) {
|
|||
};
|
||||
|
||||
// SpriteMorph inheritance - custom blocks
|
||||
// +++ under construction - remember to propagate to StageMorph
|
||||
// under construction
|
||||
|
||||
SpriteMorph.prototype.updateMethod = function (aDefinition, spec) {
|
||||
var slot;
|
||||
if (isNil(spec)) {
|
||||
spec = aDefinition.blockSpec();
|
||||
}
|
||||
|
||||
// sanity checks, to be removed after thorough testing
|
||||
if (aDefinition.isGlobal) {
|
||||
throw new Error('cannot update methods with global block');
|
||||
}
|
||||
if (spec === '') {
|
||||
throw new Error('missing spec in definition update');
|
||||
}
|
||||
|
||||
slot = this.methods[spec];
|
||||
if (slot instanceof Variable) {
|
||||
slot.value = aDefinition;
|
||||
} else {
|
||||
slot = new Variable(aDefinition);
|
||||
this.methods[spec] = slot;
|
||||
}
|
||||
return slot;
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.updateAllMethods = function () {
|
||||
var all = this.allBlocks(),
|
||||
methods = this.methods,
|
||||
obsolete;
|
||||
|
||||
Object.keys(all).forEach(function (spec) {
|
||||
this.updateMethod(all[spec], spec);
|
||||
});
|
||||
|
||||
// remove unused entries
|
||||
obsolete = Object.keys(methods).filter(function (spec) {
|
||||
return !contains(Object.keys(all), spec);
|
||||
});
|
||||
obsolete.forEach(function (spec) {
|
||||
methods.delete(spec);
|
||||
/*
|
||||
SpriteMorph.prototype.ownBlocks = function () {
|
||||
var dict = {};
|
||||
this.customBlocks.forEach(function (def) {
|
||||
dict[def.blockSpec()] = def;
|
||||
});
|
||||
return dict;
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.allBlocks = function (valuesOnly) {
|
||||
// private
|
||||
var dict = {};
|
||||
this.allExemplars().reverse().forEach(function (sprite) {
|
||||
sprite.customBlocks.forEach(function (def) {
|
||||
|
@ -4994,17 +4955,7 @@ SpriteMorph.prototype.allBlocks = function (valuesOnly) {
|
|||
return dict;
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.ownBlocks = function () {
|
||||
// private
|
||||
var dict = {};
|
||||
this.customBlocks.forEach(function (def) {
|
||||
dict[def.blockSpec()] = def;
|
||||
});
|
||||
return dict;
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.inheritedBlocks = function (valuesOnly) {
|
||||
// private
|
||||
var dict = {},
|
||||
own = Object.keys(this.ownBlocks()),
|
||||
others = this.allExemplars().reverse();
|
||||
|
@ -5022,6 +4973,7 @@ SpriteMorph.prototype.inheritedBlocks = function (valuesOnly) {
|
|||
}
|
||||
return dict;
|
||||
};
|
||||
*/
|
||||
|
||||
// SpriteMorph thumbnail
|
||||
|
||||
|
|
14
store.js
14
store.js
|
@ -61,7 +61,7 @@ normalizeCanvas, contains*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.store = '2017-February-16';
|
||||
modules.store = '2017-March-01';
|
||||
|
||||
|
||||
// XML_Serializer ///////////////////////////////////////////////////////
|
||||
|
@ -1827,23 +1827,23 @@ ReporterBlockMorph.prototype.toScriptXML = function (
|
|||
};
|
||||
|
||||
CustomCommandBlockMorph.prototype.toBlockXML = function (serializer) {
|
||||
var scope = this.definition.value.isGlobal ? undefined
|
||||
: this.definition.value.receiver.name;
|
||||
var scope = this.definition.isGlobal ? undefined
|
||||
: this.definition.receiver.name;
|
||||
return serializer.format(
|
||||
'<custom-block s="@"%>%%%%</custom-block>',
|
||||
this.blockSpec,
|
||||
this.definition.value.isGlobal ?
|
||||
this.definition.isGlobal ?
|
||||
'' : serializer.format(' scope="@"', scope),
|
||||
serializer.store(this.inputs()),
|
||||
this.definition.value.variableNames.length ?
|
||||
this.definition.variableNames.length ?
|
||||
'<variables>' +
|
||||
this.variables.toXML(serializer) +
|
||||
'</variables>'
|
||||
: '',
|
||||
this.comment ? this.comment.toXML(serializer) : '',
|
||||
scope && !this.definition.value.receiver[serializer.idProperty] ?
|
||||
scope && !this.definition.receiver[serializer.idProperty] ?
|
||||
'<receiver>' +
|
||||
serializer.store(this.definition.value.receiver) +
|
||||
serializer.store(this.definition.receiver) +
|
||||
'</receiver>'
|
||||
: ''
|
||||
);
|
||||
|
|
13
threads.js
13
threads.js
|
@ -61,7 +61,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy,
|
|||
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph,
|
||||
TableFrameMorph, ColorSlotMorph, isSnapObject*/
|
||||
|
||||
modules.threads = '2017-February-16';
|
||||
modules.threads = '2017-March-01';
|
||||
|
||||
var ThreadManager;
|
||||
var Process;
|
||||
|
@ -1269,8 +1269,8 @@ Process.prototype.runContinuation = function (aContext, args) {
|
|||
|
||||
Process.prototype.evaluateCustomBlock = function () {
|
||||
var caller = this.context.parentContext,
|
||||
context = this.context.expression.definition.value.body,
|
||||
declarations = this.context.expression.definition.value.declarations,
|
||||
context = this.context.expression.definition.body,
|
||||
declarations = this.context.expression.definition.declarations,
|
||||
args = new List(this.context.inputs),
|
||||
parms = args.asArray(),
|
||||
runnable,
|
||||
|
@ -1290,7 +1290,7 @@ Process.prototype.evaluateCustomBlock = function () {
|
|||
// only splice in block vars if any are defined, because block vars
|
||||
// can cause race conditions in global block definitions that
|
||||
// access sprite-local variables at the same time.
|
||||
if (this.context.expression.definition.value.variableNames.length) {
|
||||
if (this.context.expression.definition.variableNames.length) {
|
||||
this.context.expression.variables.parentFrame = outer.receiver ?
|
||||
outer.receiver.variables : null;
|
||||
} else {
|
||||
|
@ -1329,7 +1329,7 @@ Process.prototype.evaluateCustomBlock = function () {
|
|||
}
|
||||
|
||||
// tag return target
|
||||
if (this.context.expression.definition.value.type !== 'command') {
|
||||
if (this.context.expression.definition.type !== 'command') {
|
||||
if (caller) {
|
||||
// tag caller, so "report" can catch it later
|
||||
caller.tag = 'exit';
|
||||
|
@ -1361,8 +1361,7 @@ Process.prototype.evaluateCustomBlock = function () {
|
|||
}
|
||||
// yield commands unless explicitly "warped" or directly recursive
|
||||
if (!this.isAtomic &&
|
||||
this.context.expression.definition.value.isDirectlyRecursive()
|
||||
) {
|
||||
this.context.expression.definition.isDirectlyRecursive()) {
|
||||
this.readyToYield = true;
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue