mujoco-react 12.1.0 → 12.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +16 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/runtime/client.ts +17 -7
package/package.json
CHANGED
package/src/runtime/client.ts
CHANGED
|
@@ -29,7 +29,7 @@ export class RuntimeClient implements SimulationRuntime {
|
|
|
29
29
|
constructor(
|
|
30
30
|
private worker: WorkerPort,
|
|
31
31
|
private apply: (display: DisplayState) => void,
|
|
32
|
-
private release: () => void,
|
|
32
|
+
private release: (restoreViewer: boolean) => void,
|
|
33
33
|
private capture?: (options: PolicyCameraFrameCaptureOptions) => ReturnType<typeof capturePolicyCameraFrames>,
|
|
34
34
|
) {
|
|
35
35
|
worker.onmessage = event => {
|
|
@@ -132,12 +132,12 @@ export class RuntimeClient implements SimulationRuntime {
|
|
|
132
132
|
return this.exclusive(async () => { await this.request({ kind: 'reset' }); return this.state; });
|
|
133
133
|
}
|
|
134
134
|
async dispose() { await this.cancel(); this.close(); }
|
|
135
|
-
close(error = new Error('Simulation runtime disposed')) {
|
|
135
|
+
close(error = new Error('Simulation runtime disposed'), restoreViewer = true) {
|
|
136
136
|
if (this.closed) return;
|
|
137
137
|
this.closed = true; this.generation++;
|
|
138
138
|
this.worker.terminate();
|
|
139
139
|
this.pending?.reject(error); this.pending = null;
|
|
140
|
-
this.release();
|
|
140
|
+
this.release(restoreViewer);
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -172,15 +172,25 @@ export async function attachSimulationRuntime(
|
|
|
172
172
|
data.time = display.time;
|
|
173
173
|
invalidate();
|
|
174
174
|
};
|
|
175
|
-
const client = new RuntimeClient(worker, apply,
|
|
175
|
+
const client = new RuntimeClient(worker, apply, restoreViewer => {
|
|
176
176
|
// Revert partial display frames to the last acknowledged complete state.
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
try {
|
|
178
|
+
if (api.mjModelRef.current === model && complete) {
|
|
179
|
+
apply(complete);
|
|
180
|
+
// Native contact/constraint structures cannot be mirrored as typed arrays.
|
|
181
|
+
// Rebuild once when returning ownership, never on progress frames or unmount.
|
|
182
|
+
if (restoreViewer) {
|
|
183
|
+
module.mj_forward(model, data);
|
|
184
|
+
const state = complete.integration!;
|
|
185
|
+
module.mj_setState(model, data, Array.from(state.values), state.signature);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
} finally { owners.delete(model); }
|
|
179
189
|
}, async cameras => {
|
|
180
190
|
await waitForDisplay();
|
|
181
191
|
return capturePolicyCameraFrames(api, cameras);
|
|
182
192
|
});
|
|
183
|
-
owners.set(model, { close: () => client.close(), contacts: () => client.state.contacts });
|
|
193
|
+
owners.set(model, { close: () => client.close(undefined, false), contacts: () => client.state.contacts });
|
|
184
194
|
try { await client.initialize({ model: binary, state: initialState }); return client; }
|
|
185
195
|
catch (error) { client.close(); throw error; }
|
|
186
196
|
}
|