feat(sim-builder): фаза 7 — custom-sim на доске онлайн-урока (синхрон параметров классу, аннотации)

This commit is contained in:
Maxim Dolgolyov
2026-06-13 13:25:24 +03:00
parent 5c01a5c7ed
commit f26b522207
7 changed files with 192 additions and 26 deletions
+47 -1
View File
@@ -395,6 +395,45 @@ const SIMS = [
_lastEmittedState = null;
}
/* Конструктор симуляций (Фаза 7): подключить custom-sim (SimEngine-инстанс через
адаптерный манифест real.instance()) к тому же мосту sim_state/apply_sim_state,
что и встроенные. Состояние = { params, running } — параметры слайдеров +
признак воспроизведения. applyState проигрывает их у ученика через setParam/
play/pause (время жёстко не синхронится — параметры и play/pause достаточны).
Регистрируем под ключом _autoSim ('custom:<dbid>'), т.к. обработчик
apply_sim_state у ученика берёт _simStateRegistry[_autoSim]. */
function _bridgeCustomSimState(real) {
if (!_embedMode || !real || typeof real.instance !== 'function') return;
var key = _autoSim;
if (!key || _simStateRegistry[key]) return; // уже подключено
function getState() {
var inst = real.instance();
if (!inst || !inst.params) return null;
var p = {};
for (var k in inst.params) {
if (Object.prototype.hasOwnProperty.call(inst.params, k)) {
var v = inst.params[k];
if (typeof v === 'number' && isFinite(v)) p[k] = v;
}
}
return { params: p, running: !!(inst.isRunning && inst.isRunning()) };
}
function applyState(st) {
var inst = real.instance();
if (!inst || !st) return;
if (st.params) {
for (var k in st.params) {
if (Object.prototype.hasOwnProperty.call(st.params, k)) inst.setParam(k, st.params[k]);
}
}
var run = !!st.running, isRun = !!(inst.isRunning && inst.isRunning());
if (run && !isRun && inst.play) inst.play();
else if (!run && isRun && inst.pause) inst.pause();
}
_registerSimState(key, getState, applyState);
_startStateEmit(key);
}
// Receive apply_sim_state from parent (students)
window.addEventListener('message', e => {
if (!_embedMode) return;
@@ -683,7 +722,14 @@ const SIMS = [
real._custom = true;
real._customId = dbid;
if (window.LabRegistry) window.LabRegistry.setActive(real);
return real.open(ctx);
var _r = real.open(ctx);
// Конструктор симуляций (Фаза 7): синхрон параметров/play на доске
// онлайн-урока. В embed подключаем custom-sim к общему мосту
// sim_state/apply_sim_state — тем же каналом, что и встроенные.
// Ключ — исходный _autoSim ('custom:<dbid>'), т.к. apply_sim_state
// у ученика берёт _simStateRegistry[_autoSim].
try { _bridgeCustomSimState(real); } catch (e) {}
return _r;
}
});
}