kopia lustrzana https://github.com/backface/turtlestitch
let clones share the orginal’s scripts without shallow-copying them
rodzic
cc47a6fb5a
commit
eea1d08c82
160
blocks.js
160
blocks.js
|
@ -150,7 +150,7 @@ CustomCommandBlockMorph*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.blocks = '2017-May-12';
|
||||
modules.blocks = '2017-May-30';
|
||||
|
||||
var SyntaxElementMorph;
|
||||
var BlockMorph;
|
||||
|
@ -570,7 +570,7 @@ SyntaxElementMorph.prototype.revertToDefaultInput = function (arg, noValues) {
|
|||
deflt = this.labelPart(this.parseSpec(this.blockSpec)[idx]);
|
||||
if (this.isCustomBlock) {
|
||||
def = this.isGlobal ? this.definition
|
||||
: this.receiver().getMethod(this.blockSpec);
|
||||
: this.scriptTarget().getMethod(this.blockSpec);
|
||||
if (deflt instanceof InputSlotMorph) {
|
||||
deflt.setChoices.apply(
|
||||
deflt,
|
||||
|
@ -636,7 +636,7 @@ SyntaxElementMorph.prototype.getVarNamesDict = function () {
|
|||
if (!block) {
|
||||
return {};
|
||||
}
|
||||
rcvr = block.receiver();
|
||||
rcvr = block.scriptTarget();
|
||||
block.allParents().forEach(function (morph) {
|
||||
if (morph instanceof PrototypeHatBlockMorph) {
|
||||
tempVars.push.apply(
|
||||
|
@ -1546,7 +1546,7 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
|
|||
// has issues when loading costumes (asynchronously)
|
||||
// commented out for now
|
||||
|
||||
var rcvr = this.definition.receiver || this.receiver(),
|
||||
var rcvr = this.definition.receiver || this.scriptTarget(),
|
||||
id = spec.slice(1),
|
||||
cst;
|
||||
if (!rcvr) {return this.labelPart('%stop'); }
|
||||
|
@ -1888,7 +1888,7 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic) {
|
|||
if ((value === undefined) || !wrrld || !this.receiver) {
|
||||
return null;
|
||||
}
|
||||
rcvr = this.receiver();
|
||||
rcvr = this.scriptTarget();
|
||||
if (value instanceof ListWatcherMorph) {
|
||||
morphToShow = value;
|
||||
morphToShow.update(true);
|
||||
|
@ -2053,7 +2053,7 @@ SyntaxElementMorph.prototype.endLayout = function () {
|
|||
accessors are:
|
||||
|
||||
selector - (string) name of method to be triggered
|
||||
receiver() - answer the object (sprite) to which I apply
|
||||
scriptTarget() - answer the object (sprite) to which I apply
|
||||
inputs() - answer an array with my arg slots and nested reporters
|
||||
defaults - an optional Array containing default input values
|
||||
topBlock() - answer the top block of the stack I'm attached to
|
||||
|
@ -2204,16 +2204,23 @@ BlockMorph.prototype.init = function (silently) {
|
|||
this.cachedInputs = null;
|
||||
};
|
||||
|
||||
BlockMorph.prototype.receiver = function () {
|
||||
// answer the object to which I apply (whose method I represent)
|
||||
var up = this.parent;
|
||||
while (!!up) {
|
||||
if (up.owner) {
|
||||
return up.owner;
|
||||
}
|
||||
up = up.parent;
|
||||
BlockMorph.prototype.scriptTarget = function () {
|
||||
// answer the sprite or stage that this block acts on,
|
||||
// if the user clicks on it.
|
||||
// NOTE: since scripts can be shared by more than a single sprite
|
||||
// this method only gives the desired result within the context of
|
||||
// the user actively clicking on a block inside the IDE
|
||||
// there is no direct relationship between a block and a sprite.
|
||||
var scripts = this.parentThatIsA(ScriptsMorph),
|
||||
ide;
|
||||
if (scripts) {
|
||||
return scripts.scriptTarget();
|
||||
}
|
||||
return null;
|
||||
ide = this.parentThatIsA(IDE_Morph);
|
||||
if (ide) {
|
||||
return ide.currentSprite;
|
||||
}
|
||||
throw new Error('script target cannot be found for orphaned block');
|
||||
};
|
||||
|
||||
BlockMorph.prototype.toString = function () {
|
||||
|
@ -2461,7 +2468,7 @@ BlockMorph.prototype.userMenu = function () {
|
|||
|
||||
// allow toggling inheritable attributes
|
||||
if (StageMorph.prototype.enableInheritance) {
|
||||
rcvr = this.receiver();
|
||||
rcvr = this.scriptTarget();
|
||||
field = {
|
||||
xPosition: 'x position',
|
||||
yPosition: 'y position',
|
||||
|
@ -2695,7 +2702,7 @@ BlockMorph.prototype.isInheritedVariable = function () {
|
|||
(this.selector === 'reportGetVar') &&
|
||||
(this.parent instanceof FrameMorph)) {
|
||||
return contains(
|
||||
this.receiver().inheritedVariableNames(),
|
||||
this.scriptTarget().inheritedVariableNames(),
|
||||
this.blockSpec
|
||||
);
|
||||
}
|
||||
|
@ -2704,13 +2711,13 @@ BlockMorph.prototype.isInheritedVariable = function () {
|
|||
|
||||
BlockMorph.prototype.isTransientVariable = function () {
|
||||
// private - only for variable getter template inside the palette
|
||||
var varFrame = this.receiver().variables.silentFind(this.blockSpec);
|
||||
var varFrame = this.scriptTarget().variables.silentFind(this.blockSpec);
|
||||
return varFrame ? varFrame.vars[this.blockSpec].isTransient : false;
|
||||
};
|
||||
|
||||
BlockMorph.prototype.toggleTransientVariable = function () {
|
||||
// private - only for variable getter template inside the palette
|
||||
var varFrame = this.receiver().variables.silentFind(this.blockSpec);
|
||||
var varFrame = this.scriptTarget().variables.silentFind(this.blockSpec);
|
||||
if (!varFrame) {return; }
|
||||
varFrame.vars[this.blockSpec].isTransient =
|
||||
!(varFrame.vars[this.blockSpec].isTransient);
|
||||
|
@ -3212,7 +3219,7 @@ BlockMorph.prototype.refactorThisVar = function (justTheTemplate) {
|
|||
|
||||
var myself = this,
|
||||
oldName = this.blockSpec,
|
||||
receiver = this.receiver(),
|
||||
receiver = this.scriptTarget(),
|
||||
ide = this.parentThatIsA(IDE_Morph),
|
||||
stage = ide.stage,
|
||||
oldWatcher = receiver.findVariableWatcher(oldName),
|
||||
|
@ -3674,14 +3681,7 @@ BlockMorph.prototype.hasLabels = function () {
|
|||
|
||||
// BlockMorph copying
|
||||
|
||||
BlockMorph.prototype.fullCopy = function (forClone) {
|
||||
if (forClone) {
|
||||
if (this.hasBlockVars()) {
|
||||
forClone = false;
|
||||
} else {
|
||||
return copy(this);
|
||||
}
|
||||
}
|
||||
BlockMorph.prototype.fullCopy = function () {
|
||||
var ans = BlockMorph.uber.fullCopy.call(this);
|
||||
ans.removeHighlight();
|
||||
ans.isDraggable = true;
|
||||
|
@ -3721,7 +3721,7 @@ BlockMorph.prototype.hasBlockVars = function () {
|
|||
|
||||
BlockMorph.prototype.mouseClickLeft = function () {
|
||||
var top = this.topBlock(),
|
||||
receiver = top.receiver(),
|
||||
receiver = top.scriptTarget(),
|
||||
shiftClicked = this.world().currentKey === 16,
|
||||
stage;
|
||||
if (shiftClicked && !this.isTemplate) {
|
||||
|
@ -3733,7 +3733,7 @@ BlockMorph.prototype.mouseClickLeft = function () {
|
|||
if (receiver) {
|
||||
stage = receiver.parentThatIsA(StageMorph);
|
||||
if (stage) {
|
||||
stage.threads.toggleProcess(top);
|
||||
stage.threads.toggleProcess(top, receiver);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -3755,7 +3755,7 @@ BlockMorph.prototype.focus = function () {
|
|||
|
||||
BlockMorph.prototype.activeProcess = function () {
|
||||
var top = this.topBlock(),
|
||||
receiver = top.receiver(),
|
||||
receiver = top.scriptTarget(),
|
||||
stage;
|
||||
if (top instanceof PrototypeHatBlockMorph) {
|
||||
return null;
|
||||
|
@ -3763,7 +3763,7 @@ BlockMorph.prototype.activeProcess = function () {
|
|||
if (receiver) {
|
||||
stage = receiver.parentThatIsA(StageMorph);
|
||||
if (stage) {
|
||||
return stage.threads.findProcess(top);
|
||||
return stage.threads.findProcess(top, receiver);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -3908,10 +3908,16 @@ BlockMorph.prototype.destroy = function (justThis) {
|
|||
comment.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
/* +++ needs tweaking:
|
||||
// stop active process(es) for this block
|
||||
// for this we need access to the stage...
|
||||
|
||||
if ((!this.parent || !this.parent.topBlock)
|
||||
&& this.activeProcess()) {
|
||||
this.activeProcess().stop();
|
||||
}
|
||||
*/
|
||||
|
||||
BlockMorph.uber.destroy.call(this);
|
||||
};
|
||||
|
@ -3957,7 +3963,7 @@ BlockMorph.prototype.snap = function () {
|
|||
}
|
||||
// register generic hat blocks
|
||||
if (this.selector === 'receiveCondition') {
|
||||
receiver = top.receiver();
|
||||
receiver = top.scriptTarget();
|
||||
if (receiver) {
|
||||
stage = receiver.parentThatIsA(StageMorph);
|
||||
if (stage) {
|
||||
|
@ -5156,14 +5162,14 @@ ReporterBlockMorph.prototype.mouseClickLeft = function (pos) {
|
|||
|
||||
ReporterBlockMorph.prototype.exportResultPic = function () {
|
||||
var top = this.topBlock(),
|
||||
receiver = top.receiver(),
|
||||
receiver = top.scriptTarget(),
|
||||
stage;
|
||||
if (top !== this) {return; }
|
||||
if (receiver) {
|
||||
stage = receiver.parentThatIsA(StageMorph);
|
||||
if (stage) {
|
||||
stage.threads.stopProcess(top);
|
||||
stage.threads.startProcess(top, false, true);
|
||||
stage.threads.startProcess(top, receiver, false, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -5711,12 +5717,11 @@ ScriptsMorph.prototype.enableNestedAutoWrapping = true;
|
|||
|
||||
// ScriptsMorph instance creation:
|
||||
|
||||
function ScriptsMorph(owner) {
|
||||
this.init(owner);
|
||||
function ScriptsMorph() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
ScriptsMorph.prototype.init = function (owner) {
|
||||
this.owner = owner || null;
|
||||
ScriptsMorph.prototype.init = function () {
|
||||
this.feedbackColor = SyntaxElementMorph.prototype.feedbackColor;
|
||||
this.feedbackMorph = new BoxMorph();
|
||||
this.rejectsHats = false;
|
||||
|
@ -5744,7 +5749,7 @@ ScriptsMorph.prototype.init = function (owner) {
|
|||
|
||||
// ScriptsMorph deep copying:
|
||||
|
||||
ScriptsMorph.prototype.fullCopy = function (forClone) {
|
||||
ScriptsMorph.prototype.fullCopy = function () {
|
||||
var cpy = new ScriptsMorph(),
|
||||
pos = this.position(),
|
||||
child;
|
||||
|
@ -5753,21 +5758,17 @@ ScriptsMorph.prototype.fullCopy = function (forClone) {
|
|||
}
|
||||
this.children.forEach(function (morph) {
|
||||
if (!morph.block) { // omit anchored comments
|
||||
child = morph.fullCopy(forClone);
|
||||
child = morph.fullCopy();
|
||||
cpy.add(child);
|
||||
if (!forClone) {
|
||||
child.setPosition(morph.position().subtract(pos));
|
||||
if (child instanceof BlockMorph) {
|
||||
child.allComments().forEach(function (comment) {
|
||||
comment.align(child);
|
||||
});
|
||||
}
|
||||
child.setPosition(morph.position().subtract(pos));
|
||||
if (child instanceof BlockMorph) {
|
||||
child.allComments().forEach(function (comment) {
|
||||
comment.align(child);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!forClone) {
|
||||
cpy.adjustBounds();
|
||||
}
|
||||
cpy.adjustBounds();
|
||||
return cpy;
|
||||
};
|
||||
|
||||
|
@ -6073,7 +6074,7 @@ ScriptsMorph.prototype.userMenu = function () {
|
|||
shiftClicked = this.world().currentKey === 16,
|
||||
blockEditor,
|
||||
myself = this,
|
||||
obj = this.owner,
|
||||
obj = this.scriptTarget(),
|
||||
hasUndropQueue,
|
||||
stage = obj.parentThatIsA(StageMorph);
|
||||
|
||||
|
@ -6594,6 +6595,28 @@ ScriptsMorph.prototype.edit = function (pos) {
|
|||
this.focus.getFocus(world);
|
||||
};
|
||||
|
||||
// ScriptsMorph context - scripts target
|
||||
|
||||
ScriptsMorph.prototype.scriptTarget = function () {
|
||||
// answer the sprite or stage that this script editor acts on,
|
||||
// if the user clicks on a block.
|
||||
// NOTE: since scripts can be shared by more than a single sprite
|
||||
// this method only gives the desired result within the context of
|
||||
// the user actively clicking on a block inside the IDE
|
||||
// there is no direct relationship between a block or a scripts editor
|
||||
// and a sprite.
|
||||
var editor = this.parentThatIsA(IDE_Morph);
|
||||
if (editor) {
|
||||
return editor.currentSprite;
|
||||
}
|
||||
editor = this.parentThatIsA(BlockEditorMorph);
|
||||
if (editor) {
|
||||
return editor.target.currentSprite;
|
||||
}
|
||||
throw new Error('script target bannot be found for orphaned scripts');
|
||||
};
|
||||
|
||||
|
||||
// ArgMorph //////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
|
@ -6644,7 +6667,7 @@ ArgMorph.prototype.reactToSliderEdit = function () {
|
|||
block = this.parentThatIsA(BlockMorph);
|
||||
if (block) {
|
||||
top = block.topBlock();
|
||||
receiver = top.receiver();
|
||||
receiver = top.scriptTarget();
|
||||
if (top instanceof PrototypeHatBlockMorph) {
|
||||
return;
|
||||
}
|
||||
|
@ -6652,7 +6675,7 @@ ArgMorph.prototype.reactToSliderEdit = function () {
|
|||
stage = receiver.parentThatIsA(StageMorph);
|
||||
if (stage && (stage.isThreadSafe ||
|
||||
Process.prototype.enableSingleStepping)) {
|
||||
stage.threads.startProcess(top, stage.isThreadSafe);
|
||||
stage.threads.startProcess(top, receiver, stage.isThreadSafe);
|
||||
} else {
|
||||
top.mouseClickLeft();
|
||||
}
|
||||
|
@ -7944,7 +7967,7 @@ InputSlotMorph.prototype.menuFromDict = function (choices, noEmptyOption) {
|
|||
|
||||
InputSlotMorph.prototype.messagesMenu = function () {
|
||||
var dict = {},
|
||||
rcvr = this.parentThatIsA(BlockMorph).receiver(),
|
||||
rcvr = this.parentThatIsA(BlockMorph).scriptTarget(),
|
||||
stage = rcvr.parentThatIsA(StageMorph),
|
||||
myself = this,
|
||||
allNames = [];
|
||||
|
@ -7977,7 +8000,7 @@ InputSlotMorph.prototype.messagesMenu = function () {
|
|||
|
||||
InputSlotMorph.prototype.messagesReceivedMenu = function () {
|
||||
var dict = {'any message': ['any message']},
|
||||
rcvr = this.parentThatIsA(BlockMorph).receiver(),
|
||||
rcvr = this.parentThatIsA(BlockMorph).scriptTarget(),
|
||||
stage = rcvr.parentThatIsA(StageMorph),
|
||||
myself = this,
|
||||
allNames = [];
|
||||
|
@ -8012,7 +8035,7 @@ InputSlotMorph.prototype.collidablesMenu = function () {
|
|||
edge : ['edge'],
|
||||
'pen trails' : ['pen trails']
|
||||
},
|
||||
rcvr = this.parentThatIsA(BlockMorph).receiver(),
|
||||
rcvr = this.parentThatIsA(BlockMorph).scriptTarget(),
|
||||
stage = rcvr.parentThatIsA(StageMorph),
|
||||
allNames = [];
|
||||
|
||||
|
@ -8036,7 +8059,7 @@ InputSlotMorph.prototype.distancesMenu = function () {
|
|||
var dict = {
|
||||
'mouse-pointer' : ['mouse-pointer']
|
||||
},
|
||||
rcvr = this.parentThatIsA(BlockMorph).receiver(),
|
||||
rcvr = this.parentThatIsA(BlockMorph).scriptTarget(),
|
||||
stage = rcvr.parentThatIsA(StageMorph),
|
||||
allNames = [];
|
||||
|
||||
|
@ -8058,7 +8081,7 @@ InputSlotMorph.prototype.distancesMenu = function () {
|
|||
|
||||
InputSlotMorph.prototype.clonablesMenu = function () {
|
||||
var dict = {},
|
||||
rcvr = this.parentThatIsA(BlockMorph).receiver(),
|
||||
rcvr = this.parentThatIsA(BlockMorph).scriptTarget(),
|
||||
stage = rcvr.parentThatIsA(StageMorph),
|
||||
allNames = [];
|
||||
|
||||
|
@ -8080,7 +8103,7 @@ InputSlotMorph.prototype.clonablesMenu = function () {
|
|||
};
|
||||
|
||||
InputSlotMorph.prototype.objectsMenu = function () {
|
||||
var rcvr = this.parentThatIsA(BlockMorph).receiver(),
|
||||
var rcvr = this.parentThatIsA(BlockMorph).scriptTarget(),
|
||||
stage = rcvr.parentThatIsA(StageMorph),
|
||||
dict = {},
|
||||
allNames = [];
|
||||
|
@ -8146,7 +8169,7 @@ InputSlotMorph.prototype.gettablesMenu = function () {
|
|||
InputSlotMorph.prototype.attributesMenu = function () {
|
||||
var block = this.parentThatIsA(BlockMorph),
|
||||
objName = block.inputs()[1].evaluate(),
|
||||
rcvr = block.receiver(),
|
||||
rcvr = block.scriptTarget(),
|
||||
stage = rcvr.parentThatIsA(StageMorph),
|
||||
obj,
|
||||
dict = {},
|
||||
|
@ -8196,7 +8219,7 @@ InputSlotMorph.prototype.attributesMenu = function () {
|
|||
};
|
||||
|
||||
InputSlotMorph.prototype.costumesMenu = function () {
|
||||
var rcvr = this.parentThatIsA(BlockMorph).receiver(),
|
||||
var rcvr = this.parentThatIsA(BlockMorph).scriptTarget(),
|
||||
dict,
|
||||
allNames = [];
|
||||
if (rcvr instanceof SpriteMorph) {
|
||||
|
@ -8217,7 +8240,7 @@ InputSlotMorph.prototype.costumesMenu = function () {
|
|||
};
|
||||
|
||||
InputSlotMorph.prototype.soundsMenu = function () {
|
||||
var rcvr = this.parentThatIsA(BlockMorph).receiver(),
|
||||
var rcvr = this.parentThatIsA(BlockMorph).scriptTarget(),
|
||||
allNames = [],
|
||||
dict = {};
|
||||
|
||||
|
@ -8257,7 +8280,7 @@ InputSlotMorph.prototype.shadowedVariablesMenu = function () {
|
|||
dict = {};
|
||||
|
||||
if (!block) {return dict; }
|
||||
rcvr = block.receiver();
|
||||
rcvr = block.scriptTarget();
|
||||
if (rcvr && rcvr.exemplar) {
|
||||
vars = rcvr.inheritedVariableNames(true);
|
||||
vars.forEach(function (name) {
|
||||
|
@ -13237,7 +13260,7 @@ ScriptFocusMorph.prototype.deleteLastElement = function () {
|
|||
};
|
||||
|
||||
ScriptFocusMorph.prototype.insertBlock = function (block) {
|
||||
var pb, stage, ide;
|
||||
var pb, stage, ide, rcvr;
|
||||
block.isTemplate = false;
|
||||
block.isDraggable = true;
|
||||
|
||||
|
@ -13303,8 +13326,9 @@ ScriptFocusMorph.prototype.insertBlock = function (block) {
|
|||
|
||||
// register generic hat blocks
|
||||
if (block.selector === 'receiveCondition') {
|
||||
if (this.editor.owner) {
|
||||
stage = this.editor.owner.parentThatIsA(StageMorph);
|
||||
rcvr = this.editor.scriptTarget();
|
||||
if (rcvr) {
|
||||
stage = rcvr.parentThatIsA(StageMorph);
|
||||
if (stage) {
|
||||
stage.enableCustomHatBlocks = true;
|
||||
stage.threads.pauseCustomHatBlocks = false;
|
||||
|
@ -13752,7 +13776,7 @@ ScriptFocusMorph.prototype.reactToKeyEvent = function (key) {
|
|||
delete this.fps;
|
||||
delete this.step;
|
||||
this.show();
|
||||
this.editor.owner.searchBlocks(
|
||||
this.editor.scriptTarget().searchBlocks(
|
||||
key,
|
||||
types,
|
||||
vNames,
|
||||
|
|
23
byob.js
23
byob.js
|
@ -108,7 +108,7 @@ BooleanSlotMorph, XML_Serializer*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.byob = '2017-April-10';
|
||||
modules.byob = '2017-May-30';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -799,7 +799,7 @@ CustomCommandBlockMorph.prototype.edit = function () {
|
|||
);
|
||||
} else {
|
||||
// check for local custom block inheritance
|
||||
rcvr = this.receiver();
|
||||
rcvr = this.scriptTarget();
|
||||
if (!this.isGlobal) {
|
||||
if (contains(
|
||||
Object.keys(rcvr.inheritedBlocks()),
|
||||
|
@ -860,8 +860,12 @@ 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
|
||||
// NOTE: for sprite-local blocks only to be used in a situation
|
||||
// where the user actively clicks on a block in the IDE,
|
||||
// e.g. to edit it (and change its type)
|
||||
var def = this.definition,
|
||||
ide = this.receiver().parentThatIsA(IDE_Morph);
|
||||
rcvr = this.scriptTarget(),
|
||||
ide = rcvr.parentThatIsA(IDE_Morph);
|
||||
if (def.isGlobal && ide) {
|
||||
return ide.sprites.asArray().concat([ide.stage]).some(
|
||||
function (any, idx) {
|
||||
|
@ -869,15 +873,14 @@ CustomCommandBlockMorph.prototype.isInUse = function () {
|
|||
}
|
||||
);
|
||||
}
|
||||
// return this.receiver().usesBlockInstance(def);
|
||||
return this.receiver().allDependentInvocationsOf(this.blockSpec).length > 0;
|
||||
return rcvr.allDependentInvocationsOf(this.blockSpec).length > 0;
|
||||
};
|
||||
|
||||
// CustomCommandBlockMorph menu:
|
||||
|
||||
CustomCommandBlockMorph.prototype.userMenu = function () {
|
||||
var hat = this.parentThatIsA(PrototypeHatBlockMorph),
|
||||
rcvr = this.receiver(),
|
||||
rcvr = this.scriptTarget(),
|
||||
myself = this,
|
||||
shiftClicked = this.world().currentKey === 16,
|
||||
menu;
|
||||
|
@ -999,7 +1002,7 @@ CustomCommandBlockMorph.prototype.exportBlockDefinition = function () {
|
|||
};
|
||||
|
||||
CustomCommandBlockMorph.prototype.duplicateBlockDefinition = function () {
|
||||
var rcvr = this.receiver(),
|
||||
var rcvr = this.scriptTarget(),
|
||||
ide = this.parentThatIsA(IDE_Morph),
|
||||
def = this.isGlobal ? this.definition : rcvr.getMethod(this.blockSpec),
|
||||
dup = def.copyAndBindTo(rcvr);
|
||||
|
@ -1015,7 +1018,7 @@ CustomCommandBlockMorph.prototype.duplicateBlockDefinition = function () {
|
|||
|
||||
CustomCommandBlockMorph.prototype.deleteBlockDefinition = function () {
|
||||
var idx, stage, ide, method, block,
|
||||
rcvr = this.receiver(),
|
||||
rcvr = this.scriptTarget(),
|
||||
myself = this;
|
||||
if (this.isPrototype) {
|
||||
return null; // under construction...
|
||||
|
@ -1093,7 +1096,7 @@ CustomCommandBlockMorph.prototype.relabel = function (alternatives) {
|
|||
};
|
||||
|
||||
CustomCommandBlockMorph.prototype.alternatives = function () {
|
||||
var rcvr = this.receiver(),
|
||||
var rcvr = this.scriptTarget(),
|
||||
stage = rcvr.parentThatIsA(StageMorph),
|
||||
allDefs = rcvr.customBlocks.concat(stage.globalBlocks),
|
||||
type = this instanceof CommandBlockMorph ? 'command'
|
||||
|
@ -1894,7 +1897,7 @@ BlockEditorMorph.prototype.init = function (definition, target) {
|
|||
this.createLabel();
|
||||
|
||||
// create scripting area
|
||||
scripts = new ScriptsMorph(target);
|
||||
scripts = new ScriptsMorph();
|
||||
scripts.rejectsHats = true;
|
||||
scripts.isDraggable = false;
|
||||
scripts.color = IDE_Morph.prototype.groupColor;
|
||||
|
|
2
gui.js
2
gui.js
|
@ -74,7 +74,7 @@ isRetinaSupported, SliderMorph, Animation*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.gui = '2017-May-12';
|
||||
modules.gui = '2017-May-30';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
|
|
@ -3428,6 +3428,10 @@ Fixes:
|
|||
* added inheritance support for the wardrobe (‘costumes’)
|
||||
* added inheritance support for ‘costume #’
|
||||
|
||||
170530
|
||||
------
|
||||
* let clones share the orginal’s scripts without shallow-copying them
|
||||
|
||||
|
||||
Features:
|
||||
* polymorphic sprite-local custom blocks
|
||||
|
@ -3441,6 +3445,7 @@ Features:
|
|||
* support for codification of String, Number and Boolean value types
|
||||
* costume icons indicate svg costumes
|
||||
* sprites’s rotation centers can be adjusted onstage
|
||||
* clones share their original sprite’s scripts, not a shallow-copy of them
|
||||
|
||||
Fixes:
|
||||
* changed keyboard shortcut indicator for “find blocks” to “^”
|
||||
|
|
103
objects.js
103
objects.js
|
@ -82,7 +82,7 @@ SpeechBubbleMorph, RingMorph, isNil, FileReader, TableDialogMorph,
|
|||
BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
|
||||
TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph*/
|
||||
|
||||
modules.objects = '2017-May-15';
|
||||
modules.objects = '2017-May-30';
|
||||
|
||||
var SpriteMorph;
|
||||
var StageMorph;
|
||||
|
@ -1343,7 +1343,7 @@ function SpriteMorph(globals) {
|
|||
SpriteMorph.prototype.init = function (globals) {
|
||||
this.name = localize('Sprite');
|
||||
this.variables = new VariableFrame(globals || null, this);
|
||||
this.scripts = new ScriptsMorph(this);
|
||||
this.scripts = new ScriptsMorph();
|
||||
this.customBlocks = [];
|
||||
this.costumes = new List();
|
||||
this.costume = null;
|
||||
|
@ -1388,7 +1388,7 @@ SpriteMorph.prototype.init = function (globals) {
|
|||
|
||||
// sprite inheritance
|
||||
this.exemplar = null;
|
||||
this.cachedSpecimens = null; // temporary for morphic animations
|
||||
this.cachedSpecimens = null; // not to be persisted
|
||||
this.inheritedAttributes = []; // 'x position', 'direction', 'size' etc...
|
||||
|
||||
SpriteMorph.uber.init.call(this);
|
||||
|
@ -1413,11 +1413,10 @@ SpriteMorph.prototype.fullCopy = function (forClone) {
|
|||
c.color = this.color.copy();
|
||||
c.blocksCache = {};
|
||||
c.paletteCache = {};
|
||||
c.scripts = this.scripts.fullCopy(forClone);
|
||||
c.scripts.owner = c;
|
||||
c.variables = this.variables.copy();
|
||||
c.variables.owner = c;
|
||||
if (!forClone) {
|
||||
c.scripts = this.scripts.fullCopy();
|
||||
c.customBlocks = [];
|
||||
this.customBlocks.forEach(function (def) {
|
||||
cb = def.copyAndBindTo(c);
|
||||
|
@ -3159,7 +3158,8 @@ SpriteMorph.prototype.createClone = function (immediately) {
|
|||
};
|
||||
|
||||
SpriteMorph.prototype.clonify = function (stage, immediately) {
|
||||
var hats;
|
||||
var hats,
|
||||
myself = this;
|
||||
this.parts.forEach(function (part) {
|
||||
part.clonify(stage);
|
||||
});
|
||||
|
@ -3173,6 +3173,7 @@ SpriteMorph.prototype.clonify = function (stage, immediately) {
|
|||
hats.forEach(function (block) {
|
||||
stage.threads.startProcess(
|
||||
block,
|
||||
myself,
|
||||
stage.isThreadSafe,
|
||||
null, // export result
|
||||
null, // callback
|
||||
|
@ -3899,7 +3900,7 @@ SpriteMorph.prototype.prepareToBeGrabbed = function (hand) {
|
|||
this.recordLayers();
|
||||
this.shadowAttribute('x position');
|
||||
this.shadowAttribute('y position');
|
||||
this.cachedSpecimens = this.specimens();
|
||||
this.specimens(); // make sure specimens are cached
|
||||
if (!this.bounds.containsPoint(hand.position()) &&
|
||||
this.isCorrectingOutsideDrag()) {
|
||||
this.setCenter(hand.position());
|
||||
|
@ -3920,7 +3921,6 @@ SpriteMorph.prototype.justDropped = function () {
|
|||
if (stage) {
|
||||
stage.enableCustomHatBlocks = true;
|
||||
}
|
||||
this.cachedSpecimens = null;
|
||||
if (this.exemplar) {
|
||||
this.inheritedAttributes.forEach(function (att) {
|
||||
myself.refreshInheritedAttribute(att);
|
||||
|
@ -4111,17 +4111,17 @@ SpriteMorph.prototype.slideBackTo = function (
|
|||
var myself = this;
|
||||
|
||||
// caching specimens
|
||||
this.cachedSpecimens = situation.origin.children.filter(function (m) {
|
||||
return m instanceof SpriteMorph && (m.exemplar === myself);
|
||||
});
|
||||
if (isNil(this.cachedSpecimens)) {
|
||||
this.cachedSpecimens = situation.origin.children.filter(function (m) {
|
||||
return m instanceof SpriteMorph && (m.exemplar === myself);
|
||||
});
|
||||
}
|
||||
|
||||
SpriteMorph.uber.slideBackTo.call(
|
||||
this,
|
||||
situation,
|
||||
msecs,
|
||||
function () {
|
||||
// make sure to flush cached specimens
|
||||
myself.cachedSpecimens = null;
|
||||
if (onBeforeDrop) {onBeforeDrop(); }
|
||||
},
|
||||
onBeforeDrop,
|
||||
|
@ -4548,11 +4548,16 @@ SpriteMorph.prototype.mouseDownLeft = function () {
|
|||
SpriteMorph.prototype.receiveUserInteraction = function (interaction) {
|
||||
var stage = this.parentThatIsA(StageMorph),
|
||||
procs = [],
|
||||
myself = this,
|
||||
hats;
|
||||
if (!stage) {return; } // currently dragged
|
||||
hats = this.allHatBlocksForInteraction(interaction);
|
||||
hats.forEach(function (block) {
|
||||
procs.push(stage.threads.startProcess(block, stage.isThreadSafe));
|
||||
procs.push(stage.threads.startProcess(
|
||||
block,
|
||||
myself,
|
||||
stage.isThreadSafe
|
||||
));
|
||||
});
|
||||
return procs;
|
||||
};
|
||||
|
@ -5129,6 +5134,7 @@ SpriteMorph.prototype.setExemplar = function (another) {
|
|||
ide.flushBlocksCache('variables');
|
||||
ide.refreshPalette();
|
||||
}
|
||||
another.cachedSpecimens = null;
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.allExemplars = function () {
|
||||
|
@ -5145,9 +5151,12 @@ SpriteMorph.prototype.allExemplars = function () {
|
|||
SpriteMorph.prototype.specimens = function () {
|
||||
// without myself
|
||||
var myself = this;
|
||||
return this.cachedSpecimens || this.siblings().filter(function (m) {
|
||||
return m instanceof SpriteMorph && (m.exemplar === myself);
|
||||
});
|
||||
if (isNil(this.cachedSpecimens)) {
|
||||
this.cachedSpecimens = this.siblings().filter(function (m) {
|
||||
return m instanceof SpriteMorph && (m.exemplar === myself);
|
||||
});
|
||||
}
|
||||
return this.cachedSpecimens;
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.allSpecimens = function () {
|
||||
|
@ -5536,6 +5545,16 @@ SpriteMorph.prototype.restoreLayers = function () {
|
|||
this.layers = null;
|
||||
};
|
||||
|
||||
// SpriteMorph destroying
|
||||
|
||||
SpriteMorph.prototype.destroy = function () {
|
||||
// make sure to invalidate the specimens cache
|
||||
if (this.exemplar) {
|
||||
this.exemplar.cachedSpecimens = null;
|
||||
}
|
||||
SpriteMorph.uber.destroy.call(this);
|
||||
};
|
||||
|
||||
// SpriteMorph highlighting
|
||||
|
||||
SpriteMorph.prototype.addHighlight = function (oldHighlight) {
|
||||
|
@ -5768,7 +5787,7 @@ StageMorph.prototype.init = function (globals) {
|
|||
this.name = localize('Stage');
|
||||
this.threads = new ThreadManager();
|
||||
this.variables = new VariableFrame(globals || null, this);
|
||||
this.scripts = new ScriptsMorph(this);
|
||||
this.scripts = new ScriptsMorph();
|
||||
this.customBlocks = [];
|
||||
this.globalBlocks = [];
|
||||
this.costumes = new List();
|
||||
|
@ -6174,25 +6193,24 @@ StageMorph.prototype.step = function () {
|
|||
};
|
||||
|
||||
StageMorph.prototype.stepGenericConditions = function (stopAll) {
|
||||
var hats = [],
|
||||
var hatCount = 0,
|
||||
myself = this,
|
||||
ide;
|
||||
this.children.concat(this).forEach(function (morph) {
|
||||
if (morph instanceof SpriteMorph || morph instanceof StageMorph) {
|
||||
hats = hats.concat(morph.allGenericHatBlocks());
|
||||
if (isSnapObject(morph)) {
|
||||
morph.allGenericHatBlocks().forEach(function (block) {
|
||||
hatCount += 1;
|
||||
myself.threads.doWhen(block, morph, stopAll);
|
||||
});
|
||||
}
|
||||
});
|
||||
if (!hats.length) {
|
||||
if (!hatCount) {
|
||||
this.enableCustomHatBlocks = false;
|
||||
ide = this.parentThatIsA(IDE_Morph);
|
||||
if (ide) {
|
||||
ide.controlBar.stopButton.refresh();
|
||||
}
|
||||
return;
|
||||
}
|
||||
hats.forEach(function (block) {
|
||||
myself.threads.doWhen(block, stopAll);
|
||||
});
|
||||
};
|
||||
|
||||
StageMorph.prototype.developersMenu = function () {
|
||||
|
@ -6266,7 +6284,6 @@ StageMorph.prototype.processKeyEvent = function (event, action) {
|
|||
|
||||
StageMorph.prototype.fireKeyEvent = function (key) {
|
||||
var evt = key.toLowerCase(),
|
||||
hats = [],
|
||||
procs = [],
|
||||
ide = this.parentThatIsA(IDE_Morph),
|
||||
myself = this;
|
||||
|
@ -6311,12 +6328,15 @@ StageMorph.prototype.fireKeyEvent = function (key) {
|
|||
}
|
||||
this.children.concat(this).forEach(function (morph) {
|
||||
if (isSnapObject(morph)) {
|
||||
hats = hats.concat(morph.allHatBlocksForKey(evt));
|
||||
morph.allHatBlocksForKey(evt).forEach(function (block) {
|
||||
procs.push(myself.threads.startProcess(
|
||||
block,
|
||||
morph,
|
||||
myself.isThreadSafe
|
||||
));
|
||||
});
|
||||
}
|
||||
});
|
||||
hats.forEach(function (block) {
|
||||
procs.push(myself.threads.startProcess(block, myself.isThreadSafe));
|
||||
});
|
||||
return procs;
|
||||
};
|
||||
|
||||
|
@ -6333,21 +6353,20 @@ StageMorph.prototype.inspectKeyEvent
|
|||
|
||||
StageMorph.prototype.fireGreenFlagEvent = function () {
|
||||
var procs = [],
|
||||
hats = [],
|
||||
ide = this.parentThatIsA(IDE_Morph),
|
||||
myself = this;
|
||||
|
||||
this.children.concat(this).forEach(function (morph) {
|
||||
if (isSnapObject(morph)) {
|
||||
hats = hats.concat(morph.allHatBlocksFor('__shout__go__'));
|
||||
morph.allHatBlocksFor('__shout__go__').forEach(function (block) {
|
||||
procs.push(myself.threads.startProcess(
|
||||
block,
|
||||
morph,
|
||||
myself.isThreadSafe
|
||||
));
|
||||
});
|
||||
}
|
||||
});
|
||||
hats.forEach(function (block) {
|
||||
procs.push(myself.threads.startProcess(
|
||||
block,
|
||||
myself.isThreadSafe
|
||||
));
|
||||
});
|
||||
if (ide) {
|
||||
ide.controlBar.pauseButton.refresh();
|
||||
}
|
||||
|
@ -7210,6 +7229,12 @@ StageMorph.prototype.allSpecimens = function () {
|
|||
|
||||
StageMorph.prototype.shadowAttribute = nop;
|
||||
|
||||
// StageMorph inheritance support - attributes
|
||||
|
||||
StageMorph.prototype.inheritsAttribute = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
// StageMorph inheritance support - variables
|
||||
|
||||
StageMorph.prototype.isVariableNameInUse
|
||||
|
|
116
threads.js
116
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-May-12';
|
||||
modules.threads = '2017-May-30';
|
||||
|
||||
var ThreadManager;
|
||||
var Process;
|
||||
|
@ -109,7 +109,7 @@ function snapEquals(a, b) {
|
|||
function invoke(
|
||||
action, // a BlockMorph or a Context, a reified ("ringified") block
|
||||
contextArgs, // optional List of arguments for the context, or null
|
||||
receiver, // optional sprite or environment
|
||||
receiver, // sprite or environment, optional for contexts
|
||||
timeout, // msecs
|
||||
timeoutErrorMsg, // string
|
||||
suppressErrors // bool
|
||||
|
@ -126,23 +126,23 @@ function invoke(
|
|||
// Use ThreadManager::startProcess with a callback instead
|
||||
|
||||
var proc = new Process(),
|
||||
deadline = (timeout ? Date.now() + timeout : null),
|
||||
rcvr;
|
||||
deadline = (timeout ? Date.now() + timeout : null);
|
||||
|
||||
if (action instanceof Context) {
|
||||
if (receiver) {
|
||||
if (receiver) { // optional
|
||||
action = proc.reportContextFor(receiver);
|
||||
}
|
||||
proc.initializeFor(action, contextArgs || new List());
|
||||
} else if (action instanceof BlockMorph) {
|
||||
proc.topBlock = action;
|
||||
rcvr = receiver || action.receiver();
|
||||
if (rcvr) {
|
||||
if (receiver) {
|
||||
proc.homeContext = new Context();
|
||||
proc.homeContext.receiver = rcvr;
|
||||
if (rcvr.variables) {
|
||||
proc.homeContext.variables.parentFrame = rcvr.variables;
|
||||
proc.homeContext.receiver = receiver;
|
||||
if (receiver.variables) {
|
||||
proc.homeContext.variables.parentFrame = receiver.variables;
|
||||
}
|
||||
} else {
|
||||
throw new Error('expecting a receiver but getting ' + receiver);
|
||||
}
|
||||
proc.context = new Context(
|
||||
null,
|
||||
|
@ -180,25 +180,26 @@ function ThreadManager() {
|
|||
|
||||
ThreadManager.prototype.pauseCustomHatBlocks = false;
|
||||
|
||||
ThreadManager.prototype.toggleProcess = function (block) {
|
||||
var active = this.findProcess(block);
|
||||
ThreadManager.prototype.toggleProcess = function (block, receiver) {
|
||||
var active = this.findProcess(block, receiver);
|
||||
if (active) {
|
||||
active.stop();
|
||||
} else {
|
||||
return this.startProcess(block, null, null, null, true);
|
||||
return this.startProcess(block, receiver, null, null, null, true);
|
||||
}
|
||||
};
|
||||
|
||||
ThreadManager.prototype.startProcess = function (
|
||||
block,
|
||||
receiver,
|
||||
isThreadSafe,
|
||||
exportResult,
|
||||
exportResult, // bool
|
||||
callback,
|
||||
isClicked,
|
||||
rightAway
|
||||
) {
|
||||
var active = this.findProcess(block),
|
||||
top = block.topBlock(),
|
||||
var top = block.topBlock(),
|
||||
active = this.findProcess(top, receiver),
|
||||
newProc;
|
||||
if (active) {
|
||||
if (isThreadSafe) {
|
||||
|
@ -207,7 +208,7 @@ ThreadManager.prototype.startProcess = function (
|
|||
active.stop();
|
||||
this.removeTerminatedProcesses();
|
||||
}
|
||||
newProc = new Process(block.topBlock(), callback, rightAway);
|
||||
newProc = new Process(top, receiver, callback, rightAway);
|
||||
newProc.exportResult = exportResult;
|
||||
newProc.isClicked = isClicked || false;
|
||||
if (!newProc.homeContext.receiver.isClone) {
|
||||
|
@ -241,8 +242,8 @@ ThreadManager.prototype.stopAllForReceiver = function (rcvr, excpt) {
|
|||
});
|
||||
};
|
||||
|
||||
ThreadManager.prototype.stopProcess = function (block) {
|
||||
var active = this.findProcess(block);
|
||||
ThreadManager.prototype.stopProcess = function (block, receiver) {
|
||||
var active = this.findProcess(block, receiver);
|
||||
if (active) {
|
||||
active.stop();
|
||||
}
|
||||
|
@ -309,7 +310,8 @@ ThreadManager.prototype.removeTerminatedProcesses = function () {
|
|||
this.processes.forEach(function (proc) {
|
||||
var result;
|
||||
if ((!proc.isRunning() && !proc.errorFlag) || proc.isDead) {
|
||||
if (proc.topBlock instanceof BlockMorph) {
|
||||
if (proc.topBlock instanceof BlockMorph
|
||||
&& (!proc.receiver.isClone)) {
|
||||
proc.unflash();
|
||||
proc.topBlock.removeHighlight();
|
||||
}
|
||||
|
@ -349,19 +351,19 @@ ThreadManager.prototype.removeTerminatedProcesses = function () {
|
|||
this.processes = remaining;
|
||||
};
|
||||
|
||||
ThreadManager.prototype.findProcess = function (block) {
|
||||
ThreadManager.prototype.findProcess = function (block, receiver) {
|
||||
var top = block.topBlock();
|
||||
return detect(
|
||||
this.processes,
|
||||
function (each) {
|
||||
return each.topBlock === top;
|
||||
return each.topBlock === top && (each.receiver === receiver);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
ThreadManager.prototype.doWhen = function (block, stopIt) {
|
||||
ThreadManager.prototype.doWhen = function (block, receiver, stopIt) {
|
||||
if (this.pauseCustomHatBlocks) {return; }
|
||||
if ((!block) || this.findProcess(block)) {
|
||||
if ((!block) || this.findProcess(block, receiver)) {
|
||||
return;
|
||||
}
|
||||
var pred = block.inputs()[0], world;
|
||||
|
@ -376,12 +378,20 @@ ThreadManager.prototype.doWhen = function (block, stopIt) {
|
|||
if (invoke(
|
||||
pred,
|
||||
null,
|
||||
block.receiver(), // needed for shallow copied clones - was null
|
||||
receiver,
|
||||
50,
|
||||
'the predicate takes\ntoo long for a\ncustom hat block',
|
||||
true // suppress errors => handle them right here instead
|
||||
) === true) {
|
||||
this.startProcess(block, null, null, null, null, true); // atomic
|
||||
this.startProcess(
|
||||
block,
|
||||
receiver,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true // atomic
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
block.addErrorHighlight();
|
||||
|
@ -476,9 +486,9 @@ Process.prototype.enableSingleStepping = false; // experimental
|
|||
Process.prototype.flashTime = 0; // experimental
|
||||
// Process.prototype.enableJS = false;
|
||||
|
||||
function Process(topBlock, onComplete, rightAway) {
|
||||
function Process(topBlock, receiver, onComplete, rightAway) {
|
||||
this.topBlock = topBlock || null;
|
||||
|
||||
this.receiver = receiver;
|
||||
this.readyToYield = false;
|
||||
this.readyToTerminate = false;
|
||||
this.isDead = false;
|
||||
|
@ -486,7 +496,7 @@ function Process(topBlock, onComplete, rightAway) {
|
|||
this.isShowingResult = false;
|
||||
this.errorFlag = false;
|
||||
this.context = null;
|
||||
this.homeContext = new Context();
|
||||
this.homeContext = new Context(null, null, null, receiver);
|
||||
this.lastYield = Date.now();
|
||||
this.isFirstStep = true;
|
||||
this.isAtomic = false;
|
||||
|
@ -502,7 +512,6 @@ function Process(topBlock, onComplete, rightAway) {
|
|||
this.isInterrupted = false; // experimental, for single-stepping
|
||||
|
||||
if (topBlock) {
|
||||
this.homeContext.receiver = topBlock.receiver();
|
||||
this.homeContext.variables.parentFrame =
|
||||
this.homeContext.receiver.variables;
|
||||
this.context = new Context(
|
||||
|
@ -651,7 +660,7 @@ Process.prototype.evaluateBlock = function (block, argCount) {
|
|||
}
|
||||
|
||||
// first evaluate all inputs, then apply the primitive
|
||||
var rcvr = this.context.receiver || this.topBlock.receiver(),
|
||||
var rcvr = this.context.receiver || this.receiver,
|
||||
inputs = this.context.inputs;
|
||||
|
||||
if (argCount > inputs.length) {
|
||||
|
@ -963,7 +972,7 @@ Process.prototype.reify = function (topBlock, parameterNames, isCustomBlock) {
|
|||
|
||||
context.inputs = parameterNames.asArray();
|
||||
context.receiver
|
||||
= this.context ? this.context.receiver : topBlock.receiver();
|
||||
= this.context ? this.context.receiver : this.receiver;
|
||||
context.origin = context.receiver; // for serialization
|
||||
|
||||
return context;
|
||||
|
@ -1137,6 +1146,9 @@ Process.prototype.initializeFor = function (context, args) {
|
|||
value,
|
||||
exit;
|
||||
|
||||
// remember the receiver
|
||||
this.context = context.receiver;
|
||||
|
||||
// assign parameters if any were passed
|
||||
if (parms.length > 0) {
|
||||
|
||||
|
@ -1557,7 +1569,7 @@ Process.prototype.doDeleteAttr = function (attrName) {
|
|||
if (!isNil(name)) {
|
||||
rcvr.inheritAttribute(name);
|
||||
}
|
||||
return; // +++ error: cannot delete attribute...
|
||||
return; // error: cannot delete attribute...
|
||||
}
|
||||
}
|
||||
if (name instanceof Array) {
|
||||
|
@ -2063,7 +2075,7 @@ Process.prototype.doThinkFor = function (data, secs) {
|
|||
|
||||
Process.prototype.blockReceiver = function () {
|
||||
return this.context ? this.context.receiver || this.homeContext.receiver
|
||||
: this.homeContext.receiver;
|
||||
: this.homeContext.receiver || this.receiver;
|
||||
};
|
||||
|
||||
// Process sound primitives (interpolated)
|
||||
|
@ -2180,7 +2192,6 @@ Process.prototype.doBroadcast = function (message) {
|
|||
trg,
|
||||
rcvrs,
|
||||
myself = this,
|
||||
hats = [],
|
||||
procs = [];
|
||||
|
||||
if (message instanceof List && (message.length() === 2)) {
|
||||
|
@ -2211,40 +2222,19 @@ Process.prototype.doBroadcast = function (message) {
|
|||
stage.lastMessage = message; // the actual data structure
|
||||
rcvrs.forEach(function (morph) {
|
||||
if (isSnapObject(morph)) {
|
||||
hats = hats.concat(morph.allHatBlocksFor(msg));
|
||||
morph.allHatBlocksFor(msg).forEach(function (block) {
|
||||
procs.push(stage.threads.startProcess(
|
||||
block,
|
||||
morph,
|
||||
stage.isThreadSafe
|
||||
));
|
||||
});
|
||||
}
|
||||
});
|
||||
hats.forEach(function (block) {
|
||||
procs.push(stage.threads.startProcess(block, stage.isThreadSafe));
|
||||
});
|
||||
}
|
||||
return procs;
|
||||
};
|
||||
|
||||
// old purely global broadcast code, commented out and retained in case
|
||||
// we need to revert
|
||||
|
||||
/*
|
||||
Process.prototype.doBroadcast = function (message) {
|
||||
var stage = this.homeContext.receiver.parentThatIsA(StageMorph),
|
||||
hats = [],
|
||||
procs = [];
|
||||
|
||||
if (message !== '') {
|
||||
stage.lastMessage = message;
|
||||
stage.children.concat(stage).forEach(function (morph) {
|
||||
if (isSnapObject(morph)) {
|
||||
hats = hats.concat(morph.allHatBlocksFor(message));
|
||||
}
|
||||
});
|
||||
hats.forEach(function (block) {
|
||||
procs.push(stage.threads.startProcess(block, stage.isThreadSafe));
|
||||
});
|
||||
}
|
||||
return procs;
|
||||
};
|
||||
*/
|
||||
|
||||
Process.prototype.doBroadcastAndWait = function (message) {
|
||||
if (!this.context.activeSends) {
|
||||
this.context.activeSends = this.doBroadcast(message);
|
||||
|
|
Ładowanie…
Reference in New Issue