-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathevent-class.lisp
66 lines (50 loc) · 2.57 KB
/
event-class.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
(in-package #:org.shirakumo.deeds)
(defclass event-class (cached-slots-class)
())
(defmethod c2mop:validate-superclass ((class event-class) (superclass t))
NIL)
(defmethod c2mop:validate-superclass ((class standard-class) (superclass event-class))
T)
(defmethod c2mop:validate-superclass ((class event-class) (superclass standard-class))
T)
(defmethod c2mop:validate-superclass ((class event-class) (superclass event-class))
T)
(defclass event-slot ()
((mutable :initarg :mutable :initform NIL :accessor event-slot-mutable))
(:documentation "Superclass for event slots with an option"))
(defclass event-direct-slot-definition (event-slot c2mop:standard-direct-slot-definition)
())
(defclass event-effective-slot-definition (event-slot c2mop:standard-effective-slot-definition)
())
(defun check-event-slots (class slot-forms)
(dolist (form slot-forms)
(when (and (not (getf form :mutable)) (getf form :writers))
(warn 'immutable-event-slot-has-writer :event class :slot (getf form :name) :writers (getf form :writers)))))
(defmethod initialize-instance :before ((class event-class) &key direct-slots &allow-other-keys)
(check-event-slots class direct-slots))
(defmethod reinitialize-instance :before ((class event-class) &key direct-slots &allow-other-keys)
(check-event-slots class direct-slots))
(defmethod c2mop:direct-slot-definition-class ((class event-class) &rest initargs)
(declare (ignore initargs))
(find-class 'event-direct-slot-definition))
(defmethod c2mop:effective-slot-definition-class ((class event-class) &rest initargs)
(declare (ignore initargs))
(find-class 'event-effective-slot-definition))
(defmethod c2mop:compute-effective-slot-definition ((class event-class) name direct-slots)
(declare (ignore name))
(let ((effective-slot (call-next-method)))
(dolist (direct-slot direct-slots)
(when (and (typep direct-slot 'event-direct-slot-definition)
(eql (c2mop:slot-definition-name direct-slot)
(c2mop:slot-definition-name effective-slot)))
(setf (event-slot-mutable effective-slot)
(event-slot-mutable direct-slot))
(return)))
effective-slot))
(defmethod (setf c2mop:slot-value-using-class) :before (value (class event-class) event (slotd event-slot))
(unless (event-slot-mutable slotd)
(cerror "Write to the slot anyway." 'immutable-event-slot-modified
:event event :slot (c2mop:slot-definition-name slotd) :value value)))
(defmacro with-immutable-slots-unlocked (() &body body)
`(handler-bind ((immutable-event-slot-modified #'continue))
,@body))