kopia lustrzana https://github.com/backface/turtlestitch
cloning speedup
significantly speed up sprite cloning through partial shallow-copying of scripts and costumes instead of deep-duplicationdev
rodzic
d7479f90e4
commit
71333021d4
36
blocks.js
36
blocks.js
|
@ -145,11 +145,11 @@ radians, useBlurredShadows, SpeechBubbleMorph, modules, StageMorph,
|
||||||
fontHeight, TableFrameMorph, SpriteMorph, Context, ListWatcherMorph,
|
fontHeight, TableFrameMorph, SpriteMorph, Context, ListWatcherMorph,
|
||||||
CellMorph, DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph,
|
CellMorph, DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph,
|
||||||
Costume, IDE_Morph, BlockDialogMorph, BlockEditorMorph, localize, isNil,
|
Costume, IDE_Morph, BlockDialogMorph, BlockEditorMorph, localize, isNil,
|
||||||
isSnapObject*/
|
isSnapObject, copy*/
|
||||||
|
|
||||||
// Global stuff ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.blocks = '2016-May-02';
|
modules.blocks = '2016-May-04';
|
||||||
|
|
||||||
var SyntaxElementMorph;
|
var SyntaxElementMorph;
|
||||||
var BlockMorph;
|
var BlockMorph;
|
||||||
|
@ -3251,7 +3251,14 @@ BlockMorph.prototype.setCategory = function (aString) {
|
||||||
|
|
||||||
// BlockMorph copying
|
// BlockMorph copying
|
||||||
|
|
||||||
BlockMorph.prototype.fullCopy = function () {
|
BlockMorph.prototype.fullCopy = function (forClone) {
|
||||||
|
if (forClone) {
|
||||||
|
if (this.hasBlockVars()) {
|
||||||
|
forClone = false;
|
||||||
|
} else {
|
||||||
|
return copy(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
var ans = BlockMorph.uber.fullCopy.call(this);
|
var ans = BlockMorph.uber.fullCopy.call(this);
|
||||||
ans.removeHighlight();
|
ans.removeHighlight();
|
||||||
ans.isDraggable = true;
|
ans.isDraggable = true;
|
||||||
|
@ -3261,22 +3268,15 @@ BlockMorph.prototype.fullCopy = function () {
|
||||||
ans.allChildren().filter(function (block) {
|
ans.allChildren().filter(function (block) {
|
||||||
if (block instanceof SyntaxElementMorph) {
|
if (block instanceof SyntaxElementMorph) {
|
||||||
block.cachedInputs = null;
|
block.cachedInputs = null;
|
||||||
// if (block instanceof InputSlotMorph) {
|
|
||||||
// block.contents().clearSelection();
|
|
||||||
// } else
|
|
||||||
if (block.definition) {
|
if (block.definition) {
|
||||||
block.initializeVariables();
|
block.initializeVariables();
|
||||||
}
|
}
|
||||||
// } else if (block instanceof CursorMorph) {
|
|
||||||
// block.destroy();
|
|
||||||
}
|
}
|
||||||
return !isNil(block.comment);
|
return !isNil(block.comment);
|
||||||
}).forEach(function (block) {
|
}).forEach(function (block) {
|
||||||
var cmnt = block.comment.fullCopy();
|
var cmnt = block.comment.fullCopy();
|
||||||
block.comment = cmnt;
|
block.comment = cmnt;
|
||||||
cmnt.block = block;
|
cmnt.block = block;
|
||||||
//block.comment = null;
|
|
||||||
|
|
||||||
});
|
});
|
||||||
ans.cachedInputs = null;
|
ans.cachedInputs = null;
|
||||||
return ans;
|
return ans;
|
||||||
|
@ -3286,6 +3286,12 @@ BlockMorph.prototype.reactToTemplateCopy = function () {
|
||||||
this.forceNormalColoring();
|
this.forceNormalColoring();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockMorph.prototype.hasBlockVars = function () {
|
||||||
|
return this.anyChild(function (any) {
|
||||||
|
return any.definition && any.definition.variableNames.length;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// BlockMorph events
|
// BlockMorph events
|
||||||
|
|
||||||
BlockMorph.prototype.mouseClickLeft = function () {
|
BlockMorph.prototype.mouseClickLeft = function () {
|
||||||
|
@ -5177,7 +5183,7 @@ ScriptsMorph.prototype.init = function (owner) {
|
||||||
|
|
||||||
// ScriptsMorph deep copying:
|
// ScriptsMorph deep copying:
|
||||||
|
|
||||||
ScriptsMorph.prototype.fullCopy = function () {
|
ScriptsMorph.prototype.fullCopy = function (forClone) {
|
||||||
var cpy = new ScriptsMorph(),
|
var cpy = new ScriptsMorph(),
|
||||||
pos = this.position(),
|
pos = this.position(),
|
||||||
child;
|
child;
|
||||||
|
@ -5186,17 +5192,21 @@ ScriptsMorph.prototype.fullCopy = function () {
|
||||||
}
|
}
|
||||||
this.children.forEach(function (morph) {
|
this.children.forEach(function (morph) {
|
||||||
if (!morph.block) { // omit anchored comments
|
if (!morph.block) { // omit anchored comments
|
||||||
child = morph.fullCopy();
|
child = morph.fullCopy(forClone);
|
||||||
child.setPosition(morph.position().subtract(pos));
|
|
||||||
cpy.add(child);
|
cpy.add(child);
|
||||||
|
if (!forClone) {
|
||||||
|
child.setPosition(morph.position().subtract(pos));
|
||||||
if (child instanceof BlockMorph) {
|
if (child instanceof BlockMorph) {
|
||||||
child.allComments().forEach(function (comment) {
|
child.allComments().forEach(function (comment) {
|
||||||
comment.align(child);
|
comment.align(child);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
if (!forClone) {
|
||||||
cpy.adjustBounds();
|
cpy.adjustBounds();
|
||||||
|
}
|
||||||
return cpy;
|
return cpy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
4
gui.js
4
gui.js
|
@ -70,7 +70,7 @@ isSnapObject*/
|
||||||
|
|
||||||
// Global stuff ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.gui = '2016-May-02';
|
modules.gui = '2016-May-04';
|
||||||
|
|
||||||
// Declarations
|
// Declarations
|
||||||
|
|
||||||
|
@ -2835,7 +2835,7 @@ IDE_Morph.prototype.aboutSnap = function () {
|
||||||
module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn,
|
module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn,
|
||||||
world = this.world();
|
world = this.world();
|
||||||
|
|
||||||
aboutTxt = 'Snap! 4.0.7\nBuild Your Own Blocks\n\n'
|
aboutTxt = 'Snap! 4.0.7.1\nBuild Your Own Blocks\n\n'
|
||||||
+ 'Copyright \u24B8 2016 Jens M\u00F6nig and '
|
+ 'Copyright \u24B8 2016 Jens M\u00F6nig and '
|
||||||
+ 'Brian Harvey\n'
|
+ 'Brian Harvey\n'
|
||||||
+ 'jens@moenig.org, bh@cs.berkeley.edu\n\n'
|
+ 'jens@moenig.org, bh@cs.berkeley.edu\n\n'
|
||||||
|
|
|
@ -2908,10 +2908,15 @@ http://snap.berkeley.edu/run#cloud:Username=jens&ProjectName=PathFollower
|
||||||
http://snap.berkeley.edu/run#present:Username=jens&ProjectName=cartwheel
|
http://snap.berkeley.edu/run#present:Username=jens&ProjectName=cartwheel
|
||||||
http://snap.berkeley.edu/run#cloud:Username=jens&ProjectName=rotation
|
http://snap.berkeley.edu/run#cloud:Username=jens&ProjectName=rotation
|
||||||
|
|
||||||
|
* new Indonesian translation. Yay!! Thank you, Alexander Liu!!
|
||||||
* Translation updates: Slovenian, Portuguese, Chinese
|
* Translation updates: Slovenian, Portuguese, Chinese
|
||||||
* minor bug fixes
|
* minor bug fixes
|
||||||
|
|
||||||
== v4.0.7 ==== - first class sprites
|
== v4.0.7 ==== - first class sprites
|
||||||
|
|
||||||
|
160504
|
||||||
|
------
|
||||||
|
* Morphic, Objects, Blocks, Threads, GUI: Partially shallow-copy clones for speed
|
||||||
|
* new Estonian translation! Yay!! Thanks, Hasso Tepper!
|
||||||
|
|
||||||
|
== v4.0.7.1 ==== - cloning speed-up
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
/*global modules, contains*/
|
/*global modules, contains*/
|
||||||
|
|
||||||
modules.locale = '2016-May-02';
|
modules.locale = '2016-May-04';
|
||||||
|
|
||||||
// Global stuff
|
// Global stuff
|
||||||
|
|
||||||
|
|
23
morphic.js
23
morphic.js
|
@ -337,7 +337,7 @@
|
||||||
(c) an application
|
(c) an application
|
||||||
-------------------
|
-------------------
|
||||||
Of course, most of the time you don't want to just plain use the
|
Of course, most of the time you don't want to just plain use the
|
||||||
standard Morhic World "as is" out of the box, but write your own
|
standard Morphic World "as is" out of the box, but write your own
|
||||||
application (something like Scratch!) in it. For such an
|
application (something like Scratch!) in it. For such an
|
||||||
application you'll create your own morph prototypes, perhaps
|
application you'll create your own morph prototypes, perhaps
|
||||||
assemble your own "window frame" and bring it all to life in a
|
assemble your own "window frame" and bring it all to life in a
|
||||||
|
@ -1054,10 +1054,9 @@
|
||||||
|
|
||||||
// Global settings /////////////////////////////////////////////////////
|
// Global settings /////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio,
|
/*global window, HTMLCanvasElement, FileReader, Audio, FileList*/
|
||||||
FileList, getBlurredShadowSupport*/
|
|
||||||
|
|
||||||
var morphicVersion = '2016-February-24';
|
var morphicVersion = '2016-May-04';
|
||||||
var modules = {}; // keep track of additional loaded modules
|
var modules = {}; // keep track of additional loaded modules
|
||||||
var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug
|
var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug
|
||||||
|
|
||||||
|
@ -1938,7 +1937,7 @@ Rectangle.prototype.round = function () {
|
||||||
Rectangle.prototype.spread = function () {
|
Rectangle.prototype.spread = function () {
|
||||||
// round me by applying floor() to my origin and ceil() to my corner
|
// round me by applying floor() to my origin and ceil() to my corner
|
||||||
// expand by 1 to be on the safe side, this eliminates rounding
|
// expand by 1 to be on the safe side, this eliminates rounding
|
||||||
// artefacts caused by Safari's auto-scaling on retina displays
|
// artifacts caused by Safari's auto-scaling on retina displays
|
||||||
return this.origin.floor().corner(this.corner.ceil()).expandBy(1);
|
return this.origin.floor().corner(this.corner.ceil()).expandBy(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2090,6 +2089,20 @@ Node.prototype.forAllChildren = function (aFunction) {
|
||||||
aFunction.call(null, this);
|
aFunction.call(null, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Node.prototype.anyChild = function (aPredicate) {
|
||||||
|
// includes myself
|
||||||
|
var i;
|
||||||
|
if (aPredicate.call(null, this)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (i = 0; i < this.children.length; i += 1) {
|
||||||
|
if (this.children[i].anyChild(aPredicate)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
Node.prototype.allLeafs = function () {
|
Node.prototype.allLeafs = function () {
|
||||||
var result = [];
|
var result = [];
|
||||||
this.allChildren().forEach(function (element) {
|
this.allChildren().forEach(function (element) {
|
||||||
|
|
38
objects.js
38
objects.js
|
@ -82,7 +82,7 @@ SpeechBubbleMorph, RingMorph, isNil, FileReader, TableDialogMorph,
|
||||||
BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
|
BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
|
||||||
TableMorph, TableFrameMorph*/
|
TableMorph, TableFrameMorph*/
|
||||||
|
|
||||||
modules.objects = '2016-May-02';
|
modules.objects = '2016-May-04';
|
||||||
|
|
||||||
var SpriteMorph;
|
var SpriteMorph;
|
||||||
var StageMorph;
|
var StageMorph;
|
||||||
|
@ -1364,7 +1364,7 @@ SpriteMorph.prototype.init = function (globals) {
|
||||||
|
|
||||||
// SpriteMorph duplicating (fullCopy)
|
// SpriteMorph duplicating (fullCopy)
|
||||||
|
|
||||||
SpriteMorph.prototype.fullCopy = function () {
|
SpriteMorph.prototype.fullCopy = function (forClone) {
|
||||||
var c = SpriteMorph.uber.fullCopy.call(this),
|
var c = SpriteMorph.uber.fullCopy.call(this),
|
||||||
myself = this,
|
myself = this,
|
||||||
arr = [],
|
arr = [],
|
||||||
|
@ -1374,11 +1374,12 @@ SpriteMorph.prototype.fullCopy = function () {
|
||||||
c.color = this.color.copy();
|
c.color = this.color.copy();
|
||||||
c.blocksCache = {};
|
c.blocksCache = {};
|
||||||
c.paletteCache = {};
|
c.paletteCache = {};
|
||||||
c.scripts = this.scripts.fullCopy();
|
c.scripts = this.scripts.fullCopy(forClone);
|
||||||
c.scripts.owner = c;
|
c.scripts.owner = c;
|
||||||
c.variables = this.variables.copy();
|
c.variables = this.variables.copy();
|
||||||
c.variables.owner = c;
|
c.variables.owner = c;
|
||||||
c.customBlocks = [];
|
c.customBlocks = [];
|
||||||
|
if (!forClone) {
|
||||||
this.customBlocks.forEach(function (def) {
|
this.customBlocks.forEach(function (def) {
|
||||||
cb = def.copyAndBindTo(c);
|
cb = def.copyAndBindTo(c);
|
||||||
c.customBlocks.push(cb);
|
c.customBlocks.push(cb);
|
||||||
|
@ -1386,8 +1387,9 @@ SpriteMorph.prototype.fullCopy = function () {
|
||||||
block.definition = cb;
|
block.definition = cb;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
this.costumes.asArray().forEach(function (costume) {
|
this.costumes.asArray().forEach(function (costume) {
|
||||||
var cst = costume.copy();
|
var cst = forClone ? costume : costume.copy();
|
||||||
arr.push(cst);
|
arr.push(cst);
|
||||||
if (costume === myself.costume) {
|
if (costume === myself.costume) {
|
||||||
c.costume = cst;
|
c.costume = cst;
|
||||||
|
@ -1404,12 +1406,11 @@ SpriteMorph.prototype.fullCopy = function () {
|
||||||
c.anchor = null;
|
c.anchor = null;
|
||||||
c.parts = [];
|
c.parts = [];
|
||||||
this.parts.forEach(function (part) {
|
this.parts.forEach(function (part) {
|
||||||
var dp = part.fullCopy();
|
var dp = part.fullCopy(forClone);
|
||||||
dp.nestingScale = part.nestingScale;
|
dp.nestingScale = part.nestingScale;
|
||||||
dp.rotatesWithAnchor = part.rotatesWithAnchor;
|
dp.rotatesWithAnchor = part.rotatesWithAnchor;
|
||||||
c.attachPart(dp);
|
c.attachPart(dp);
|
||||||
});
|
});
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2834,12 +2835,30 @@ SpriteMorph.prototype.remove = function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpriteMorph cloning (experimental)
|
// SpriteMorph cloning
|
||||||
|
|
||||||
|
/*
|
||||||
|
clones are temporary, partially shallow copies of sprites that don't
|
||||||
|
appear as icons in the corral. Clones get deleted when the red stop button
|
||||||
|
is pressed. Shallow-copying clones' scripts and costumes makes spawning
|
||||||
|
very fast, so they can be used for particle system simulations.
|
||||||
|
This speed-up, however, comes at the cost of some detrimental side
|
||||||
|
effects: Changes to a costume or a script of the original sprite are
|
||||||
|
in some cases shared with all of its clones, however such shared changes
|
||||||
|
are hard to predict for users and not actively propagated, so they don't
|
||||||
|
offer any reliable feature, and will not be supported as such.
|
||||||
|
Changes to the original sprite's scripts affect all of its clones, unless
|
||||||
|
the script contains any custom block whose definition contains one or more
|
||||||
|
block variables (in which case the script does get deep-copied).
|
||||||
|
The original sprite's scripting area, costumes wardrobe or sounds jukebox
|
||||||
|
are also not shared. therefore adding or deleting a script, sound or
|
||||||
|
costume in the original sprite has no effect on any of its clones.
|
||||||
|
*/
|
||||||
|
|
||||||
SpriteMorph.prototype.createClone = function () {
|
SpriteMorph.prototype.createClone = function () {
|
||||||
var stage = this.parentThatIsA(StageMorph);
|
var stage = this.parentThatIsA(StageMorph);
|
||||||
if (stage && stage.cloneCount <= 1000) {
|
if (stage && stage.cloneCount <= 2000) {
|
||||||
this.fullCopy().clonify(stage);
|
this.fullCopy(true).clonify(stage);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6636,7 +6655,6 @@ Costume.prototype.copy = function () {
|
||||||
var canvas = newCanvas(this.extent()),
|
var canvas = newCanvas(this.extent()),
|
||||||
cpy,
|
cpy,
|
||||||
ctx;
|
ctx;
|
||||||
|
|
||||||
ctx = canvas.getContext('2d');
|
ctx = canvas.getContext('2d');
|
||||||
ctx.drawImage(this.contents, 0, 0);
|
ctx.drawImage(this.contents, 0, 0);
|
||||||
cpy = new Costume(canvas, this.name ? copy(this.name) : null);
|
cpy = new Costume(canvas, this.name ? copy(this.name) : null);
|
||||||
|
|
|
@ -61,7 +61,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy,
|
||||||
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph,
|
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph,
|
||||||
TableFrameMorph, isSnapObject*/
|
TableFrameMorph, isSnapObject*/
|
||||||
|
|
||||||
modules.threads = '2016-May-02';
|
modules.threads = '2016-May-04';
|
||||||
|
|
||||||
var ThreadManager;
|
var ThreadManager;
|
||||||
var Process;
|
var Process;
|
||||||
|
@ -354,7 +354,7 @@ ThreadManager.prototype.doWhen = function (block, stopIt) {
|
||||||
if (invoke(
|
if (invoke(
|
||||||
pred,
|
pred,
|
||||||
null,
|
null,
|
||||||
null,
|
block.receiver(), // needed for shallow copied clones - was null
|
||||||
50,
|
50,
|
||||||
'the predicate takes\ntoo long for a\ncustom hat block',
|
'the predicate takes\ntoo long for a\ncustom hat block',
|
||||||
true // suppress errors => handle them right here instead
|
true // suppress errors => handle them right here instead
|
||||||
|
|
Ładowanie…
Reference in New Issue