1 ! Copyright (C) 2006 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: generic kernel math sequences timers ;
6 TUPLE: model value connections dependencies ref ;
8 C: model ( value -- model )
9 [ set-model-value ] keep
10 V{ } clone over set-model-connections
11 V{ } clone over set-model-dependencies
12 0 over set-model-ref ;
16 : add-dependency ( dep model -- )
17 model-dependencies push ;
19 : remove-dependency ( dep model -- )
20 model-dependencies delete ;
24 GENERIC: model-activated ( model -- )
26 M: model model-activated drop ;
28 : ref-model ( model -- n )
29 dup model-ref 1+ dup rot set-model-ref ;
31 : unref-model ( model -- n )
32 dup model-ref 1- dup rot set-model-ref ;
34 : activate-model ( model -- )
36 dup model-dependencies
37 [ dup activate-model dupd add-connection ] each
43 DEFER: remove-connection
45 : deactivate-model ( model -- )
46 dup unref-model zero? [
47 dup model-dependencies
48 [ dup deactivate-model remove-connection ] each-with
53 GENERIC: model-changed ( observer -- )
55 : add-connection ( observer model -- )
56 dup model-connections empty? [ dup activate-model ] when
57 model-connections push ;
59 : remove-connection ( observer model -- )
60 [ model-connections delete ] keep
61 dup model-connections empty? [ dup deactivate-model ] when
64 GENERIC: set-model ( value model -- )
67 [ set-model-value ] keep
68 model-connections [ model-changed ] each ;
70 : ((change-model)) ( model quot -- newvalue model )
71 over >r >r model-value r> call r> ; inline
73 : change-model ( model quot -- )
74 ((change-model)) set-model ; inline
76 : (change-model) ( model quot -- )
77 ((change-model)) set-model-value ; inline
79 : delegate>model ( tuple -- )
80 f <model> swap set-delegate ;
82 TUPLE: filter model quot ;
84 C: filter ( model quot -- filter )
86 [ set-filter-quot ] keep
87 [ set-filter-model ] 2keep
88 [ add-dependency ] keep ;
90 M: filter model-changed
91 dup filter-model model-value over filter-quot call
94 M: filter model-activated model-changed ;
98 C: compose ( models -- compose )
100 swap clone over set-model-dependencies ;
102 M: compose model-changed
103 dup model-dependencies [ model-value ] map
104 swap delegate set-model ;
106 M: compose model-activated model-changed ;
109 model-dependencies [ set-model ] 2each ;
111 TUPLE: history back forward ;
113 C: history ( value -- history )
114 [ >r <model> r> set-delegate ] keep
115 V{ } clone over set-history-back
116 V{ } clone over set-history-forward ;
119 swap model-value dup [ swap push ] [ 2drop ] if ;
121 : go-back/forward ( history to from -- )
124 [ >r dupd (add-history) r> pop swap set-model ] if ;
126 : go-back ( history -- )
127 dup history-forward over history-back go-back/forward ;
129 : go-forward ( history -- )
130 dup history-back over history-forward go-back/forward ;
132 : add-history ( history -- )
133 dup history-forward delete-all
134 dup history-back (add-history) ;
136 TUPLE: delay model timeout ;
138 : update-delay-model ( delay -- )
139 dup delay-model model-value swap set-model ;
141 C: delay ( model timeout -- filter )
143 [ set-delay-timeout ] keep
144 [ set-delay-model ] 2keep
145 [ add-dependency ] keep
146 dup update-delay-model ;
148 M: delay model-changed 0 over delay-timeout add-timer ;
150 M: delay model-activated update-delay-model ;
152 M: delay tick dup remove-timer update-delay-model ;