[cells-devel] Cells: Controlling the way kids are added to a parent ...
Frank Goenninger
frgo at me.com
Thu Oct 30 21:05:18 UTC 2008
... and again a question related to this:
Suppose I have :
(defmd kid-test-2 (family)
(a-slot (c-in nil))
:kids (list (make-instance 'my-kid)
(make-instance 'my-kid)))
Now - this completely bypasses the control mechanism inserted into fm-
kid-add - which is not what I wanted ;-)
So, I am asking myself if it would be better to insert the check into
the .kids observer ...
I now have:
(defmodel family (model)
((.kid-slots :cell nil
:initform nil
:accessor kid-slots
:initarg :kid-slots)
(.kids :initform (c-in nil) ;; most useful
:owning t
:accessor kids
:initarg :kids)
(registry? :cell nil
:initform nil
:initarg :registry?
:accessor registry?)
(registry :cell nil
:initform nil
:accessor registry)
;; added: frgo, 2008-10-30
(control-hooks :cell nil
:accessor control-hooks
:initform (make-hash-table :test 'eql)
:initarg :control-hooks)))
(defmethod get-control-hooks ((self family) hook-id)
(gethash hook-id (control-hooks self)))
(defmethod add-hook ((self family) id hook)
(setf (gethash id (control-hooks self)) hook))
(defun call-control-hook (hook self &rest args)
;;; to be completed here
)
(eval-when (:compile-time :load-toplevel)
(proclaim '(inline mklist))
(if (not (fboundp 'mklist))
(defun mklist (obj)
(if (listp obj)
obj
(list obj)))))
(defun run-control-hooks (id self &rest args)
(c-assert (typep self 'family))
(let ((hooks (get-control-hooks self id)))
(if hooks
(loop for hook in (get-control-hooks self id)
collect (call-control-hook hook self args)
into result
finally (return (mklist result)))
(mklist t))))
and
(define-condition cells-adding-kid-not-allowed-error (error)
((text :initarg :text :reader text)))
(defun kid-add-allowed? (fm-parent kid)
(notany #'null (run-control-hooks 'fm-kid-add-control fm-parent
kid)))
(defun fm-kid-add (fm-parent kid &optional before)
(c-assert (or (null (fm-parent kid)) (eql fm-parent (fm-parent
kid))))
(c-assert (typep fm-parent 'family))
;; Added: frgo, 2008-10-30
(if (kid-add-allowed? fm-parent kid)
(progn
;; (trc "Adding kid to parent" kid fm-parent)
(setf (fm-parent kid) fm-parent)
(fm-kid-insert kid before))
(error 'cells-adding-kid-not-allowed-error
:text (format nil
"ERROR: Kid ~s not allowed for parent
~s." kid fm-parent))))
- which is incomplete, of course, but shows the basic idea, or so I
hope.
Any thoughts if I should use the observer or do some clever slot
trickery using MOP ?
Thanks for feedback!
Regards
Frank
Am 30.10.2008 um 13:15 schrieb Frank Goenninger:
> * PGP Signed: 10/30/08 at 13:15:51
>
> Hi -
>
> I want to control if a kid is added to a parent based on the
> execution of a check function. The check function is supposed to
> throw an condition when the check fails.
>
> Current use case:
>
> Control which classes of kids are added to a parent. I do have a
> model of class BOM (bill of material) that only can accept classes
> Assembly and Part as kids.
>
> I found two places at which I could insert a call to the check
> function:
>
> function fm-kid-add (higher level interface)
> function fm-kid-insert (lower level interface)
>
> Question now is: Why would one be better than the other?
>
> Idea here is based on adding a new slot to class family:
>
> (defmodel family (model)
> ((.kid-slots :cell nil
> :initform nil
> :accessor kid-slots
> :initarg :kid-slots)
> (.kids :initform (c-in nil) ;; most useful
> :owning t
> :accessor kids
> :initarg :kids)
> (registry? :cell nil
> :initform nil
> :initarg :registry?
> :accessor registry?)
> (registry :cell nil
> :initform nil
> :accessor registry)
> ;; added: frgo, 2008-10-30 -----
> (kid-add-control-hook :cell nil
> :initform nil
> :initarg: kid-add-control-hook)))
>
> and then do run the check functions that have been added to the
> control hook (= list of functions to be funcalled).
>
> Right approach? Any comments? (It works but I'd like to know if am
> on the right track).
>
> Thanks for feedback.
>
> Cheers
> Frank
>
>
>
>
>
> * Frank Goenninger <frgo at me.com>
> * 0xE6BDA9B9:0x6AEA9601
> _______________________________________________
> cells-devel site list
> cells-devel at common-lisp.net
> http://common-lisp.net/mailman/listinfo/cells-devel
>
>
> * PGP Signed: 10/30/08 at 13:15:51
> * text/plain body
> * Frank Goenninger <frgo at me.com>
> * 0xE6BDA9B9:0x6AEA9601
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 859 bytes
Desc: not available
URL: <https://mailman.common-lisp.net/pipermail/cells-devel/attachments/20081030/473725d1/attachment.sig>
More information about the cells-devel
mailing list