(initfunctions :initform nil)
(attribute-class :accessor attribute-class
:initarg :attribute-class
- :initform 'standard-attribute)
+ :initform 'standard-attribute
+ :layered t)
(name :layered-accessor attribute-name
:initarg :name)
(label :layered-accessor attribute-label
(print-unreadable-object (object stream :type nil :identity t)
(format stream "ATTRIBUTE ~A" (or (ignore-errors (attribute-name object)) "+unnamed-attribute+"))))
+(defgeneric eval-property-initarg (att initarg)
+ (:method ((attribute standard-attribute) initarg)
+ nil)
+ (:method ((attribute standard-attribute) (initarg (eql :function)))
+ t))
+
+(defun prepare-initargs (att args)
+ (loop
+ :for (key arg)
+ :on args :by #'cddr
+ :nconc (list key
+ (if (eval-property-initarg att key)
+ (eval arg)
+ arg))))
+
(defvar *bypass-property-layered-function* nil)
(define-layered-function property-layered-function (description attribute-name property-name)
:in-layer (context t)
(new-value class (attribute standard-attribute) property writer)
- (when (or *bypass-property-layered-function*
- (not (slot-definition-layeredp property)))
+ (when (or *bypass-property-layered-function*)
(return-from slot-value-using-layer (call-next-method)))
(ensure-layered-method
fn
`(lambda (description)
- ,new-value)
+ (funcall ,(lambda()
+ new-value)))
:in-layer layer
:specializers (list (class-of (attribute-description attribute)
))))))
(if (slot-boundp attribute 'description-class)
(do-set-slot)
- (push (lambda () (do-set-slot))
- (slot-value attribute 'initfunctions))))))
+ (error "serrint wif no desc WTF!")))))
(define-layered-method slot-value-using-layer
:in-layer (layer t)
:around (class (attribute standard-attribute) property reader)
- ;(dprint "Getting the slot value of ~A" property)
-
- (when (not (slot-boundp-using-class class attribute property))
- ;; If the slot is unbound, we search for its layered-function
-
- (let ((fn (property-layered-function
- (attribute-description attribute)
- (attribute-name attribute)
- (closer-mop:slot-definition-name property))))
- (dprint ".. not bound yet, have function ~A" fn)
- (if (generic-function-methods fn)
- (let ((*bypass-property-layered-function* t))
- ; (dprint " This shit has been bound!. We gona set the _real_ slot to the generic function like.")
- (setf (slot-value-using-class class attribute property) fn))
- (progn
- ;(dprint "This shit aint never been bound nowhere! checking for initfunction...")
- (when (slot-definition-initfunction property)
- ;(dprint "At least we have an initfunction. sweeet")
- (let ((*bypass-property-layered-function* nil))
- (setf (slot-value attribute (slot-definition-name property))
- (funcall (slot-definition-initfunction property)))))))))
-
- ;(dprint "If we're here, the slot should be bound")
+ ;; (dprint "Getting the slot value of ~A" property)
+ ;; We do some magic in here and i thought it
+ ;; would be called magically in call-next-method.
+ ;; This explicit call is good enough for now.
+
+ (unless (slot-boundp-using-class class attribute property)
+ (slot-unbound class attribute (slot-definition-name property)))
+
+ (let ((val (call-next-method)))
- (if (and
+ (if (and
+ ;; Not special access
+ (not (symbolp val))
(contextl::slot-definition-layeredp property)
(not *bypass-property-layered-function*))
- (let ((fn (call-next-method)))
+ (let ((fn val))
;(dprint "... using fn ~A to get value" fn)
(funcall fn layer (attribute-description attribute)))
- (call-next-method)))
-
-
+ val)))
+(defmacro define-bypass-function (name function-name)
+ `(defun ,name (&rest args)
+ (let ((*bypass-property-layered-function* t))
+ (apply (function ,function-name) args))))
+(define-bypass-function real-slot-boundp-using-class slot-boundp-using-class)
+(define-bypass-function real-slot-value-using-class slot-value-using-class)
+(define-bypass-function (setf real-slot-value-using-class) (setf slot-value-using-class))
+
(defun slot-boundp-using-property-layered-function (class attribute property)
- (when (not
- (let ((*bypass-property-layered-function* t))
- (slot-boundp-using-class class attribute property)))
- ;; If the slot is unbound, we search for its layered-function
-
- (let ((fn (property-layered-function
- (attribute-description attribute)
-
+ ;(dprint "plf boundp:")
+ (let* ((really-bound-p
+ (real-slot-boundp-using-class class attribute property))
+ (fn (if really-bound-p
+ (real-slot-value-using-class class attribute property)
+ (setf (real-slot-value-using-class class attribute property)
+ (property-layered-function
+ (attribute-description attribute)
(attribute-name attribute)
- (closer-mop:slot-definition-name property))))
- (if (generic-function-methods fn)
- (let ((*bypass-property-layered-function* t))
- (setf (slot-value-using-class class attribute property) fn))
- NIL))))
+ (closer-mop:slot-definition-name property))))))
+
+ (if (symbolp fn)
+ ;;special symbol access in process
+ T
+ (if (generic-function-methods fn)
+ T
+ NIL))))
-#+nil(define-layered-method slot-boundp-using-layer
+(define-layered-method slot-boundp-using-layer
:in-layer (layer t)
:around (class (attribute standard-attribute) property reader)
(if *bypass-property-layered-function*