summaryrefslogtreecommitdiff
path: root/threads.js
diff options
context:
space:
mode:
authorJens Mönig <jens@moenig.org>2015-03-21 11:12:43 +0100
committerJens Mönig <jens@moenig.org>2015-03-21 11:12:43 +0100
commit4acf1896bd9fa57d3dbe3f4721b6790c6f3b0d56 (patch)
tree8d44be9ed6bb5458d4354d59200783669dbc5cb2 /threads.js
parentfdd2ecf7d91d8026d3ca42c4bd52774877c72645 (diff)
downloadsnap-4acf1896bd9fa57d3dbe3f4721b6790c6f3b0d56.tar.gz
snap-4acf1896bd9fa57d3dbe3f4721b6790c6f3b0d56.zip
Prototypal inheritance of sprite-local variables
(experimental) slotwise inheritance à la Henry Lieberman for sprite-local variables. see http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.htm l Let a sprite inherit another sprite’s local variables by making it the “parent” in the sprite-icon’s context menu (the button icon in the sprite corral underneath the stage). The child not only inherits the variable slot but also - dynamically - the parent variable’s value. Changing the parent’s variable value also changes it for every child. If a child uses SET or CHANGE on an inherited variable it automatically “shadows” it with its own value, thereby stopping dynamic participation in the parent slot’s value (in effect dis-inheriting that slot). Deleting a shadowed variable slot once again reinstates its inheritance status. inherited variables are shown as “ghosted” both in the child’s variables palette and in such stage watchers. “Shadowing” them un-ghosts both the variable blob template in the palette and the watcher onstage (if any). Deleting a shadowed variable once again ghosts the watcher and the palette block template. Delete a (shadowed) variable either via the “Delete a variable” button in the IDE or using the new “Delete” block in the variables category
Diffstat (limited to 'threads.js')
-rw-r--r--threads.js73
1 files changed, 51 insertions, 22 deletions
diff --git a/threads.js b/threads.js
index 50af8dd..d3dcfc9 100644
--- a/threads.js
+++ b/threads.js
@@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/
// Global stuff ////////////////////////////////////////////////////////
-modules.threads = '2015-February-28';
+modules.threads = '2015-March-21';
var ThreadManager;
var Process;
@@ -1159,7 +1159,7 @@ Process.prototype.doSetVar = function (varName, value) {
name = name.expression.blockSpec;
}
}
- varFrame.setVar(name, value);
+ varFrame.setVar(name, value, this.blockReceiver());
};
Process.prototype.doChangeVar = function (varName, value) {
@@ -1171,7 +1171,7 @@ Process.prototype.doChangeVar = function (varName, value) {
name = name.expression.blockSpec;
}
}
- varFrame.changeVar(name, value);
+ varFrame.changeVar(name, value, this.blockReceiver());
};
Process.prototype.reportGetVar = function () {
@@ -1295,6 +1295,20 @@ Process.prototype.doRemoveTemporaries = function () {
}
};
+// Process sprite inheritance primitives
+
+Process.prototype.doDeleteAttr = function (attrName) {
+ // currently only variables are deletable
+ var name = attrName;
+
+ if (name instanceof Context) {
+ if (name.expression.selector === 'reportGetVar') {
+ name = name.expression.blockSpec;
+ }
+ }
+ this.blockReceiver().deleteVariable(name);
+};
+
// Process lists primitives
Process.prototype.reportNewList = function (elements) {
@@ -3103,35 +3117,50 @@ VariableFrame.prototype.silentFind = function (name) {
return null;
};
-VariableFrame.prototype.setVar = function (name, value) {
-/*
- change the specified variable if it exists
- else throw an error, because variables need to be
- declared explicitly (e.g. through a "script variables" block),
- before they can be accessed.
-*/
+VariableFrame.prototype.setVar = function (name, value, sender) {
+ // change the specified variable if it exists
+ // else throw an error, because variables need to be
+ // declared explicitly (e.g. through a "script variables" block),
+ // before they can be accessed.
+ // if the found frame is inherited by the sender sprite
+ // shadow it (create an explicit one for the sender)
+ // before setting the value ("create-on-write")
+
var frame = this.find(name);
if (frame) {
- frame.vars[name].value = value;
+ if (sender instanceof SpriteMorph &&
+ (frame.owner instanceof SpriteMorph) &&
+ (sender !== frame.owner)) {
+ sender.shadowVar(name, value);
+ } else {
+ frame.vars[name].value = value;
+ }
}
};
-VariableFrame.prototype.changeVar = function (name, delta) {
-/*
- change the specified variable if it exists
- else throw an error, because variables need to be
- declared explicitly (e.g. through a "script variables" block,
- before they can be accessed.
-*/
+VariableFrame.prototype.changeVar = function (name, delta, sender) {
+ // change the specified variable if it exists
+ // else throw an error, because variables need to be
+ // declared explicitly (e.g. through a "script variables" block,
+ // before they can be accessed.
+ // if the found frame is inherited by the sender sprite
+ // shadow it (create an explicit one for the sender)
+ // before changing the value ("create-on-write")
+
var frame = this.find(name),
- value;
+ value,
+ newValue;
if (frame) {
value = parseFloat(frame.vars[name].value);
- if (isNaN(value)) {
- frame.vars[name].value = delta;
+ newValue = isNaN(value) ? delta : value + parseFloat(delta);
+ if (sender instanceof SpriteMorph &&
+ (frame.owner instanceof SpriteMorph) &&
+ (sender !== frame.owner)) {
+ sender.shadowVar(name, newValue);
} else {
- frame.vars[name].value = value + parseFloat(delta);
+ frame.vars[name].value = newValue;
}
+
}
};