4
4
from .system import create_reactive_system
5
5
6
6
__all__ = [
7
- 'start_batch' ,
8
- 'end_batch' ,
9
- 'pause_tracking' ,
10
- 'resume_tracking' ,
11
- 'signal' ,
12
- 'computed' ,
13
- 'effect' ,
14
- 'effect_scope' ,
7
+ 'start_batch' ,
8
+ 'end_batch' ,
9
+ 'pause_tracking' ,
10
+ 'resume_tracking' ,
11
+ 'signal' ,
12
+ 'computed' ,
13
+ 'effect' ,
14
+ 'effect_scope' ,
15
15
]
16
16
17
17
18
18
class _Stack :
19
- def __init__ (self ):
20
- self .pause_stack = []
21
- self .bacth_depth = 0
22
- self .active_sub = None
23
- self .active_scope = None
19
+ def __init__ (self ):
20
+ self .pause_stack = []
21
+ self .bacth_depth = 0
22
+ self .active_sub = None
23
+ self .active_scope = None
24
+
24
25
25
26
_ = _Stack ()
26
27
27
28
28
29
def update_computed (computed ):
29
- prev_sub = _ .active_sub
30
- _ .active_sub = computed
31
- start_tracking (computed )
32
- try :
33
- old_value = computed .current_value
34
- new_value = computed .getter (old_value )
35
- if old_value != new_value :
36
- computed .current_value = new_value
37
- return True
38
- return False
39
- finally :
40
- _ .active_sub = prev_sub
41
- end_tracking (computed )
30
+ prev_sub = _ .active_sub
31
+ _ .active_sub = computed
32
+ start_tracking (computed )
33
+ try :
34
+ old_value = computed .current_value
35
+ new_value = computed .getter (old_value )
36
+ if old_value != new_value :
37
+ computed .current_value = new_value
38
+ return True
39
+ return False
40
+ finally :
41
+ _ .active_sub = prev_sub
42
+ end_tracking (computed )
43
+
42
44
43
45
rs = create_reactive_system (
44
- update_computed ,
45
- lambda e : notify_effect_scope (e ) if hasattr (e , 'is_scope' ) else notify_effect (e )
46
+ update_computed ,
47
+ lambda e : notify_effect_scope (e ) if hasattr (e , 'is_scope' ) else notify_effect (e ),
46
48
)
47
49
48
50
link = rs .link
@@ -56,158 +58,162 @@ def update_computed(computed):
56
58
57
59
58
60
def start_batch ():
59
- _ .bacth_depth += 1
61
+ _ .bacth_depth += 1
60
62
61
63
62
64
def end_batch ():
63
- _ .bacth_depth -= 1
64
- if not _ .bacth_depth :
65
- process_effect_notifications ()
65
+ _ .bacth_depth -= 1
66
+ if not _ .bacth_depth :
67
+ process_effect_notifications ()
66
68
67
69
68
70
def pause_tracking ():
69
- _ .pause_stack .append (_ .active_sub )
70
- _ .active_sub = None
71
+ _ .pause_stack .append (_ .active_sub )
72
+ _ .active_sub = None
71
73
72
74
73
75
def resume_tracking ():
74
- _ .active_sub = _ .pause_stack .pop ()
76
+ _ .active_sub = _ .pause_stack .pop ()
75
77
76
78
77
79
class _Signal :
78
- def __init__ (self , initial_value ):
79
- self .current_value = initial_value
80
- self .subs = None
81
- self .subs_tail = None
82
-
83
- def __call__ (self , * args ):
84
- if len (args ):
85
- self .value = args [0 ]
86
- else :
87
- return self .value
80
+ def __init__ (self , initial_value ):
81
+ self .current_value = initial_value
82
+ self .subs = None
83
+ self .subs_tail = None
84
+
85
+ def __call__ (self , * args ):
86
+ if len (args ):
87
+ self .value = args [0 ]
88
+ else :
89
+ return self .value
90
+
91
+ @property
92
+ def value (self ):
93
+ if _ .active_sub != None :
94
+ link (self , _ .active_sub )
95
+ return self .current_value
96
+
97
+ @value .setter
98
+ def value (self , value ):
99
+ if self .current_value != value :
100
+ self .current_value = value
101
+ if self .subs != None :
102
+ propagate (self .subs )
103
+ if not _ .bacth_depth :
104
+ process_effect_notifications ()
88
105
89
- @property
90
- def value (self ):
91
- if _ .active_sub != None :
92
- link (self , _ .active_sub )
93
- return self .current_value
94
-
95
- @value .setter
96
- def value (self , value ):
97
- if self .current_value != value :
98
- self .current_value = value
99
- if self .subs != None :
100
- propagate (self .subs )
101
- if not _ .bacth_depth :
102
- process_effect_notifications ()
103
106
104
107
signal = lambda initial_value : _Signal (initial_value )
105
108
106
109
107
110
class _Computed :
108
- def __init__ (self , getter ):
109
- self .current_value = None
110
- self .subs = None
111
- self .subs_tail = None
112
- self .deps = None
113
- self .deps_tail = None
114
- self .flags = COMPUTED | DIRTY
115
- self .getter = getter
116
-
117
- def __call__ (self ):
118
- return self .value
119
-
120
- @property
121
- def value (self ):
122
- if (self .flags & (DIRTY | PENDING_COMPUTED )):
123
- process_computed_update (self , self .flags )
124
- if _ .active_sub != None :
125
- link (self , _ .active_sub )
126
- elif _ .active_scope != None :
127
- link (self , _ .active_scope )
111
+ def __init__ (self , getter ):
112
+ self .current_value = None
113
+ self .subs = None
114
+ self .subs_tail = None
115
+ self .deps = None
116
+ self .deps_tail = None
117
+ self .flags = COMPUTED | DIRTY
118
+ self .getter = getter
119
+
120
+ def __call__ (self ):
121
+ return self .value
122
+
123
+ @property
124
+ def value (self ):
125
+ if self .flags & (DIRTY | PENDING_COMPUTED ):
126
+ process_computed_update (self , self .flags )
127
+ if _ .active_sub != None :
128
+ link (self , _ .active_sub )
129
+ elif _ .active_scope != None :
130
+ link (self , _ .active_scope )
131
+
132
+ return self .current_value
128
133
129
- return self .current_value
130
134
131
135
computed = lambda getter : _Computed (getter )
132
136
133
137
134
138
def _effect_stop (e ):
135
- def effect_stop ():
136
- start_tracking (e )
137
- end_tracking (e )
139
+ def effect_stop ():
140
+ start_tracking (e )
141
+ end_tracking (e )
138
142
139
- return effect_stop
143
+ return effect_stop
140
144
141
145
142
146
class _Effect :
143
- def __init__ (self , fn ):
144
- self .fn = fn
145
- self .subs = None
146
- self .subs_tail = None
147
- self .deps = None
148
- self .deps_tail = None
149
- self .flags = EFFECT
147
+ def __init__ (self , fn ):
148
+ self .fn = fn
149
+ self .subs = None
150
+ self .subs_tail = None
151
+ self .deps = None
152
+ self .deps_tail = None
153
+ self .flags = EFFECT
154
+
150
155
151
156
def effect (fn ):
152
- e = _Effect (fn )
153
- if _ .active_sub != None :
154
- link (e , _ .active_sub )
155
- elif _ .active_scope != None :
156
- link (e , _ .active_scope )
157
- prev_sub = _ .active_sub
158
- _ .active_sub = e
159
- try :
160
- e .fn ()
161
- finally :
162
- _ .active_sub = prev_sub
157
+ e = _Effect (fn )
158
+ if _ .active_sub != None :
159
+ link (e , _ .active_sub )
160
+ elif _ .active_scope != None :
161
+ link (e , _ .active_scope )
162
+ prev_sub = _ .active_sub
163
+ _ .active_sub = e
164
+ try :
165
+ e .fn ()
166
+ finally :
167
+ _ .active_sub = prev_sub
163
168
164
- return _effect_stop (e )
169
+ return _effect_stop (e )
165
170
166
171
167
172
class _EffectScope :
168
- def __init__ (self ):
169
- self .subs = None
170
- self .subs_tail = None
171
- self .deps = None
172
- self .deps_tail = None
173
- self .flags = EFFECT
174
- self .is_scope = True
173
+ def __init__ (self ):
174
+ self .subs = None
175
+ self .subs_tail = None
176
+ self .deps = None
177
+ self .deps_tail = None
178
+ self .flags = EFFECT
179
+ self .is_scope = True
180
+
175
181
176
182
def effect_scope (fn ):
177
- e = _EffectScope ()
178
- prev_sub = _ .active_scope
179
- _ .active_scope = e
180
- try :
181
- fn ()
182
- finally :
183
- _ .active_scope = prev_sub
183
+ e = _EffectScope ()
184
+ prev_sub = _ .active_scope
185
+ _ .active_scope = e
186
+ try :
187
+ fn ()
188
+ finally :
189
+ _ .active_scope = prev_sub
184
190
185
- return _effect_stop (e )
191
+ return _effect_stop (e )
186
192
187
193
188
194
def notify_effect (e ):
189
- flags = e .flags
190
-
191
- if (( flags & DIRTY ) or ((flags & PENDING_COMPUTED ) and update_dirty_flag (e , flags ) )):
192
- prev_sub = _ .active_sub
193
- _ .active_sub = e
194
- start_tracking (e )
195
- try :
196
- e .fn ()
197
- finally :
198
- _ .active_sub = prev_sub
199
- end_tracking (e )
200
- else :
201
- process_pending_inner_effects (e , e .flags )
195
+ flags = e .flags
196
+
197
+ if (flags & DIRTY ) or ((flags & PENDING_COMPUTED ) and update_dirty_flag (e , flags )):
198
+ prev_sub = _ .active_sub
199
+ _ .active_sub = e
200
+ start_tracking (e )
201
+ try :
202
+ e .fn ()
203
+ finally :
204
+ _ .active_sub = prev_sub
205
+ end_tracking (e )
206
+ else :
207
+ process_pending_inner_effects (e , e .flags )
202
208
203
- return True
209
+ return True
204
210
205
211
206
212
def notify_effect_scope (e ):
207
- flags = e .flags
213
+ flags = e .flags
208
214
209
- if flags & PENDING_EFFECT :
210
- process_pending_inner_effects (e , e .flags )
211
- return True
215
+ if flags & PENDING_EFFECT :
216
+ process_pending_inner_effects (e , e .flags )
217
+ return True
212
218
213
- return False
219
+ return False
0 commit comments