Skip to content

Commit de94bc6

Browse files
committed
Use lock instead of wrapping handler
Simplifies the logic of suppressing duplicate and invalid updates. Courtesy of Neil Vaytet.
1 parent b18b67f commit de94bc6

File tree

1 file changed

+24
-42
lines changed

1 file changed

+24
-42
lines changed

src/ess/dream/diagnostics.py

Lines changed: 24 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ def __init__(
4040
self._bank_selector = _make_bank_selector(data.keys())
4141
self._bank = self._data[self._bank_selector.value]
4242

43-
self._dim_selector = _DimensionSelector(self._bank.dims)
44-
self._dim_selector.observe(self._update_view, names='value')
43+
self._dim_selector = _DimensionSelector(self._bank.dims, self._update_view)
4544

4645
self._fig_kwargs = {'rasterized': rasterized}
4746
self._figure_box = ipw.HBox([self._make_figure()])
@@ -83,17 +82,18 @@ def _prepare_data(dg: sc.DataGroup) -> sc.DataGroup:
8382

8483

8584
class _DimensionSelector(ipw.VBox):
86-
def __init__(self, dims: tuple[str, ...]) -> None:
87-
self._value_observers = []
85+
def __init__(self, dims: tuple[str, ...], callback: Callable[[dict], None]) -> None:
86+
self._lock = False
87+
self._callback = callback
8888

89-
h_buttons, v_buttons = self._make_buttons(dims, *self._default_dims(dims))
89+
self._horizontal_buttons, self._vertical_buttons = self._make_buttons(
90+
dims, *self._default_dims(dims)
91+
)
9092

91-
self._horizontal_selector_box = ipw.HBox([h_buttons])
92-
self._vertical_selector_box = ipw.HBox([v_buttons])
9393
super().__init__(
9494
[
95-
ipw.HBox([ipw.Label('X'), self._horizontal_selector_box]),
96-
ipw.HBox([ipw.Label('Y'), self._vertical_selector_box]),
95+
ipw.HBox([ipw.Label('X'), self._horizontal_buttons]),
96+
ipw.HBox([ipw.Label('Y'), self._vertical_buttons]),
9797
]
9898
)
9999

@@ -104,31 +104,19 @@ def _make_buttons(
104104
options = {dim.capitalize(): dim for dim in dims}
105105
h_buttons = ipw.ToggleButtons(options=options, value=h_dim, style=style)
106106
v_buttons = ipw.ToggleButtons(options=options, value=v_dim, style=style)
107-
h_buttons.observe(self._observe_values, names='value')
108-
v_buttons.observe(self._observe_values, names='value')
107+
h_buttons.observe(self.update, names='value')
108+
v_buttons.observe(self.update, names='value')
109109
return h_buttons, v_buttons
110110

111-
@property
112-
def _horizontal_buttons(self) -> ipw.ToggleButtons:
113-
return self._horizontal_selector_box.children[0]
114-
115-
@property
116-
def _vertical_buttons(self) -> ipw.ToggleButtons:
117-
return self._vertical_selector_box.children[0]
118-
119111
def set_dims(self, new_dims: tuple[str, ...]) -> None:
120-
self._horizontal_buttons.unobserve_all(name='value')
121-
self._vertical_buttons.unobserve_all(name='value')
122-
123-
old_h = self._horizontal_buttons.value
124-
old_v = self._vertical_buttons.value
125112
default_h, default_v = self._default_dims(new_dims)
126-
new_h = old_h if old_h in new_dims else default_h
127-
new_v = old_v if old_v in new_dims else default_v
128-
129-
h_buttons, v_buttons = self._make_buttons(new_dims, new_h, new_v)
130-
self._horizontal_selector_box.children = [h_buttons]
131-
self._vertical_selector_box.children = [v_buttons]
113+
options = {dim.capitalize(): dim for dim in new_dims}
114+
self._lock = True
115+
self._horizontal_buttons.options = options
116+
self._vertical_buttons.options = options
117+
self._horizontal_buttons.value = default_h
118+
self._vertical_buttons.value = default_v
119+
self._lock = False
132120

133121
@staticmethod
134122
def _default_dims(dims: tuple[str, ...]) -> tuple[str, str]:
@@ -141,26 +129,20 @@ def value(self):
141129
'vertical': self._vertical_buttons.value,
142130
}
143131

144-
def observe(self, handler, names: str | list[str], *args, **kwargs):
145-
if names != 'value':
146-
super().observe(handler, names, *args, **kwargs)
147-
else:
148-
self._value_observers.append(handler)
149-
150-
def _observe_values(self, change: dict) -> None:
132+
def update(self, change: dict) -> None:
133+
if self._lock:
134+
return
151135
clicked = change['owner']
152136
other = (
153137
self._vertical_buttons
154138
if clicked is self._horizontal_buttons
155139
else self._horizontal_buttons
156140
)
157141
if other.value == clicked.value:
142+
self._lock = True # suppress update from `other`
158143
other.value = change['old']
159-
else:
160-
# Only when dims are different to avoid unnecessary redraws
161-
# and drawing with invalid dims.
162-
for observer in self._value_observers:
163-
observer(change)
144+
self._lock = False
145+
self._callback(change)
164146

165147

166148
def _flat_voxel_figure(

0 commit comments

Comments
 (0)