I want to show ObjectVirus, special kind of ClassGhost.
But first let's look at ClassGhost. It is ghost which can play role of object classes. ClassGhost can substitute class of objects and intercept all their messages. And as ghost it intercepts all direct messages too. So concrete implementation should decide how ghost should behave itself and how normal objects should behave when they are "infected" by ghost. Subclasses of GHClassGhost should implement two kind of behaviour: #ghostBehaviour (as any other ghost) and #instancesBehaviour (to process messages to "infected" objects).
ObjectVirus makes these decisions. It delegates all direct messages to victim class. By looking at virus you will not see any difference from class which it substitutes.
And to process messages to infected objects you should define concrete ghost behaviour:
Now let's play with virus. I want to infect morphs on screen such way that when infected morph will touch another morph it will paint it by own color. For this we need to implement special behaviour. Let's call it MorphsColoring:
We increase current meta level here to escape possible recursion when we interact with surrounding objects. Without it "aMorph color" will produce recursive call to behaviour to process message #color which will lead to infinite recursion. When message is sent inside meta level it will not intercepted by behaviour. And in case of virus it will be performed by original method of infected object.
Now lets infect some morph by virus and play with it:
P.S. ObjectVirus is now renamed to ObjectMutation with all related messages
But first let's look at ClassGhost. It is ghost which can play role of object classes. ClassGhost can substitute class of objects and intercept all their messages. And as ghost it intercepts all direct messages too. So concrete implementation should decide how ghost should behave itself and how normal objects should behave when they are "infected" by ghost. Subclasses of GHClassGhost should implement two kind of behaviour: #ghostBehaviour (as any other ghost) and #instancesBehaviour (to process messages to "infected" objects).
ObjectVirus makes these decisions. It delegates all direct messages to victim class. By looking at virus you will not see any difference from class which it substitutes.
And to process messages to infected objects you should define concrete ghost behaviour:
virus := GHObjectVirus behaviour: aGhostBehaviour.To substitute class of object you should infect it by virus:
virus infect: anObjectThen you can detect infection by:
infectedObject isInfectedByVirus.And you can recover it:
infectedObject virus
infectedObject recoverFromVirusor
virus heal: infectedObjectVirus related methods are defined in Object too. So you can ask any object about it.
Now let's play with virus. I want to infect morphs on screen such way that when infected morph will touch another morph it will paint it by own color. For this we need to implement special behaviour. Let's call it MorphsColoring:
GHGhostBehaviour subclass: #MorphsColoringMorphsColoring >>send: aMessage to: aMorph
instanceVariableNames: ''
classVariableNames: ''
package: 'MyWork'
| bounds color |For any message to infected morph it executes morph original method and performs extra virus side effect. It will scan all morphs on screen to detect "touching" morphs. And it will paint them by own color.
GHCurrentMetaLevelDepth increaseFor: [
color := aMorph color.
bounds := aMorph bounds.
^[GHVictimMetaMessages executeOriginalMethodOf: aMorph for: aMessage]
ensure: [
(World submorphsSatisfying: [ :each |
each ~~ aMorph and: [ each bounds intersects: bounds] ])
do: [:each | each color: color].
]
]
We increase current meta level here to escape possible recursion when we interact with surrounding objects. Without it "aMorph color" will produce recursive call to behaviour to process message #color which will lead to infinite recursion. When message is sent inside meta level it will not intercepted by behaviour. And in case of virus it will be performed by original method of infected object.
Now lets infect some morph by virus and play with it:
virus := GHObjectVirus behaviour: MorphsColoring new.
morph := Morph new.
virus infect: morph.
morph openInWorld.
P.S. ObjectVirus is now renamed to ObjectMutation with all related messages
Комментариев нет:
Отправить комментарий