kopia lustrzana https://github.com/backface/turtlestitch
unify Scratch-style clones and Snap-specimens
implement clones as specimensupd4.1
rodzic
d89f29957e
commit
de10e558e6
|
@ -150,7 +150,7 @@ CustomCommandBlockMorph*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.blocks = '2017-June-26';
|
||||
modules.blocks = '2017-July-04';
|
||||
|
||||
var SyntaxElementMorph;
|
||||
var BlockMorph;
|
||||
|
@ -8117,7 +8117,7 @@ InputSlotMorph.prototype.collidablesMenu = function () {
|
|||
allNames = [];
|
||||
|
||||
stage.children.forEach(function (morph) {
|
||||
if (morph instanceof SpriteMorph && !morph.isClone) {
|
||||
if (morph instanceof SpriteMorph && !morph.isTemporary) {
|
||||
if (morph.name !== rcvr.name) {
|
||||
allNames = allNames.concat(morph.name);
|
||||
}
|
||||
|
@ -8166,7 +8166,7 @@ InputSlotMorph.prototype.clonablesMenu = function () {
|
|||
dict.myself = ['myself'];
|
||||
}
|
||||
stage.children.forEach(function (morph) {
|
||||
if (morph instanceof SpriteMorph && !morph.isClone) {
|
||||
if (morph instanceof SpriteMorph && !morph.isTemporary) {
|
||||
allNames = allNames.concat(morph.name);
|
||||
}
|
||||
});
|
||||
|
|
4
gui.js
4
gui.js
|
@ -74,7 +74,7 @@ isRetinaSupported, SliderMorph, Animation*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.gui = '2017-June-26';
|
||||
modules.gui = '2017-July-04';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -1514,7 +1514,7 @@ IDE_Morph.prototype.createCorral = function () {
|
|||
frame.alpha = 0;
|
||||
|
||||
this.sprites.asArray().forEach(function (morph) {
|
||||
if (!morph.isClone) {
|
||||
if (!morph.isTemporary) {
|
||||
template = new SpriteIconMorph(morph, template);
|
||||
frame.contents.add(template);
|
||||
}
|
||||
|
|
|
@ -3492,6 +3492,15 @@ Fixes:
|
|||
* Objects: reflect attribute inheritance status by ghosting / un-ghosting stage monitors
|
||||
* Objects: migrate experimental “jukebox” reporters to the new “my sounds” reporter
|
||||
|
||||
170703
|
||||
------
|
||||
* Objects, Threads, GUI, Blocks, YPR: renamed Sprite::isClone to Sprite:isTemporary
|
||||
|
||||
170704
|
||||
------
|
||||
* Morphic: Simplify contains()
|
||||
* Unify Scratch-style clones and Snap-specimens, part 1: implement clones as specimens
|
||||
|
||||
|
||||
Features:
|
||||
* polymorphic sprite-local custom blocks
|
||||
|
|
245
objects.js
245
objects.js
|
@ -82,7 +82,7 @@ SpeechBubbleMorph, RingMorph, isNil, FileReader, TableDialogMorph,
|
|||
BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
|
||||
TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph*/
|
||||
|
||||
modules.objects = '2017-June-30';
|
||||
modules.objects = '2017-July-04';
|
||||
|
||||
var SpriteMorph;
|
||||
var StageMorph;
|
||||
|
@ -1363,7 +1363,7 @@ SpriteMorph.prototype.init = function (globals) {
|
|||
this.scale = 1;
|
||||
this.rotationStyle = 1; // 1 = full, 2 = left/right, 0 = off
|
||||
this.version = Date.now(); // for observer optimization
|
||||
this.isClone = false; // indicate a "temporary" Scratch-style clone
|
||||
this.isTemporary = false; // indicate a temporary Scratch-style clone
|
||||
this.isCorpse = false; // indicate whether a sprite/clone has been deleted
|
||||
this.cloneOriginName = '';
|
||||
|
||||
|
@ -1399,7 +1399,8 @@ SpriteMorph.prototype.init = function (globals) {
|
|||
|
||||
// sprite inheritance
|
||||
this.exemplar = null;
|
||||
this.cachedSpecimens = null; // not to be persisted
|
||||
this.instances = [];
|
||||
this.cachedPropagation = false; // not to be persisted
|
||||
this.inheritedAttributes = []; // 'x position', 'direction', 'size' etc...
|
||||
|
||||
SpriteMorph.uber.init.call(this);
|
||||
|
@ -1420,13 +1421,23 @@ SpriteMorph.prototype.fullCopy = function (forClone) {
|
|||
arr = [],
|
||||
cb, effect;
|
||||
|
||||
c.instances = [];
|
||||
c.stopTalking();
|
||||
c.color = this.color.copy();
|
||||
c.blocksCache = {};
|
||||
c.paletteCache = {};
|
||||
c.variables = this.variables.copy();
|
||||
c.variables.owner = c;
|
||||
if (!forClone) {
|
||||
if (forClone) {
|
||||
c.exemplar = this;
|
||||
this.addSpecimen(c);
|
||||
this.cachedPropagation = false;
|
||||
['scripts', 'costumes', 'sounds'].forEach(function (att) {
|
||||
if (!contains(c.inheritedAttributes, att)) {
|
||||
c.inheritedAttributes.push(att);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
c.scripts = this.scripts.fullCopy();
|
||||
c.customBlocks = [];
|
||||
this.customBlocks.forEach(function (def) {
|
||||
|
@ -1473,7 +1484,7 @@ SpriteMorph.prototype.fullCopy = function (forClone) {
|
|||
|
||||
SpriteMorph.prototype.appearIn = function (ide) {
|
||||
// private - used in IDE_Morph.duplicateSprite()
|
||||
if (!this.isClone) {
|
||||
if (!this.isTemporary) {
|
||||
this.name = ide.newSpriteName(this.name);
|
||||
ide.corral.addSprite(this);
|
||||
ide.sprites.add(this);
|
||||
|
@ -2929,13 +2940,15 @@ SpriteMorph.prototype.wearCostume = function (costume, noShadow) {
|
|||
this.shadowAttribute('costume #');
|
||||
}
|
||||
this.specimens().forEach(function (instance) {
|
||||
if (instance.inheritsAttribute('costume #')) {
|
||||
if (idx === null) {
|
||||
instance.wearCostume(null, true);
|
||||
} else if (idx === -1) {
|
||||
instance.wearCostume(costume, true);
|
||||
} else {
|
||||
instance.doSwitchToCostume(idx + 1, true);
|
||||
if (instance.cachedPropagation) {
|
||||
if (instance.inheritsAttribute('costume #')) {
|
||||
if (idx === null) {
|
||||
instance.wearCostume(null, true);
|
||||
} else if (idx === -1) {
|
||||
instance.wearCostume(costume, true);
|
||||
} else {
|
||||
instance.doSwitchToCostume(idx + 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -3059,7 +3072,7 @@ SpriteMorph.prototype.userMenu = function () {
|
|||
// menu.addItem('help', 'nop');
|
||||
return menu;
|
||||
}
|
||||
if (!this.isClone) {
|
||||
if (!this.isTemporary) {
|
||||
menu.addItem("duplicate", 'duplicate');
|
||||
}
|
||||
menu.addItem("delete", 'remove');
|
||||
|
@ -3071,7 +3084,7 @@ SpriteMorph.prototype.userMenu = function () {
|
|||
'edit the costume\'s\nrotation center'
|
||||
);
|
||||
}
|
||||
if (!this.isClone) {
|
||||
if (!this.isTemporary) {
|
||||
menu.addItem("edit", 'edit');
|
||||
}
|
||||
menu.addLine();
|
||||
|
@ -3089,7 +3102,7 @@ SpriteMorph.prototype.userMenu = function () {
|
|||
};
|
||||
|
||||
SpriteMorph.prototype.exportSprite = function () {
|
||||
if (this.isClone) {return; }
|
||||
if (this.isTemporary) {return; }
|
||||
var ide = this.parentThatIsA(IDE_Morph);
|
||||
if (ide) {
|
||||
ide.exportSprite(this);
|
||||
|
@ -3160,9 +3173,9 @@ SpriteMorph.prototype.clonify = function (stage, immediately) {
|
|||
part.clonify(stage);
|
||||
});
|
||||
stage.cloneCount += 1;
|
||||
this.cloneOriginName = this.isClone ?
|
||||
this.cloneOriginName = this.isTemporary ?
|
||||
this.cloneOriginName : this.name;
|
||||
this.isClone = true;
|
||||
this.isTemporary = true;
|
||||
this.name = '';
|
||||
stage.add(this);
|
||||
hats = this.allHatBlocksFor('__clone__init__');
|
||||
|
@ -3181,7 +3194,7 @@ SpriteMorph.prototype.clonify = function (stage, immediately) {
|
|||
};
|
||||
|
||||
SpriteMorph.prototype.removeClone = function () {
|
||||
if (this.isClone) {
|
||||
if (this.isTemporary) {
|
||||
// this.stopTalking();
|
||||
this.parent.threads.stopAllForReceiver(this);
|
||||
this.corpsify();
|
||||
|
@ -3418,9 +3431,11 @@ SpriteMorph.prototype.setScale = function (percentage, noShadow) {
|
|||
if (!noShadow) {
|
||||
this.shadowAttribute('size');
|
||||
}
|
||||
this.specimens().forEach(function (instance) {
|
||||
if (instance.inheritsAttribute('size')) {
|
||||
instance.setScale(percentage, true);
|
||||
this.instances.forEach(function (instance) {
|
||||
if (instance.cachedPropagation) {
|
||||
if (instance.inheritsAttribute('size')) {
|
||||
instance.setScale(percentage, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -3896,7 +3911,7 @@ SpriteMorph.prototype.prepareToBeGrabbed = function (hand) {
|
|||
this.recordLayers();
|
||||
this.shadowAttribute('x position');
|
||||
this.shadowAttribute('y position');
|
||||
this.specimens(); // make sure specimens are cached
|
||||
this.instances; // make sure specimens are cached
|
||||
if (!this.bounds.containsPoint(hand.position()) &&
|
||||
this.isCorrectingOutsideDrag()) {
|
||||
this.setCenter(hand.position());
|
||||
|
@ -4033,15 +4048,17 @@ SpriteMorph.prototype.moveBy = function (delta, justMe) {
|
|||
this.parts.forEach(function (part) {
|
||||
part.moveBy(delta);
|
||||
});
|
||||
this.specimens().forEach(function (instance) {
|
||||
var inheritsX = instance.inheritsAttribute('x position'),
|
||||
inheritsY = instance.inheritsAttribute('y position');
|
||||
if (inheritsX && inheritsY) {
|
||||
instance.moveBy(delta);
|
||||
} else if (inheritsX) {
|
||||
instance.moveBy(new Point(delta.x, 0));
|
||||
} else if (inheritsY) {
|
||||
instance.moveBy(new Point(0, delta.y));
|
||||
this.instances.forEach(function (instance) {
|
||||
if (instance.cachedPropagation) {
|
||||
var inheritsX = instance.inheritsAttribute('x position'),
|
||||
inheritsY = instance.inheritsAttribute('y position');
|
||||
if (inheritsX && inheritsY) {
|
||||
instance.moveBy(delta);
|
||||
} else if (inheritsX) {
|
||||
instance.moveBy(new Point(delta.x, 0));
|
||||
} else if (inheritsY) {
|
||||
instance.moveBy(new Point(0, delta.y));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -4053,15 +4070,17 @@ SpriteMorph.prototype.silentMoveBy = function (delta, justMe) {
|
|||
this.parts.forEach(function (part) {
|
||||
part.moveBy(delta);
|
||||
});
|
||||
this.specimens().forEach(function (instance) {
|
||||
var inheritsX = instance.inheritsAttribute('x position'),
|
||||
inheritsY = instance.inheritsAttribute('y position');
|
||||
if (inheritsX && inheritsY) {
|
||||
instance.moveBy(delta);
|
||||
} else if (inheritsX) {
|
||||
instance.moveBy(new Point(delta.x, 0));
|
||||
} else if (inheritsY) {
|
||||
instance.moveBy(new Point(0, delta.y));
|
||||
this.instances.forEach(function (instance) {
|
||||
if (instance.cachedPropagation) {
|
||||
var inheritsX = instance.inheritsAttribute('x position'),
|
||||
inheritsY = instance.inheritsAttribute('y position');
|
||||
if (inheritsX && inheritsY) {
|
||||
instance.moveBy(delta);
|
||||
} else if (inheritsX) {
|
||||
instance.moveBy(new Point(delta.x, 0));
|
||||
} else if (inheritsY) {
|
||||
instance.moveBy(new Point(0, delta.y));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -4096,35 +4115,6 @@ SpriteMorph.prototype.nestingBounds = function () {
|
|||
return result;
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.slideBackTo = function (
|
||||
situation,
|
||||
msecs,
|
||||
onBeforeDrop,
|
||||
onComplete
|
||||
) {
|
||||
// override the inherited method to make sure my specimens can follow
|
||||
// by caching them while sliding
|
||||
var myself = this;
|
||||
|
||||
// caching specimens
|
||||
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 () {
|
||||
if (onBeforeDrop) {onBeforeDrop(); }
|
||||
},
|
||||
onBeforeDrop,
|
||||
onComplete
|
||||
);
|
||||
};
|
||||
|
||||
// SpriteMorph motion primitives
|
||||
|
||||
SpriteMorph.prototype.setPosition = function (aPoint, justMe) {
|
||||
|
@ -4186,9 +4176,11 @@ SpriteMorph.prototype.setHeading = function (degrees, noShadow) {
|
|||
if (!noShadow) {
|
||||
this.shadowAttribute('direction');
|
||||
}
|
||||
this.specimens().forEach(function (instance) {
|
||||
if (instance.inheritsAttribute('direction')) {
|
||||
instance.setHeading(degrees, true);
|
||||
this.instances.forEach(function (instance) {
|
||||
if (instance.cachedPropagation) {
|
||||
if (instance.inheritsAttribute('direction')) {
|
||||
instance.setHeading(degrees, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -4559,7 +4551,7 @@ SpriteMorph.prototype.receiveUserInteraction = function (interaction) {
|
|||
};
|
||||
|
||||
SpriteMorph.prototype.mouseDoubleClick = function () {
|
||||
if (this.isClone) {return; }
|
||||
if (this.isTemporary) {return; }
|
||||
this.edit();
|
||||
};
|
||||
|
||||
|
@ -4817,7 +4809,7 @@ SpriteMorph.prototype.deleteAllBlockInstances = function (definition) {
|
|||
});
|
||||
}
|
||||
} else {
|
||||
this.allSpecimens().concat(this).forEach(function (sprite) {
|
||||
this.allinstances.concat(this).forEach(function (sprite) {
|
||||
sprite.customBlocks.forEach(function (def) {
|
||||
def.purgeCorpses();
|
||||
});
|
||||
|
@ -4865,7 +4857,7 @@ SpriteMorph.prototype.allIndependentInvocationsOf = function (aSpec) {
|
|||
return [];
|
||||
}
|
||||
blocks = this.allInvocationsOf(aSpec);
|
||||
this.specimens().forEach(function (sprite) {
|
||||
this.instances.forEach(function (sprite) {
|
||||
sprite.addAllInvocationsOf(aSpec, blocks);
|
||||
});
|
||||
return blocks;
|
||||
|
@ -4874,7 +4866,7 @@ SpriteMorph.prototype.allIndependentInvocationsOf = function (aSpec) {
|
|||
SpriteMorph.prototype.allDependentInvocationsOf = function (aSpec) {
|
||||
var blocks;
|
||||
blocks = this.allInvocationsOf(aSpec);
|
||||
this.specimens().forEach(function (sprite) {
|
||||
this.instances.forEach(function (sprite) {
|
||||
sprite.addAllInvocationsOf(aSpec, blocks);
|
||||
});
|
||||
return blocks;
|
||||
|
@ -4920,7 +4912,7 @@ SpriteMorph.prototype.addAllInvocationsOf = function (aSpec, anArray) {
|
|||
this.allInvocationsOf(aSpec).forEach(function (block) {
|
||||
anArray.push(block);
|
||||
});
|
||||
this.specimens().forEach(function (sprite) {
|
||||
this.instances.forEach(function (sprite) {
|
||||
sprite.addAllInvocationsOf(aSpec, anArray);
|
||||
});
|
||||
}
|
||||
|
@ -5122,40 +5114,39 @@ SpriteMorph.prototype.setExemplar = function (another) {
|
|||
var ide = this.parentThatIsA(IDE_Morph);
|
||||
this.emancipate();
|
||||
this.exemplar = another;
|
||||
if (isNil(another)) {
|
||||
this.variables.parentFrame = (this.globalVariables());
|
||||
} else {
|
||||
if (another) {
|
||||
this.variables.parentFrame = (another.variables);
|
||||
another.addSpecimen(this);
|
||||
} else {
|
||||
this.variables.parentFrame = (this.globalVariables());
|
||||
}
|
||||
if (ide) {
|
||||
ide.flushBlocksCache('variables');
|
||||
ide.refreshPalette();
|
||||
}
|
||||
if (another) {
|
||||
another.cachedSpecimens = null;
|
||||
another.specimens(); // update the inheritance cache
|
||||
}
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.prune = function () {
|
||||
// sever ties with all my specimen, if any,
|
||||
this.specimens().forEach(function (child) {
|
||||
this.instances.forEach(function (child) {
|
||||
child.shadowAllAttributes();
|
||||
child.shadowAllMethods();
|
||||
child.shadowAllVars();
|
||||
child.exemplar = null;
|
||||
});
|
||||
this.cachedSpecimens = null;
|
||||
this.instances = [];
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.emancipate = function () {
|
||||
// sever all relations with my exemplar, if any,
|
||||
// and make sure I am the root of my specimen
|
||||
if (this.exemplar) {
|
||||
this.shadowAllAttributes();
|
||||
this.shadowAllMethods();
|
||||
this.shadowAllVars();
|
||||
this.exemplar.cachedSpecimens = null;
|
||||
if (!this.isTemporary) {
|
||||
this.shadowAllAttributes();
|
||||
this.shadowAllMethods();
|
||||
this.shadowAllVars();
|
||||
}
|
||||
this.exemplar.removeSpecimen(this); // optimization
|
||||
this.exemplar = null;
|
||||
}
|
||||
};
|
||||
|
@ -5173,21 +5164,29 @@ SpriteMorph.prototype.allExemplars = function () {
|
|||
|
||||
SpriteMorph.prototype.specimens = function () {
|
||||
// without myself
|
||||
var myself = this;
|
||||
if (isNil(this.cachedSpecimens)) {
|
||||
this.cachedSpecimens = this.siblings().filter(function (m) {
|
||||
return m instanceof SpriteMorph && (m.exemplar === myself);
|
||||
});
|
||||
}
|
||||
return this.cachedSpecimens;
|
||||
return this.instances;
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.allSpecimens = function () {
|
||||
// without myself
|
||||
var myself = this;
|
||||
return this.siblings().filter(function (m) {
|
||||
return m instanceof SpriteMorph && contains(m.allExemplars(), myself);
|
||||
var all = this.instances.slice();
|
||||
this.instances.forEach(function (child) {
|
||||
all.push.appl(all, child.allSpecimens());
|
||||
});
|
||||
return all;
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.addSpecimen = function (another) {
|
||||
// private - use setExemplar() to establish an inheritance relationship
|
||||
this.instances.push(another);
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.removeSpecimen = function(another) {
|
||||
// private - use setExemplar(null) to cancel an inheritance relationship
|
||||
var idx = this.instances.indexOf(another);
|
||||
if (idx !== -1) {
|
||||
this.instances.splice(idx, 1);
|
||||
}
|
||||
};
|
||||
|
||||
// SpriteMorph inheritance - attributes
|
||||
|
@ -5196,6 +5195,19 @@ SpriteMorph.prototype.inheritsAttribute = function (aName) {
|
|||
return !isNil(this.exemplar) && contains(this.inheritedAttributes, aName);
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.updatePropagationCache = function () {
|
||||
// private - indicate whether one of my inherited attributes is technically
|
||||
// propagated down from my exemplar, instead of truly shared.
|
||||
// (only) needed for internal optimization caching
|
||||
var myself = this;
|
||||
this.cachedPropagation = !isNil(this.exemplar) && detect(
|
||||
['x position', 'y position', 'direction', 'size', 'costume #'],
|
||||
function (att) {
|
||||
return contains(myself.inheritedAttributes, att);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.shadowedAttributes = function () {
|
||||
// answer an array of attribute names that can be deleted/shared
|
||||
var inherited = this.inheritedAttributes;
|
||||
|
@ -5232,7 +5244,7 @@ SpriteMorph.prototype.shadowAttribute = function (aName) {
|
|||
}
|
||||
});
|
||||
this.costumes = wardrobe;
|
||||
this.specimens().forEach(function (obj) {
|
||||
this.instances.forEach(function (obj) {
|
||||
if (obj.inheritsAttribute('costumes')) {
|
||||
obj.refreshInheritedAttribute('costumes');
|
||||
}
|
||||
|
@ -5243,7 +5255,7 @@ SpriteMorph.prototype.shadowAttribute = function (aName) {
|
|||
jukebox.add(sound.copy());
|
||||
});
|
||||
this.sounds = jukebox;
|
||||
this.specimens().forEach(function (obj) {
|
||||
this.instances.forEach(function (obj) {
|
||||
if (obj.inheritsAttribute('sounds')) {
|
||||
obj.refreshInheritedAttribute('sounds');
|
||||
}
|
||||
|
@ -5259,14 +5271,17 @@ SpriteMorph.prototype.shadowAttribute = function (aName) {
|
|||
this.scripts.setPosition(pos);
|
||||
ide.spriteEditor.adjustScrollBars();
|
||||
}
|
||||
this.specimens().forEach(function (obj) {
|
||||
this.instances.forEach(function (obj) {
|
||||
if (obj.inheritsAttribute('scripts')) {
|
||||
obj.refreshInheritedAttribute('scripts');
|
||||
}
|
||||
});
|
||||
} else if (ide) {
|
||||
ide.flushBlocksCache(); // optimization: specify category if known
|
||||
ide.refreshPalette();
|
||||
} else {
|
||||
this.updatePropagationCache();
|
||||
if (ide) {
|
||||
ide.flushBlocksCache(); // optimization: specify category if known
|
||||
ide.refreshPalette();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5290,22 +5305,26 @@ SpriteMorph.prototype.refreshInheritedAttribute = function (aName) {
|
|||
switch (aName) {
|
||||
case 'x position':
|
||||
case 'y position':
|
||||
this.cachedPropagation = true;
|
||||
this.gotoXY(this.xPosition(), this.yPosition(), false, true);
|
||||
break;
|
||||
case 'direction':
|
||||
this.cachedPropagation = true;
|
||||
this.setHeading(this.direction(), true);
|
||||
break;
|
||||
case 'size':
|
||||
this.cachedPropagation = true;
|
||||
this.setScale(this.getScale(), true);
|
||||
break;
|
||||
case 'costume #':
|
||||
this.cachedPropagation = true;
|
||||
this.doSwitchToCostume(this.getCostumeIdx(), true);
|
||||
break;
|
||||
case 'costumes':
|
||||
idx = this.getCostumeIdx();
|
||||
this.costumes = this.exemplar.costumes;
|
||||
this.doSwitchToCostume(idx, true);
|
||||
this.specimens().forEach(function (sprite) {
|
||||
this.instances.forEach(function (sprite) {
|
||||
if (sprite.inheritsAttribute('costumes')) {
|
||||
sprite.refreshInheritedAttribute('costumes');
|
||||
}
|
||||
|
@ -5313,7 +5332,7 @@ SpriteMorph.prototype.refreshInheritedAttribute = function (aName) {
|
|||
break;
|
||||
case 'sounds':
|
||||
this.sounds = this.exemplar.sounds;
|
||||
this.specimens().forEach(function (sprite) {
|
||||
this.instances.forEach(function (sprite) {
|
||||
if (sprite.inheritsAttribute('sounds')) {
|
||||
sprite.refreshInheritedAttribute('sounds');
|
||||
}
|
||||
|
@ -5329,7 +5348,7 @@ SpriteMorph.prototype.refreshInheritedAttribute = function (aName) {
|
|||
ide.fixLayout('selectSprite');
|
||||
}
|
||||
}
|
||||
this.specimens().forEach(function (sprite) {
|
||||
this.instances.forEach(function (sprite) {
|
||||
if (sprite.inheritsAttribute('scripts')) {
|
||||
sprite.refreshInheritedAttribute('scripts');
|
||||
}
|
||||
|
@ -5663,7 +5682,9 @@ SpriteMorph.prototype.restoreLayers = function () {
|
|||
SpriteMorph.prototype.destroy = function () {
|
||||
// make sure to sever all inheritance ties to other sprites
|
||||
this.emancipate();
|
||||
this.prune();
|
||||
if (!this.isTemporary) {
|
||||
this.prune();
|
||||
}
|
||||
SpriteMorph.uber.destroy.call(this);
|
||||
};
|
||||
|
||||
|
@ -6508,7 +6529,9 @@ StageMorph.prototype.fireStopAllEvent = function () {
|
|||
StageMorph.prototype.removeAllClones = function () {
|
||||
var myself = this,
|
||||
clones = this.children.filter(
|
||||
function (morph) {return morph.isClone; }
|
||||
function (morph) {
|
||||
return morph instanceof SpriteMorph && morph.isTemporary;
|
||||
}
|
||||
);
|
||||
clones.forEach(function (clone) {
|
||||
myself.threads.stopAllForReceiver(clone);
|
||||
|
|
11
threads.js
11
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-June-26';
|
||||
modules.threads = '2017-July-04';
|
||||
|
||||
var ThreadManager;
|
||||
var Process;
|
||||
|
@ -246,7 +246,7 @@ ThreadManager.prototype.stopAllForReceiver = function (rcvr, excpt) {
|
|||
this.processes.forEach(function (proc) {
|
||||
if (proc.homeContext.receiver === rcvr && proc !== excpt) {
|
||||
proc.stop();
|
||||
if (rcvr.isClone) {
|
||||
if (rcvr.isTemporary) {
|
||||
proc.isDead = true;
|
||||
}
|
||||
}
|
||||
|
@ -2724,7 +2724,7 @@ Process.prototype.getObjectsNamed = function (name, thisObj, stageObj) {
|
|||
those = [];
|
||||
|
||||
function check(obj) {
|
||||
return obj instanceof SpriteMorph && obj.isClone ?
|
||||
return obj instanceof SpriteMorph && obj.isTemporary ?
|
||||
obj.cloneOriginName === name : obj.name === name;
|
||||
}
|
||||
|
||||
|
@ -3006,13 +3006,14 @@ Process.prototype.reportGet = function (query) {
|
|||
objName = thisObj.name || thisObj.cloneOriginName;
|
||||
return new List(
|
||||
stage.children.filter(function (each) {
|
||||
return each.isClone &&
|
||||
return each.isTemporary &&
|
||||
(each !== thisObj) &&
|
||||
(each.cloneOriginName === objName);
|
||||
})
|
||||
);
|
||||
case 'other clones':
|
||||
return thisObj.isClone ? this.reportGet(['clones']) : new List();
|
||||
return thisObj.isTemporary ?
|
||||
this.reportGet(['clones']) : new List();
|
||||
case 'neighbors':
|
||||
stage = thisObj.parentThatIsA(StageMorph);
|
||||
neighborhood = thisObj.bounds.expandBy(new Point(
|
||||
|
|
4
ypr.js
4
ypr.js
|
@ -8,7 +8,7 @@ The above copyright notice and this permission notice shall be included in all c
|
|||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Last changed 2013-04-03 by Jens Moenig (disabled text area overlay)
|
||||
Last changed 2017-07-04 by Jens Moenig (disabled text area overlay, introduced Sprite::isTemporary)
|
||||
|
||||
*/
|
||||
|
||||
|
@ -392,7 +392,7 @@ var sb = (function (sb) {
|
|||
|
||||
sb.addFields(-1, 'Slider', 'BorderedMorph', 'slider,value,setValueSelector,sliderShadow,sliderColor,descending,model');
|
||||
sb.addFields(-2, 'AbstractSound', '', '');
|
||||
sb.addFields(-3, 'ScriptableScratchMorph', 'Morph', 'objName,vars,blocksBin,customBlocks,isClone,media,costume');
|
||||
sb.addFields(-3, 'ScriptableScratchMorph', 'Morph', 'objName,vars,blocksBin,customBlocks,isTemporary,media,costume');
|
||||
sb.addFields(-4, 'ArgMorph', 'BorderedMorph', 'labelMorph');
|
||||
sb.addFields(-5, 'PasteUpMorph', 'BorderedMorph', '');
|
||||
sb.addFields(-6, 'ScratchMedia', '', 'mediaName');
|
||||
|
|
Ładowanie…
Reference in New Issue