##// END OF EJS Templates
Add a new context manager, Widget.hold_sync(), which holds any syncing until the manager exits...
Jason Grout -
Show More
@@ -13,11 +13,12 b' in the IPython notebook front-end.'
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 from contextlib import contextmanager
15 from contextlib import contextmanager
16 import collections
16
17
17 from IPython.core.getipython import get_ipython
18 from IPython.core.getipython import get_ipython
18 from IPython.kernel.comm import Comm
19 from IPython.kernel.comm import Comm
19 from IPython.config import LoggingConfigurable
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 from IPython.utils.py3compat import string_types
22 from IPython.utils.py3compat import string_types
22
23
23 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
@@ -110,7 +111,8 b' class Widget(LoggingConfigurable):'
110 return [name for name in self.traits(sync=True)]
111 return [name for name in self.traits(sync=True)]
111
112
112 _property_lock = Tuple((None, None))
113 _property_lock = Tuple((None, None))
113
114 _send_state_lock = Int(0)
115 _states_to_send = Set(allow_none=False)
114 _display_callbacks = Instance(CallbackDispatcher, ())
116 _display_callbacks = Instance(CallbackDispatcher, ())
115 _msg_callbacks = Instance(CallbackDispatcher, ())
117 _msg_callbacks = Instance(CallbackDispatcher, ())
116
118
@@ -174,12 +176,12 b' class Widget(LoggingConfigurable):'
174
176
175 Parameters
177 Parameters
176 ----------
178 ----------
177 key : unicode (optional)
179 key : unicode, or iterable (optional)
178 A single property's name to sync with the front-end.
180 A single property's name or iterable of property names to sync with the front-end.
179 """
181 """
180 self._send({
182 self._send({
181 "method" : "update",
183 "method" : "update",
182 "state" : self.get_state()
184 "state" : self.get_state(key=key)
183 })
185 })
184
186
185 def get_state(self, key=None):
187 def get_state(self, key=None):
@@ -187,10 +189,17 b' class Widget(LoggingConfigurable):'
187
189
188 Parameters
190 Parameters
189 ----------
191 ----------
190 key : unicode (optional)
192 key : unicode or iterable (optional)
191 A single property's name to get.
193 A single property's name or iterable of property names to get.
192 """
194 """
193 keys = self.keys if key is None else [key]
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 state = {}
203 state = {}
195 for k in keys:
204 for k in keys:
196 f = self.trait_metadata(k, 'to_json')
205 f = self.trait_metadata(k, 'to_json')
@@ -255,10 +264,26 b' class Widget(LoggingConfigurable):'
255 finally:
264 finally:
256 self._property_lock = (None, None)
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 def _should_send_property(self, key, value):
281 def _should_send_property(self, key, value):
259 """Check the property lock (property_lock)"""
282 """Check the property lock (property_lock)"""
260 return key != self._property_lock[0] or \
283 if self._send_state_lock > 0:
261 value != self._property_lock[1]
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 # Event handlers
288 # Event handlers
264 @_show_traceback
289 @_show_traceback
General Comments 0
You need to be logged in to leave comments. Login now