Skip to content

Commit 67984cb

Browse files
committed
ipywidgets: figured out how to solve the state update problem
1 parent 6b5dab6 commit 67984cb

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

src/packages/frontend/jupyter/widgets/manager2.ts

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,7 @@ VBox([s1, s2])
106106
log("handleIpwidgetsTableChange", { model_id, type });
107107
switch (type) {
108108
case "state":
109-
// Overall state is only used for creating widget when it is
110-
// rendered for the first time as part of Environment.getSerializedModelState
111-
// So do NOT call it again here on any change. Updates for RTC use
112-
// type='value'. Doing this causes a lot of noise, which e.g., completely
113-
// breaks rendering using the threejs custom widgets, e.g., this breaks;
114-
// from pythreejs import DodecahedronGeometry; DodecahedronGeometry()
115-
// await this.ipywidgets_state_StateChange(model_id);
109+
await this.ipywidgets_state_StateChange(model_id);
116110
break;
117111
case "value":
118112
await this.ipywidgets_state_ValueChange(model_id);
@@ -129,15 +123,28 @@ VBox([s1, s2])
129123
}
130124
};
131125

132-
// private ipywidgets_state_StateChange = async (model_id: string) => {
133-
// log("ipywidgets_state_StateChange: ", model_id);
134-
// const state = this.ipywidgets_state.getSerializedModelState(model_id);
135-
// log("ipywidgets_state_StateChange: state=", JSON.stringify(state));
136-
// if (state == null) {
137-
// return;
138-
// }
139-
// await this.updateModel(model_id, state!, false);
140-
// };
126+
private ipywidgets_state_StateChange = async (model_id: string) => {
127+
// Overall state is only used for creating widget when it is
128+
// rendered for the first time as part of Environment.getSerializedModelState,
129+
// if it is called. Some widgets though need to get created, but they are
130+
// never rendered, so we only know about them due to state change.
131+
//
132+
// First: We only do this once if getSerializedModelState didn't happen. Updates for RTC use
133+
// type='value'. Doing this causes a lot of noise, which e.g., completely
134+
// breaks rendering using the threejs custom widgets, e.g., this breaks;
135+
// from pythreejs import DodecahedronGeometry; DodecahedronGeometry()
136+
//
137+
// Second: This example shows that sometimes getSerializedModelState is never called, so
138+
// it's important to call this in some cases:
139+
// from ipywidgets import VBox, jsdlink, IntSlider, Button; s1 = IntSlider(max=200, value=100); s2 = IntSlider(value=40); VBox([s1, s2])
140+
// jsdlink((s1, 'value'), (s2, 'max'))
141+
//
142+
143+
// The solution: make sure the model gets created if state change is called.
144+
// This results in getSerializedModelState being called and causes no
145+
// problems if it were getting called anyways and works in both cases above.
146+
await this.manager.get_model(model_id);
147+
};
141148

142149
private updateModel = async (
143150
model_id: string,

0 commit comments

Comments
 (0)