kitchen-simulator 3.3.0 → 3.5.0
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/es/index.js +183 -76
- package/lib/index.js +183 -76
- package/package.json +1 -1
package/es/index.js
CHANGED
|
@@ -14,6 +14,8 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
|
14
14
|
import React from 'react';
|
|
15
15
|
import LiteRenderer from "./LiteRenderer";
|
|
16
16
|
import { createRoot } from 'react-dom/client';
|
|
17
|
+
var ROOT_KEY = '__kitchenSimulatorRoot__';
|
|
18
|
+
var API_KEY = '__kitchenSimulatorApi__';
|
|
17
19
|
function nextFrame() {
|
|
18
20
|
return new Promise(function (resolve) {
|
|
19
21
|
return requestAnimationFrame(resolve);
|
|
@@ -164,6 +166,7 @@ function installGltfTracker() {
|
|
|
164
166
|
}
|
|
165
167
|
var subscribe = function subscribe(fn) {
|
|
166
168
|
listeners.add(fn);
|
|
169
|
+
// IMPORTANT: emits synchronously
|
|
167
170
|
fn(inFlight);
|
|
168
171
|
return function () {
|
|
169
172
|
return listeners["delete"](fn);
|
|
@@ -171,8 +174,8 @@ function installGltfTracker() {
|
|
|
171
174
|
};
|
|
172
175
|
|
|
173
176
|
/**
|
|
174
|
-
* Wait until
|
|
175
|
-
*
|
|
177
|
+
* Wait until inFlight becomes 0 (with grace window).
|
|
178
|
+
* Safe even when already idle.
|
|
176
179
|
*/
|
|
177
180
|
var waitForIdle = /*#__PURE__*/function () {
|
|
178
181
|
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
|
|
@@ -187,7 +190,7 @@ function installGltfTracker() {
|
|
|
187
190
|
while (1) switch (_context3.prev = _context3.next) {
|
|
188
191
|
case 0:
|
|
189
192
|
_ref3 = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : {}, _ref3$timeoutMs = _ref3.timeoutMs, timeoutMs = _ref3$timeoutMs === void 0 ? 30000 : _ref3$timeoutMs, _ref3$graceMs = _ref3.graceMs, graceMs = _ref3$graceMs === void 0 ? 50 : _ref3$graceMs;
|
|
190
|
-
start = Date.now();
|
|
193
|
+
start = Date.now();
|
|
191
194
|
if (!(graceMs > 0)) {
|
|
192
195
|
_context3.next = 1;
|
|
193
196
|
break;
|
|
@@ -196,17 +199,19 @@ function installGltfTracker() {
|
|
|
196
199
|
return sleep(graceMs);
|
|
197
200
|
case 1:
|
|
198
201
|
return _context3.abrupt("return", new Promise(function (resolve, reject) {
|
|
199
|
-
var unsub =
|
|
202
|
+
var unsub = null;
|
|
203
|
+
var onChange = function onChange(count) {
|
|
200
204
|
if (count === 0) {
|
|
201
|
-
unsub();
|
|
205
|
+
if (unsub) unsub();
|
|
202
206
|
resolve(true);
|
|
203
207
|
return;
|
|
204
208
|
}
|
|
205
209
|
if (Date.now() - start > timeoutMs) {
|
|
206
|
-
unsub();
|
|
210
|
+
if (unsub) unsub();
|
|
207
211
|
reject(new Error('GLTF did not become idle within timeout'));
|
|
208
212
|
}
|
|
209
|
-
}
|
|
213
|
+
};
|
|
214
|
+
unsub = subscribe(onChange);
|
|
210
215
|
}));
|
|
211
216
|
case 2:
|
|
212
217
|
case "end":
|
|
@@ -235,91 +240,168 @@ function installGltfTracker() {
|
|
|
235
240
|
};
|
|
236
241
|
}
|
|
237
242
|
export function renderKitchenSimulator(container) {
|
|
238
|
-
var _props$framesPerEvent, _props$waitForGltfIdl, _props$gltfTimeoutMs, _props$gltfGraceMs;
|
|
243
|
+
var _props$framesPerEvent, _props$waitForGltfIdl, _props$gltfTimeoutMs, _props$gltfGraceMs, _props$syncGltfGraceM, _props$syncExtraFrame;
|
|
239
244
|
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
240
|
-
|
|
245
|
+
if (!container) throw new Error('renderKitchenSimulator: container is required');
|
|
246
|
+
|
|
247
|
+
// ✅ Reuse existing API for same container
|
|
248
|
+
if (container[API_KEY]) {
|
|
249
|
+
var _container$API_KEY$__, _container$API_KEY;
|
|
250
|
+
// update render with latest props (safe)
|
|
251
|
+
(_container$API_KEY$__ = (_container$API_KEY = container[API_KEY]).__render) === null || _container$API_KEY$__ === void 0 || _container$API_KEY$__.call(_container$API_KEY, props);
|
|
252
|
+
return container[API_KEY];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// ✅ Reuse root for same container
|
|
256
|
+
var root = container[ROOT_KEY];
|
|
257
|
+
if (!root) {
|
|
258
|
+
root = createRoot(container);
|
|
259
|
+
container[ROOT_KEY] = root;
|
|
260
|
+
}
|
|
241
261
|
var setExternalEventFn = null;
|
|
242
|
-
var queue = [];
|
|
243
|
-
var pendingMarkers = new Set();
|
|
244
|
-
var draining = false;
|
|
245
262
|
var destroyed = false;
|
|
246
|
-
var FRAMES_PER_EVENT = (_props$framesPerEvent = props.framesPerEvent) !== null && _props$framesPerEvent !== void 0 ? _props$framesPerEvent : 2;
|
|
247
263
|
|
|
248
|
-
//
|
|
249
|
-
var
|
|
250
|
-
var
|
|
251
|
-
var
|
|
264
|
+
// queue + marker handling
|
|
265
|
+
var queue = [];
|
|
266
|
+
var pendingMarkers = new Set();
|
|
267
|
+
var MARKER = Symbol('marker');
|
|
252
268
|
var gltfTracker = installGltfTracker();
|
|
253
|
-
|
|
254
|
-
|
|
269
|
+
|
|
270
|
+
// defaults
|
|
271
|
+
var defaultFramesPerEvent = (_props$framesPerEvent = props.framesPerEvent) !== null && _props$framesPerEvent !== void 0 ? _props$framesPerEvent : 2;
|
|
272
|
+
var waitForGltf = (_props$waitForGltfIdl = props.waitForGltfIdleAfterEachEvent) !== null && _props$waitForGltfIdl !== void 0 ? _props$waitForGltfIdl : true;
|
|
273
|
+
var defaultTimeout = (_props$gltfTimeoutMs = props.gltfTimeoutMs) !== null && _props$gltfTimeoutMs !== void 0 ? _props$gltfTimeoutMs : 30000;
|
|
274
|
+
var defaultGrace = (_props$gltfGraceMs = props.gltfGraceMs) !== null && _props$gltfGraceMs !== void 0 ? _props$gltfGraceMs : 50;
|
|
275
|
+
var syncGrace = (_props$syncGltfGraceM = props.syncGltfGraceMs) !== null && _props$syncGltfGraceM !== void 0 ? _props$syncGltfGraceM : 250; // SyncScene uses larger grace
|
|
276
|
+
var syncExtraFrames = (_props$syncExtraFrame = props.syncExtraFrames) !== null && _props$syncExtraFrame !== void 0 ? _props$syncExtraFrame : 2;
|
|
277
|
+
var draining = false;
|
|
278
|
+
function isSyncScene(ev) {
|
|
279
|
+
var _ev$payload;
|
|
280
|
+
return (ev === null || ev === void 0 ? void 0 : ev.type) === 'EXTERNAL_EVENT_SYNC_SCENE' || (ev === null || ev === void 0 || (_ev$payload = ev.payload) === null || _ev$payload === void 0 ? void 0 : _ev$payload.mode) === 'sync-scene' ||
|
|
281
|
+
// if you pass mode sometimes
|
|
282
|
+
(ev === null || ev === void 0 ? void 0 : ev.__sync) === true;
|
|
255
283
|
}
|
|
256
|
-
function
|
|
257
|
-
|
|
258
|
-
|
|
284
|
+
function settle(_x) {
|
|
285
|
+
return _settle.apply(this, arguments);
|
|
286
|
+
}
|
|
287
|
+
function _settle() {
|
|
288
|
+
_settle = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(ev) {
|
|
289
|
+
var _ev$framesPerEvent, _ev$gltfGraceMs, _ev$gltfTimeoutMs;
|
|
290
|
+
var frames, i, graceMs, timeoutMs, _i;
|
|
259
291
|
return _regeneratorRuntime.wrap(function (_context5) {
|
|
260
292
|
while (1) switch (_context5.prev = _context5.next) {
|
|
261
293
|
case 0:
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
return _context5.abrupt("return");
|
|
294
|
+
frames = (_ev$framesPerEvent = ev === null || ev === void 0 ? void 0 : ev.framesPerEvent) !== null && _ev$framesPerEvent !== void 0 ? _ev$framesPerEvent : defaultFramesPerEvent; // 1) allow React + reducers to run
|
|
295
|
+
i = 0;
|
|
267
296
|
case 1:
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
case 3:
|
|
271
|
-
if (!(queue.length && !destroyed)) {
|
|
272
|
-
_context5.next = 10;
|
|
297
|
+
if (!(i < frames)) {
|
|
298
|
+
_context5.next = 3;
|
|
273
299
|
break;
|
|
274
300
|
}
|
|
275
|
-
|
|
276
|
-
|
|
301
|
+
_context5.next = 2;
|
|
302
|
+
return nextFrame();
|
|
303
|
+
case 2:
|
|
304
|
+
i += 1;
|
|
305
|
+
_context5.next = 1;
|
|
306
|
+
break;
|
|
307
|
+
case 3:
|
|
308
|
+
if (waitForGltf) {
|
|
277
309
|
_context5.next = 4;
|
|
278
310
|
break;
|
|
279
311
|
}
|
|
280
|
-
|
|
281
|
-
return _context5.abrupt("continue", 3);
|
|
312
|
+
return _context5.abrupt("return");
|
|
282
313
|
case 4:
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
314
|
+
// 2) wait for gltf idle
|
|
315
|
+
graceMs = isSyncScene(ev) ? syncGrace : (_ev$gltfGraceMs = ev === null || ev === void 0 ? void 0 : ev.gltfGraceMs) !== null && _ev$gltfGraceMs !== void 0 ? _ev$gltfGraceMs : defaultGrace;
|
|
316
|
+
timeoutMs = (_ev$gltfTimeoutMs = ev === null || ev === void 0 ? void 0 : ev.gltfTimeoutMs) !== null && _ev$gltfTimeoutMs !== void 0 ? _ev$gltfTimeoutMs : defaultTimeout;
|
|
317
|
+
_context5.next = 5;
|
|
318
|
+
return gltfTracker.waitForIdle({
|
|
319
|
+
graceMs: graceMs,
|
|
320
|
+
timeoutMs: timeoutMs
|
|
321
|
+
});
|
|
287
322
|
case 5:
|
|
288
|
-
if (!(i < FRAMES_PER_EVENT)) {
|
|
289
|
-
_context5.next = 7;
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
323
|
_context5.next = 6;
|
|
293
324
|
return nextFrame();
|
|
294
325
|
case 6:
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
326
|
+
if (!isSyncScene(ev)) {
|
|
327
|
+
_context5.next = 9;
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
_i = 0;
|
|
298
331
|
case 7:
|
|
299
|
-
if (!
|
|
332
|
+
if (!(_i < syncExtraFrames)) {
|
|
300
333
|
_context5.next = 9;
|
|
301
334
|
break;
|
|
302
335
|
}
|
|
303
336
|
_context5.next = 8;
|
|
304
|
-
return gltfTracker.waitForIdle({
|
|
305
|
-
timeoutMs: (_ev$gltfTimeoutMs = ev === null || ev === void 0 ? void 0 : ev.gltfTimeoutMs) !== null && _ev$gltfTimeoutMs !== void 0 ? _ev$gltfTimeoutMs : GLTF_TIMEOUT_MS,
|
|
306
|
-
graceMs: (_ev$gltfGraceMs = ev === null || ev === void 0 ? void 0 : ev.gltfGraceMs) !== null && _ev$gltfGraceMs !== void 0 ? _ev$gltfGraceMs : GLTF_GRACE_MS
|
|
307
|
-
});
|
|
308
|
-
case 8:
|
|
309
|
-
_context5.next = 9;
|
|
310
337
|
return nextFrame();
|
|
338
|
+
case 8:
|
|
339
|
+
_i += 1;
|
|
340
|
+
_context5.next = 7;
|
|
341
|
+
break;
|
|
311
342
|
case 9:
|
|
312
|
-
|
|
343
|
+
case "end":
|
|
344
|
+
return _context5.stop();
|
|
345
|
+
}
|
|
346
|
+
}, _callee5);
|
|
347
|
+
}));
|
|
348
|
+
return _settle.apply(this, arguments);
|
|
349
|
+
}
|
|
350
|
+
function drain() {
|
|
351
|
+
return _drain.apply(this, arguments);
|
|
352
|
+
}
|
|
353
|
+
function _drain() {
|
|
354
|
+
_drain = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
|
|
355
|
+
var item;
|
|
356
|
+
return _regeneratorRuntime.wrap(function (_context6) {
|
|
357
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
358
|
+
case 0:
|
|
359
|
+
if (!(draining || destroyed)) {
|
|
360
|
+
_context6.next = 1;
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
return _context6.abrupt("return");
|
|
364
|
+
case 1:
|
|
365
|
+
draining = true;
|
|
366
|
+
_context6.prev = 2;
|
|
367
|
+
case 3:
|
|
368
|
+
if (!(queue.length && !destroyed)) {
|
|
369
|
+
_context6.next = 8;
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
item = queue.shift(); // marker?
|
|
373
|
+
if (!(item && item.__marker === MARKER)) {
|
|
374
|
+
_context6.next = 4;
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
pendingMarkers["delete"](item.token);
|
|
378
|
+
return _context6.abrupt("continue", 3);
|
|
379
|
+
case 4:
|
|
380
|
+
if (setExternalEventFn) {
|
|
381
|
+
_context6.next = 6;
|
|
382
|
+
break;
|
|
383
|
+
}
|
|
384
|
+
_context6.next = 5;
|
|
385
|
+
return nextFrame();
|
|
386
|
+
case 5:
|
|
387
|
+
queue.unshift(item); // put back and retry
|
|
388
|
+
return _context6.abrupt("continue", 3);
|
|
389
|
+
case 6:
|
|
390
|
+
setExternalEventFn(item);
|
|
391
|
+
_context6.next = 7;
|
|
392
|
+
return settle(item);
|
|
393
|
+
case 7:
|
|
394
|
+
_context6.next = 3;
|
|
313
395
|
break;
|
|
314
|
-
case
|
|
315
|
-
|
|
396
|
+
case 8:
|
|
397
|
+
_context6.prev = 8;
|
|
316
398
|
draining = false;
|
|
317
|
-
return
|
|
318
|
-
case
|
|
399
|
+
return _context6.finish(8);
|
|
400
|
+
case 9:
|
|
319
401
|
case "end":
|
|
320
|
-
return
|
|
402
|
+
return _context6.stop();
|
|
321
403
|
}
|
|
322
|
-
},
|
|
404
|
+
}, _callee6, null, [[2,, 8, 9]]);
|
|
323
405
|
}));
|
|
324
406
|
return _drain.apply(this, arguments);
|
|
325
407
|
}
|
|
@@ -331,16 +413,27 @@ export function renderKitchenSimulator(container) {
|
|
|
331
413
|
_this2.state = {
|
|
332
414
|
externalEvent: p.externalEvent || null
|
|
333
415
|
};
|
|
334
|
-
|
|
416
|
+
_this2._mounted = false;
|
|
335
417
|
return _this2;
|
|
336
418
|
}
|
|
337
419
|
_inherits(Wrapper, _React$Component);
|
|
338
420
|
return _createClass(Wrapper, [{
|
|
339
|
-
key: "
|
|
340
|
-
value: function
|
|
341
|
-
this
|
|
342
|
-
|
|
343
|
-
|
|
421
|
+
key: "componentDidMount",
|
|
422
|
+
value: function componentDidMount() {
|
|
423
|
+
var _this3 = this;
|
|
424
|
+
this._mounted = true;
|
|
425
|
+
setExternalEventFn = function setExternalEventFn(newEvent) {
|
|
426
|
+
if (!_this3._mounted) return;
|
|
427
|
+
_this3.setState({
|
|
428
|
+
externalEvent: newEvent
|
|
429
|
+
});
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
}, {
|
|
433
|
+
key: "componentWillUnmount",
|
|
434
|
+
value: function componentWillUnmount() {
|
|
435
|
+
this._mounted = false;
|
|
436
|
+
setExternalEventFn = null;
|
|
344
437
|
}
|
|
345
438
|
}, {
|
|
346
439
|
key: "render",
|
|
@@ -351,8 +444,15 @@ export function renderKitchenSimulator(container) {
|
|
|
351
444
|
}
|
|
352
445
|
}]);
|
|
353
446
|
}(React.Component);
|
|
354
|
-
|
|
355
|
-
|
|
447
|
+
var api = {
|
|
448
|
+
// internal: rerender wrapper with latest props if host calls renderKitchenSimulator again
|
|
449
|
+
__render: function __render(nextProps) {
|
|
450
|
+
root.render(/*#__PURE__*/React.createElement(Wrapper, nextProps));
|
|
451
|
+
},
|
|
452
|
+
/**
|
|
453
|
+
* Send one or many events (in order).
|
|
454
|
+
* Resolves when this batch has been delivered + settled.
|
|
455
|
+
*/
|
|
356
456
|
sendExternalEvents: function sendExternalEvents(eventOrEvents) {
|
|
357
457
|
var events = Array.isArray(eventOrEvents) ? eventOrEvents : [eventOrEvents];
|
|
358
458
|
var _iterator2 = _createForOfIteratorHelper(events),
|
|
@@ -362,8 +462,6 @@ export function renderKitchenSimulator(container) {
|
|
|
362
462
|
var e = _step2.value;
|
|
363
463
|
queue.push(e);
|
|
364
464
|
}
|
|
365
|
-
|
|
366
|
-
// marker for this batch
|
|
367
465
|
} catch (err) {
|
|
368
466
|
_iterator2.e(err);
|
|
369
467
|
} finally {
|
|
@@ -372,7 +470,8 @@ export function renderKitchenSimulator(container) {
|
|
|
372
470
|
var token = Symbol('batch');
|
|
373
471
|
pendingMarkers.add(token);
|
|
374
472
|
queue.push({
|
|
375
|
-
|
|
473
|
+
__marker: MARKER,
|
|
474
|
+
token: token
|
|
376
475
|
});
|
|
377
476
|
drain();
|
|
378
477
|
return new Promise(function (resolve) {
|
|
@@ -411,20 +510,28 @@ export function renderKitchenSimulator(container) {
|
|
|
411
510
|
check();
|
|
412
511
|
});
|
|
413
512
|
},
|
|
414
|
-
updateExternalEvent: function updateExternalEvent(
|
|
415
|
-
return
|
|
513
|
+
updateExternalEvent: function updateExternalEvent(e) {
|
|
514
|
+
return api.sendExternalEvents(e);
|
|
416
515
|
},
|
|
417
516
|
clearQueue: function clearQueue() {
|
|
418
517
|
queue.length = 0;
|
|
419
518
|
pendingMarkers.clear();
|
|
420
519
|
},
|
|
421
520
|
unmount: function unmount() {
|
|
422
|
-
var _this$clearQueue;
|
|
423
521
|
destroyed = true;
|
|
424
|
-
|
|
522
|
+
api.clearQueue();
|
|
425
523
|
gltfTracker.uninstall();
|
|
426
524
|
root.unmount();
|
|
525
|
+
container[ROOT_KEY] = null;
|
|
526
|
+
container[API_KEY] = null;
|
|
427
527
|
}
|
|
428
528
|
};
|
|
529
|
+
|
|
530
|
+
// first render
|
|
531
|
+
api.__render(props);
|
|
532
|
+
|
|
533
|
+
// store api on container so repeated calls reuse it
|
|
534
|
+
container[API_KEY] = api;
|
|
535
|
+
return api;
|
|
429
536
|
}
|
|
430
537
|
export default renderKitchenSimulator;
|
package/lib/index.js
CHANGED
|
@@ -22,6 +22,8 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
22
22
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
23
23
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
24
24
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
25
|
+
var ROOT_KEY = '__kitchenSimulatorRoot__';
|
|
26
|
+
var API_KEY = '__kitchenSimulatorApi__';
|
|
25
27
|
function nextFrame() {
|
|
26
28
|
return new Promise(function (resolve) {
|
|
27
29
|
return requestAnimationFrame(resolve);
|
|
@@ -172,6 +174,7 @@ function installGltfTracker() {
|
|
|
172
174
|
}
|
|
173
175
|
var subscribe = function subscribe(fn) {
|
|
174
176
|
listeners.add(fn);
|
|
177
|
+
// IMPORTANT: emits synchronously
|
|
175
178
|
fn(inFlight);
|
|
176
179
|
return function () {
|
|
177
180
|
return listeners["delete"](fn);
|
|
@@ -179,8 +182,8 @@ function installGltfTracker() {
|
|
|
179
182
|
};
|
|
180
183
|
|
|
181
184
|
/**
|
|
182
|
-
* Wait until
|
|
183
|
-
*
|
|
185
|
+
* Wait until inFlight becomes 0 (with grace window).
|
|
186
|
+
* Safe even when already idle.
|
|
184
187
|
*/
|
|
185
188
|
var waitForIdle = /*#__PURE__*/function () {
|
|
186
189
|
var _ref2 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee3() {
|
|
@@ -195,7 +198,7 @@ function installGltfTracker() {
|
|
|
195
198
|
while (1) switch (_context3.prev = _context3.next) {
|
|
196
199
|
case 0:
|
|
197
200
|
_ref3 = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : {}, _ref3$timeoutMs = _ref3.timeoutMs, timeoutMs = _ref3$timeoutMs === void 0 ? 30000 : _ref3$timeoutMs, _ref3$graceMs = _ref3.graceMs, graceMs = _ref3$graceMs === void 0 ? 50 : _ref3$graceMs;
|
|
198
|
-
start = Date.now();
|
|
201
|
+
start = Date.now();
|
|
199
202
|
if (!(graceMs > 0)) {
|
|
200
203
|
_context3.next = 1;
|
|
201
204
|
break;
|
|
@@ -204,17 +207,19 @@ function installGltfTracker() {
|
|
|
204
207
|
return sleep(graceMs);
|
|
205
208
|
case 1:
|
|
206
209
|
return _context3.abrupt("return", new Promise(function (resolve, reject) {
|
|
207
|
-
var unsub =
|
|
210
|
+
var unsub = null;
|
|
211
|
+
var onChange = function onChange(count) {
|
|
208
212
|
if (count === 0) {
|
|
209
|
-
unsub();
|
|
213
|
+
if (unsub) unsub();
|
|
210
214
|
resolve(true);
|
|
211
215
|
return;
|
|
212
216
|
}
|
|
213
217
|
if (Date.now() - start > timeoutMs) {
|
|
214
|
-
unsub();
|
|
218
|
+
if (unsub) unsub();
|
|
215
219
|
reject(new Error('GLTF did not become idle within timeout'));
|
|
216
220
|
}
|
|
217
|
-
}
|
|
221
|
+
};
|
|
222
|
+
unsub = subscribe(onChange);
|
|
218
223
|
}));
|
|
219
224
|
case 2:
|
|
220
225
|
case "end":
|
|
@@ -243,91 +248,168 @@ function installGltfTracker() {
|
|
|
243
248
|
};
|
|
244
249
|
}
|
|
245
250
|
function renderKitchenSimulator(container) {
|
|
246
|
-
var _props$framesPerEvent, _props$waitForGltfIdl, _props$gltfTimeoutMs, _props$gltfGraceMs;
|
|
251
|
+
var _props$framesPerEvent, _props$waitForGltfIdl, _props$gltfTimeoutMs, _props$gltfGraceMs, _props$syncGltfGraceM, _props$syncExtraFrame;
|
|
247
252
|
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
248
|
-
|
|
253
|
+
if (!container) throw new Error('renderKitchenSimulator: container is required');
|
|
254
|
+
|
|
255
|
+
// ✅ Reuse existing API for same container
|
|
256
|
+
if (container[API_KEY]) {
|
|
257
|
+
var _container$API_KEY$__, _container$API_KEY;
|
|
258
|
+
// update render with latest props (safe)
|
|
259
|
+
(_container$API_KEY$__ = (_container$API_KEY = container[API_KEY]).__render) === null || _container$API_KEY$__ === void 0 || _container$API_KEY$__.call(_container$API_KEY, props);
|
|
260
|
+
return container[API_KEY];
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// ✅ Reuse root for same container
|
|
264
|
+
var root = container[ROOT_KEY];
|
|
265
|
+
if (!root) {
|
|
266
|
+
root = (0, _client.createRoot)(container);
|
|
267
|
+
container[ROOT_KEY] = root;
|
|
268
|
+
}
|
|
249
269
|
var setExternalEventFn = null;
|
|
250
|
-
var queue = [];
|
|
251
|
-
var pendingMarkers = new Set();
|
|
252
|
-
var draining = false;
|
|
253
270
|
var destroyed = false;
|
|
254
|
-
var FRAMES_PER_EVENT = (_props$framesPerEvent = props.framesPerEvent) !== null && _props$framesPerEvent !== void 0 ? _props$framesPerEvent : 2;
|
|
255
271
|
|
|
256
|
-
//
|
|
257
|
-
var
|
|
258
|
-
var
|
|
259
|
-
var
|
|
272
|
+
// queue + marker handling
|
|
273
|
+
var queue = [];
|
|
274
|
+
var pendingMarkers = new Set();
|
|
275
|
+
var MARKER = Symbol('marker');
|
|
260
276
|
var gltfTracker = installGltfTracker();
|
|
261
|
-
|
|
262
|
-
|
|
277
|
+
|
|
278
|
+
// defaults
|
|
279
|
+
var defaultFramesPerEvent = (_props$framesPerEvent = props.framesPerEvent) !== null && _props$framesPerEvent !== void 0 ? _props$framesPerEvent : 2;
|
|
280
|
+
var waitForGltf = (_props$waitForGltfIdl = props.waitForGltfIdleAfterEachEvent) !== null && _props$waitForGltfIdl !== void 0 ? _props$waitForGltfIdl : true;
|
|
281
|
+
var defaultTimeout = (_props$gltfTimeoutMs = props.gltfTimeoutMs) !== null && _props$gltfTimeoutMs !== void 0 ? _props$gltfTimeoutMs : 30000;
|
|
282
|
+
var defaultGrace = (_props$gltfGraceMs = props.gltfGraceMs) !== null && _props$gltfGraceMs !== void 0 ? _props$gltfGraceMs : 50;
|
|
283
|
+
var syncGrace = (_props$syncGltfGraceM = props.syncGltfGraceMs) !== null && _props$syncGltfGraceM !== void 0 ? _props$syncGltfGraceM : 250; // SyncScene uses larger grace
|
|
284
|
+
var syncExtraFrames = (_props$syncExtraFrame = props.syncExtraFrames) !== null && _props$syncExtraFrame !== void 0 ? _props$syncExtraFrame : 2;
|
|
285
|
+
var draining = false;
|
|
286
|
+
function isSyncScene(ev) {
|
|
287
|
+
var _ev$payload;
|
|
288
|
+
return (ev === null || ev === void 0 ? void 0 : ev.type) === 'EXTERNAL_EVENT_SYNC_SCENE' || (ev === null || ev === void 0 || (_ev$payload = ev.payload) === null || _ev$payload === void 0 ? void 0 : _ev$payload.mode) === 'sync-scene' ||
|
|
289
|
+
// if you pass mode sometimes
|
|
290
|
+
(ev === null || ev === void 0 ? void 0 : ev.__sync) === true;
|
|
263
291
|
}
|
|
264
|
-
function
|
|
265
|
-
|
|
266
|
-
|
|
292
|
+
function settle(_x) {
|
|
293
|
+
return _settle.apply(this, arguments);
|
|
294
|
+
}
|
|
295
|
+
function _settle() {
|
|
296
|
+
_settle = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee5(ev) {
|
|
297
|
+
var _ev$framesPerEvent, _ev$gltfGraceMs, _ev$gltfTimeoutMs;
|
|
298
|
+
var frames, i, graceMs, timeoutMs, _i;
|
|
267
299
|
return _regenerator["default"].wrap(function (_context5) {
|
|
268
300
|
while (1) switch (_context5.prev = _context5.next) {
|
|
269
301
|
case 0:
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
break;
|
|
273
|
-
}
|
|
274
|
-
return _context5.abrupt("return");
|
|
302
|
+
frames = (_ev$framesPerEvent = ev === null || ev === void 0 ? void 0 : ev.framesPerEvent) !== null && _ev$framesPerEvent !== void 0 ? _ev$framesPerEvent : defaultFramesPerEvent; // 1) allow React + reducers to run
|
|
303
|
+
i = 0;
|
|
275
304
|
case 1:
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
case 3:
|
|
279
|
-
if (!(queue.length && !destroyed)) {
|
|
280
|
-
_context5.next = 10;
|
|
305
|
+
if (!(i < frames)) {
|
|
306
|
+
_context5.next = 3;
|
|
281
307
|
break;
|
|
282
308
|
}
|
|
283
|
-
|
|
284
|
-
|
|
309
|
+
_context5.next = 2;
|
|
310
|
+
return nextFrame();
|
|
311
|
+
case 2:
|
|
312
|
+
i += 1;
|
|
313
|
+
_context5.next = 1;
|
|
314
|
+
break;
|
|
315
|
+
case 3:
|
|
316
|
+
if (waitForGltf) {
|
|
285
317
|
_context5.next = 4;
|
|
286
318
|
break;
|
|
287
319
|
}
|
|
288
|
-
|
|
289
|
-
return _context5.abrupt("continue", 3);
|
|
320
|
+
return _context5.abrupt("return");
|
|
290
321
|
case 4:
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
322
|
+
// 2) wait for gltf idle
|
|
323
|
+
graceMs = isSyncScene(ev) ? syncGrace : (_ev$gltfGraceMs = ev === null || ev === void 0 ? void 0 : ev.gltfGraceMs) !== null && _ev$gltfGraceMs !== void 0 ? _ev$gltfGraceMs : defaultGrace;
|
|
324
|
+
timeoutMs = (_ev$gltfTimeoutMs = ev === null || ev === void 0 ? void 0 : ev.gltfTimeoutMs) !== null && _ev$gltfTimeoutMs !== void 0 ? _ev$gltfTimeoutMs : defaultTimeout;
|
|
325
|
+
_context5.next = 5;
|
|
326
|
+
return gltfTracker.waitForIdle({
|
|
327
|
+
graceMs: graceMs,
|
|
328
|
+
timeoutMs: timeoutMs
|
|
329
|
+
});
|
|
295
330
|
case 5:
|
|
296
|
-
if (!(i < FRAMES_PER_EVENT)) {
|
|
297
|
-
_context5.next = 7;
|
|
298
|
-
break;
|
|
299
|
-
}
|
|
300
331
|
_context5.next = 6;
|
|
301
332
|
return nextFrame();
|
|
302
333
|
case 6:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
334
|
+
if (!isSyncScene(ev)) {
|
|
335
|
+
_context5.next = 9;
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
_i = 0;
|
|
306
339
|
case 7:
|
|
307
|
-
if (!
|
|
340
|
+
if (!(_i < syncExtraFrames)) {
|
|
308
341
|
_context5.next = 9;
|
|
309
342
|
break;
|
|
310
343
|
}
|
|
311
344
|
_context5.next = 8;
|
|
312
|
-
return gltfTracker.waitForIdle({
|
|
313
|
-
timeoutMs: (_ev$gltfTimeoutMs = ev === null || ev === void 0 ? void 0 : ev.gltfTimeoutMs) !== null && _ev$gltfTimeoutMs !== void 0 ? _ev$gltfTimeoutMs : GLTF_TIMEOUT_MS,
|
|
314
|
-
graceMs: (_ev$gltfGraceMs = ev === null || ev === void 0 ? void 0 : ev.gltfGraceMs) !== null && _ev$gltfGraceMs !== void 0 ? _ev$gltfGraceMs : GLTF_GRACE_MS
|
|
315
|
-
});
|
|
316
|
-
case 8:
|
|
317
|
-
_context5.next = 9;
|
|
318
345
|
return nextFrame();
|
|
346
|
+
case 8:
|
|
347
|
+
_i += 1;
|
|
348
|
+
_context5.next = 7;
|
|
349
|
+
break;
|
|
319
350
|
case 9:
|
|
320
|
-
|
|
351
|
+
case "end":
|
|
352
|
+
return _context5.stop();
|
|
353
|
+
}
|
|
354
|
+
}, _callee5);
|
|
355
|
+
}));
|
|
356
|
+
return _settle.apply(this, arguments);
|
|
357
|
+
}
|
|
358
|
+
function drain() {
|
|
359
|
+
return _drain.apply(this, arguments);
|
|
360
|
+
}
|
|
361
|
+
function _drain() {
|
|
362
|
+
_drain = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee6() {
|
|
363
|
+
var item;
|
|
364
|
+
return _regenerator["default"].wrap(function (_context6) {
|
|
365
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
366
|
+
case 0:
|
|
367
|
+
if (!(draining || destroyed)) {
|
|
368
|
+
_context6.next = 1;
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
return _context6.abrupt("return");
|
|
372
|
+
case 1:
|
|
373
|
+
draining = true;
|
|
374
|
+
_context6.prev = 2;
|
|
375
|
+
case 3:
|
|
376
|
+
if (!(queue.length && !destroyed)) {
|
|
377
|
+
_context6.next = 8;
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
item = queue.shift(); // marker?
|
|
381
|
+
if (!(item && item.__marker === MARKER)) {
|
|
382
|
+
_context6.next = 4;
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
pendingMarkers["delete"](item.token);
|
|
386
|
+
return _context6.abrupt("continue", 3);
|
|
387
|
+
case 4:
|
|
388
|
+
if (setExternalEventFn) {
|
|
389
|
+
_context6.next = 6;
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
_context6.next = 5;
|
|
393
|
+
return nextFrame();
|
|
394
|
+
case 5:
|
|
395
|
+
queue.unshift(item); // put back and retry
|
|
396
|
+
return _context6.abrupt("continue", 3);
|
|
397
|
+
case 6:
|
|
398
|
+
setExternalEventFn(item);
|
|
399
|
+
_context6.next = 7;
|
|
400
|
+
return settle(item);
|
|
401
|
+
case 7:
|
|
402
|
+
_context6.next = 3;
|
|
321
403
|
break;
|
|
322
|
-
case
|
|
323
|
-
|
|
404
|
+
case 8:
|
|
405
|
+
_context6.prev = 8;
|
|
324
406
|
draining = false;
|
|
325
|
-
return
|
|
326
|
-
case
|
|
407
|
+
return _context6.finish(8);
|
|
408
|
+
case 9:
|
|
327
409
|
case "end":
|
|
328
|
-
return
|
|
410
|
+
return _context6.stop();
|
|
329
411
|
}
|
|
330
|
-
},
|
|
412
|
+
}, _callee6, null, [[2,, 8, 9]]);
|
|
331
413
|
}));
|
|
332
414
|
return _drain.apply(this, arguments);
|
|
333
415
|
}
|
|
@@ -339,16 +421,27 @@ function renderKitchenSimulator(container) {
|
|
|
339
421
|
_this2.state = {
|
|
340
422
|
externalEvent: p.externalEvent || null
|
|
341
423
|
};
|
|
342
|
-
|
|
424
|
+
_this2._mounted = false;
|
|
343
425
|
return _this2;
|
|
344
426
|
}
|
|
345
427
|
(0, _inherits2["default"])(Wrapper, _React$Component);
|
|
346
428
|
return (0, _createClass2["default"])(Wrapper, [{
|
|
347
|
-
key: "
|
|
348
|
-
value: function
|
|
349
|
-
this
|
|
350
|
-
|
|
351
|
-
|
|
429
|
+
key: "componentDidMount",
|
|
430
|
+
value: function componentDidMount() {
|
|
431
|
+
var _this3 = this;
|
|
432
|
+
this._mounted = true;
|
|
433
|
+
setExternalEventFn = function setExternalEventFn(newEvent) {
|
|
434
|
+
if (!_this3._mounted) return;
|
|
435
|
+
_this3.setState({
|
|
436
|
+
externalEvent: newEvent
|
|
437
|
+
});
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
}, {
|
|
441
|
+
key: "componentWillUnmount",
|
|
442
|
+
value: function componentWillUnmount() {
|
|
443
|
+
this._mounted = false;
|
|
444
|
+
setExternalEventFn = null;
|
|
352
445
|
}
|
|
353
446
|
}, {
|
|
354
447
|
key: "render",
|
|
@@ -359,8 +452,15 @@ function renderKitchenSimulator(container) {
|
|
|
359
452
|
}
|
|
360
453
|
}]);
|
|
361
454
|
}(_react["default"].Component);
|
|
362
|
-
|
|
363
|
-
|
|
455
|
+
var api = {
|
|
456
|
+
// internal: rerender wrapper with latest props if host calls renderKitchenSimulator again
|
|
457
|
+
__render: function __render(nextProps) {
|
|
458
|
+
root.render(/*#__PURE__*/_react["default"].createElement(Wrapper, nextProps));
|
|
459
|
+
},
|
|
460
|
+
/**
|
|
461
|
+
* Send one or many events (in order).
|
|
462
|
+
* Resolves when this batch has been delivered + settled.
|
|
463
|
+
*/
|
|
364
464
|
sendExternalEvents: function sendExternalEvents(eventOrEvents) {
|
|
365
465
|
var events = Array.isArray(eventOrEvents) ? eventOrEvents : [eventOrEvents];
|
|
366
466
|
var _iterator2 = _createForOfIteratorHelper(events),
|
|
@@ -370,8 +470,6 @@ function renderKitchenSimulator(container) {
|
|
|
370
470
|
var e = _step2.value;
|
|
371
471
|
queue.push(e);
|
|
372
472
|
}
|
|
373
|
-
|
|
374
|
-
// marker for this batch
|
|
375
473
|
} catch (err) {
|
|
376
474
|
_iterator2.e(err);
|
|
377
475
|
} finally {
|
|
@@ -380,7 +478,8 @@ function renderKitchenSimulator(container) {
|
|
|
380
478
|
var token = Symbol('batch');
|
|
381
479
|
pendingMarkers.add(token);
|
|
382
480
|
queue.push({
|
|
383
|
-
|
|
481
|
+
__marker: MARKER,
|
|
482
|
+
token: token
|
|
384
483
|
});
|
|
385
484
|
drain();
|
|
386
485
|
return new Promise(function (resolve) {
|
|
@@ -419,20 +518,28 @@ function renderKitchenSimulator(container) {
|
|
|
419
518
|
check();
|
|
420
519
|
});
|
|
421
520
|
},
|
|
422
|
-
updateExternalEvent: function updateExternalEvent(
|
|
423
|
-
return
|
|
521
|
+
updateExternalEvent: function updateExternalEvent(e) {
|
|
522
|
+
return api.sendExternalEvents(e);
|
|
424
523
|
},
|
|
425
524
|
clearQueue: function clearQueue() {
|
|
426
525
|
queue.length = 0;
|
|
427
526
|
pendingMarkers.clear();
|
|
428
527
|
},
|
|
429
528
|
unmount: function unmount() {
|
|
430
|
-
var _this$clearQueue;
|
|
431
529
|
destroyed = true;
|
|
432
|
-
|
|
530
|
+
api.clearQueue();
|
|
433
531
|
gltfTracker.uninstall();
|
|
434
532
|
root.unmount();
|
|
533
|
+
container[ROOT_KEY] = null;
|
|
534
|
+
container[API_KEY] = null;
|
|
435
535
|
}
|
|
436
536
|
};
|
|
537
|
+
|
|
538
|
+
// first render
|
|
539
|
+
api.__render(props);
|
|
540
|
+
|
|
541
|
+
// store api on container so repeated calls reuse it
|
|
542
|
+
container[API_KEY] = api;
|
|
543
|
+
return api;
|
|
437
544
|
}
|
|
438
545
|
var _default = exports["default"] = renderKitchenSimulator;
|