In principle a rule should be a part of the definition of a model, and the things that change between instances should be parameters to that rule, which would be slots of the instance. It might be worth to rethink the way you are trying to model your problem domain. That said, it is certainly possible by using initargs, or, if you want to actually change the rule when the instance is live, by parametrizing on a lambda. Note that dependencies are formed dynamically, so you can call arbitrary code and still have it linked. Examples:hewih wrote:does anybody know how to apply rules in Cells on class instances? i can only find examples for class definitions.
Code: Select all
(defmodel starship ()
((x :accessor x-of :initform (c-in 0))
(y :accessor y-of :initform (c-in 0))))
(defparameter *starship* (make-instance 'starship))
(defmodel sidekick-parametrized ()
((mothership :accessor mothership-of :initarg :mothership)
(x-offset :accessor x-offset-of :initform (c-in 0) :initarg :x-offset)
(y-offset :accessor y-offset-of :initform (c-in 0) :initarg :y-offset)
(x :reader x-of :initform (c? (+ (x-offset-of self) (x-of (mothership-of self)))))
(y :reader y-of :initform (c? (+ (y-offset-of self) (y-of (mothership-of self)))))))
(defparameter *sidekick-param* (make-instance 'sidekick-parametrized :mothership (c-in *starship*) :x-offset (c-in 10)))
(defmodel sidekick-instance-rules ()
((mothership :accessor mothership-of :initarg :mothership)
(x :reader x-of :initarg :x)
(y :reader y-of :initarg :y)))
(defparameter *sidekick-rules*
(make-instance 'sidekick-instance-rules
:mothership *starship*
:x (c? (+ (x-of (mothership-of self))
10))
:y (c? (y-of (mothership-of self)))))
(defmodel sidekick-lambda-rules ()
((mothership :accessor mothership-of :initarg :mothership)
(x-rule :accessor x-rule-of :initarg :x-rule)
(y-rule :accessor y-rule-of :initarg :y-rule)
(x :reader x-of :initform (c? (funcall (x-rule-of self) (mothership-of self))))
(y :reader y-of :initform (c? (funcall (y-rule-of self) (mothership-of self))))))
(defparameter *sidekick-lambda-rules*
(make-instance 'sidekick-lambda-rules
:mothership *starship*
:x-rule (c-in (lambda (mothership)
(+ (x-of mothership) 10)))
:y-rule (c-in (lambda (mothership)
(y-of mothership)))))
Code: Select all
CL-USER> *starship*
#<STARSHIP {B0D5621}>
CL-USER> (x-of *starship*)
0
CL-USER> (y-of *starship*)
0
CL-USER> (x-of *sidekick-param*)
10
CL-USER> (y-of *sidekick-param*)
0
CL-USER> (x-of *sidekick-rules*)
10
CL-USER> (y-of *sidekick-rules*)
0
CL-USER> (x-of *sidekick-lambda-rules*)
10
CL-USER> (y-of *sidekick-lambda-rules*)
0
CL-USER> (setf (x-of *starship*) 357)
357
CL-USER> (x-of *starship*)
357
CL-USER> (x-of *sidekick-param*)
367
CL-USER> (x-of *sidekick-rules*)
367
CL-USER> (x-of *sidekick-lambda-rules*)
367