[closer-devel] Metacircular layer activation

Pascal Costanza pc at p-cos.net
Fri Mar 10 16:25:23 UTC 2006


Hi,

I have finally added a metaobject protocol to ContextL. The changes  
are as follows:

- A layer is an instance of a ContextL-specific metaclass. By  
default, it is the metaclass standard-layer-class. You can derive  
your own metaclasses from that class and declare a layer definition  
to be an instance of your new metaclass. For example:

(deflayer some-layer (... some super layers ...)
   (... some slots ...)
   (:layer-class my-layer-class))

- There are two layered functions activate-layer-using-class and  
deactivate-layer-using-class. You can specialize them and/or put them  
in your own layers. All layer activations/deactivations go through  
those layered functions. For example:

(define-layered-method activate-layer-using-class :in-layer some-layer
    ((layer my-layer-class) active-layers)
    ...)

These layered functions return two values: A new list of active  
layers and a boolean flag indicating whether the result can be cached  
or not. If the second return value is true, activate-layer-using- 
class won't be called anymore for the same list of active layers, but  
the previously computed value will be reused. The same holds for  
deactivate-layer-using-class.

See the file grouped-layers.lisp in the test folder in the darcs  
repository for an example of how to use those two layered functions.

There is not a lot what you can do with the second parameter (active- 
layers) apart from passing it (implicitly or explicitly) to call-next- 
method. I may add more functionality here in the future. Suggestions  
are welcome.

- Important: In order to make this metacircular implementation work,  
I had to change the semantics of ContextL somewhat. Consider the  
following activations of layers:

(with-active-layers (a)
   (with-active-layers (b)
     (with-active-layers (a)
        ... contained code ... )))

Until recently, the contained code has seen the layers a and b active  
in that order. This was because an activation of an already active  
layer has lead to a deactivation of that layer with an immediate  
reactivation, so that it was guaranteed that that layer would be in  
front of all other layers.

Since today, this has changed. Now the contained code sees the layer  
b and a active in that order. In other words, it is just checked  
whether the layer is already active somewhere, and if so, the list of  
active layers will remain unchanged. This was important in order to  
get layer activation/deactivation right in conjunction with  
inheritance between layers.

I hope this doesn't break any existing code. If you need the previous  
behavior, it should be possible to get it to work by specializing  
activate-layer-using-class and deactivate-layer-using-class. (Cool,  
eh? ;)


Cheers,
Pascal

-- 
Pascal Costanza, mailto:pc at p-cos.net, http://p-cos.net
Vrije Universiteit Brussel, Programming Technology Lab
Pleinlaan 2, B-1050 Brussel, Belgium







More information about the closer-devel mailing list