manage inheritance relationships when setting a prototype or deleting a sprite

upd4.1
Jens Mönig 2017-06-29 13:55:01 +02:00
rodzic f8980ad9ac
commit 5516fa1c7b
2 zmienionych plików z 58 dodań i 5 usunięć

Wyświetl plik

@ -3483,6 +3483,10 @@ Fixes:
* Objects: Inheritance of costumes and sounds - propagate changes * Objects: Inheritance of costumes and sounds - propagate changes
* Store: Tweaked loading sprites with inherited complex attributes (costumes, sounds) * Store: Tweaked loading sprites with inherited complex attributes (costumes, sounds)
170629
------
* Objects: manage inheritance relationships when setting a prototype or deleting a sprite
Features: Features:
* polymorphic sprite-local custom blocks * polymorphic sprite-local custom blocks

Wyświetl plik

@ -82,7 +82,7 @@ SpeechBubbleMorph, RingMorph, isNil, FileReader, TableDialogMorph,
BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize, BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph*/ TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph*/
modules.objects = '2017-June-27'; modules.objects = '2017-June-29';
var SpriteMorph; var SpriteMorph;
var StageMorph; var StageMorph;
@ -5129,6 +5129,7 @@ SpriteMorph.prototype.chooseExemplar = function () {
SpriteMorph.prototype.setExemplar = function (another) { SpriteMorph.prototype.setExemplar = function (another) {
var ide = this.parentThatIsA(IDE_Morph); var ide = this.parentThatIsA(IDE_Morph);
this.emancipate();
this.exemplar = another; this.exemplar = another;
if (isNil(another)) { if (isNil(another)) {
this.variables.parentFrame = (this.globalVariables()); this.variables.parentFrame = (this.globalVariables());
@ -5141,6 +5142,29 @@ SpriteMorph.prototype.setExemplar = function (another) {
} }
if (another) { if (another) {
another.cachedSpecimens = null; 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) {
child.shadowAllAttributes();
child.shadowAllMethods();
child.shadowAllVars();
});
this.cachedSpecimens = null;
};
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;
this.exemplar = null;
} }
}; };
@ -5188,6 +5212,13 @@ SpriteMorph.prototype.shadowedAttributes = function () {
}); });
}; };
SpriteMorph.prototype.shadowAllAttributes = function () {
var myself = this;
this.attributes.forEach(function (att) {
myself.shadowAttribute(att);
});
};
SpriteMorph.prototype.shadowAttribute = function (aName) { SpriteMorph.prototype.shadowAttribute = function (aName) {
var ide, wardrobe, jukebox, var ide, wardrobe, jukebox,
myself = this, myself = this,
@ -5335,6 +5366,13 @@ SpriteMorph.prototype.globalVariables = function () {
return current; return current;
}; };
SpriteMorph.prototype.shadowAllVars = function () {
var myself = this;
this.inheritedVariableNames().forEach(function (name) {
myself.shadowVar(name, myself.variables.getVar(name));
});
};
SpriteMorph.prototype.shadowVar = function (name, value) { SpriteMorph.prototype.shadowVar = function (name, value) {
var ide = this.parentThatIsA(IDE_Morph); var ide = this.parentThatIsA(IDE_Morph);
this.variables.addVar(name, value); this.variables.addVar(name, value);
@ -5429,6 +5467,18 @@ SpriteMorph.prototype.inheritedBlocks = function (valuesOnly) {
return dict; return dict;
}; };
SpriteMorph.prototype.shadowAllMethods = function () {
var ide = this.parentThatIsA(IDE_Morph),
myself = this;
this.inheritedMethods().forEach(function (dup) {
myself.customBlocks.push(dup);
});
if (ide) {
ide.flushPaletteCache();
ide.refreshPalette();
}
};
SpriteMorph.prototype.inheritedMethods = function () { SpriteMorph.prototype.inheritedMethods = function () {
// private - pre-serialization preparation // private - pre-serialization preparation
var myself = this; var myself = this;
@ -5619,10 +5669,9 @@ SpriteMorph.prototype.restoreLayers = function () {
// SpriteMorph destroying // SpriteMorph destroying
SpriteMorph.prototype.destroy = function () { SpriteMorph.prototype.destroy = function () {
// make sure to invalidate the specimens cache // make sure to sever all inheritance ties to other sprites
if (this.exemplar) { this.emancipate();
this.exemplar.cachedSpecimens = null; this.prune();
}
SpriteMorph.uber.destroy.call(this); SpriteMorph.uber.destroy.call(this);
}; };