diff options
| author | Jens Mönig <jens@moenig.org> | 2015-03-21 11:12:43 +0100 |
|---|---|---|
| committer | Jens Mönig <jens@moenig.org> | 2015-03-21 11:12:43 +0100 |
| commit | 4acf1896bd9fa57d3dbe3f4721b6790c6f3b0d56 (patch) | |
| tree | 8d44be9ed6bb5458d4354d59200783669dbc5cb2 /threads.js | |
| parent | fdd2ecf7d91d8026d3ca42c4bd52774877c72645 (diff) | |
| download | snap-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.js | 73 |
1 files changed, 51 insertions, 22 deletions
@@ -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; } + } }; |
