Show More
@@ -13,11 +13,12 b' in the IPython notebook front-end.' | |||
|
13 | 13 | # Imports |
|
14 | 14 | #----------------------------------------------------------------------------- |
|
15 | 15 | from contextlib import contextmanager |
|
16 | import collections | |
|
16 | 17 | |
|
17 | 18 | from IPython.core.getipython import get_ipython |
|
18 | 19 | from IPython.kernel.comm import Comm |
|
19 | 20 | from IPython.config import LoggingConfigurable |
|
20 | from IPython.utils.traitlets import Unicode, Dict, Instance, Bool, List, Tuple, Int | |
|
21 | from IPython.utils.traitlets import Unicode, Dict, Instance, Bool, List, Tuple, Int, Set | |
|
21 | 22 | from IPython.utils.py3compat import string_types |
|
22 | 23 | |
|
23 | 24 | #----------------------------------------------------------------------------- |
@@ -110,7 +111,8 b' class Widget(LoggingConfigurable):' | |||
|
110 | 111 | return [name for name in self.traits(sync=True)] |
|
111 | 112 | |
|
112 | 113 | _property_lock = Tuple((None, None)) |
|
113 | ||
|
114 | _send_state_lock = Int(0) | |
|
115 | _states_to_send = Set(allow_none=False) | |
|
114 | 116 | _display_callbacks = Instance(CallbackDispatcher, ()) |
|
115 | 117 | _msg_callbacks = Instance(CallbackDispatcher, ()) |
|
116 | 118 | |
@@ -174,12 +176,12 b' class Widget(LoggingConfigurable):' | |||
|
174 | 176 | |
|
175 | 177 | Parameters |
|
176 | 178 | ---------- |
|
177 | key : unicode (optional) | |
|
178 | A single property's name to sync with the front-end. | |
|
179 | key : unicode, or iterable (optional) | |
|
180 | A single property's name or iterable of property names to sync with the front-end. | |
|
179 | 181 | """ |
|
180 | 182 | self._send({ |
|
181 | 183 | "method" : "update", |
|
182 | "state" : self.get_state() | |
|
184 | "state" : self.get_state(key=key) | |
|
183 | 185 | }) |
|
184 | 186 | |
|
185 | 187 | def get_state(self, key=None): |
@@ -187,10 +189,17 b' class Widget(LoggingConfigurable):' | |||
|
187 | 189 | |
|
188 | 190 | Parameters |
|
189 | 191 | ---------- |
|
190 | key : unicode (optional) | |
|
191 | A single property's name to get. | |
|
192 | key : unicode or iterable (optional) | |
|
193 | A single property's name or iterable of property names to get. | |
|
192 | 194 | """ |
|
193 |
|
|
|
195 | if key is None: | |
|
196 | keys = self.keys | |
|
197 | elif isinstance(key, string_types): | |
|
198 | keys = [key] | |
|
199 | elif isinstance(key, collections.Iterable): | |
|
200 | keys = key | |
|
201 | else: | |
|
202 | raise ValueError("key must be a string, an iterable of keys, or None") | |
|
194 | 203 | state = {} |
|
195 | 204 | for k in keys: |
|
196 | 205 | f = self.trait_metadata(k, 'to_json') |
@@ -255,10 +264,26 b' class Widget(LoggingConfigurable):' | |||
|
255 | 264 | finally: |
|
256 | 265 | self._property_lock = (None, None) |
|
257 | 266 | |
|
267 | @contextmanager | |
|
268 | def hold_sync(self): | |
|
269 | """Hold syncing any state until the context manager is released""" | |
|
270 | # We increment a value so that this can be nested. Syncing will happen when | |
|
271 | # all levels have been released. | |
|
272 | self._send_state_lock += 1 | |
|
273 | try: | |
|
274 | yield | |
|
275 | finally: | |
|
276 | self._send_state_lock -=1 | |
|
277 | if self._send_state_lock == 0: | |
|
278 | self.send_state(self._states_to_send) | |
|
279 | self._states_to_send.clear() | |
|
280 | ||
|
258 | 281 | def _should_send_property(self, key, value): |
|
259 | 282 | """Check the property lock (property_lock)""" |
|
260 | return key != self._property_lock[0] or \ | |
|
261 | value != self._property_lock[1] | |
|
283 | if self._send_state_lock > 0: | |
|
284 | self._states_to_send.add(key) | |
|
285 | return False | |
|
286 | return key != self._property_lock[0] or value != self._property_lock[1] | |
|
262 | 287 | |
|
263 | 288 | # Event handlers |
|
264 | 289 | @_show_traceback |
General Comments 0
You need to be logged in to leave comments.
Login now