feat(lab-content-engine): phase 1 - data-driven регистрация всех симуляций
- _register-all.js: строит манифесты из SIMS + THEORY + карта OPEN (40 id), регистрирует все симуляции в LabRegistry; LAB_SIM_ALIASES для deep-link - openSim(): удалена if-цепочка (~60 строк), замена на нормализацию алиасов + диспетчеризацию через реестр (early return) - lab.html: _pilots.js -> _register-all.js (defer, последним) - _pilots.js удалён (поглощён _register-all.js) Паритет проверен: исполняемый harness (40 регистраций, dispatch, алиасы, :arg) ALL PASS; независимое ревью PASS (coverage 40/40, dispatch byte-for-byte). Lifecycle пока на _pauseAllSims/closeSim (дробовик) — паритет. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
'use strict';
|
||||
/*
|
||||
* Контент-движок, Фаза 1 — data-driven регистрация ВСЕХ симуляций в LabRegistry.
|
||||
*
|
||||
* Вместо ручного переписывания 40 манифестов модуль строит их из единых источников:
|
||||
* - метаданные (id/cat/title/desc) и preview — из массива SIMS (lab-glue.js);
|
||||
* - теория — из объекта THEORY (lab-init.js);
|
||||
* - поведение open(ctx) — из карты OPEN ниже (обёртки над глобальными _openXxx).
|
||||
* Это структурно гарантирует паритет с прежним каталогом и диспетчеризацией.
|
||||
*
|
||||
* Подключается ПОСЛЕДНИМ среди labs-скриптов (defer), поэтому SIMS, THEORY и все
|
||||
* _openXxx уже определены. Останов/закрытие симуляций по-прежнему выполняет
|
||||
* «дробовик» _pauseAllSims()/closeSim() (точный паритет) — поэтому stop/destroy
|
||||
* в манифестах не задаются на этом этапе.
|
||||
*
|
||||
* После регистрации if-цепочка в openSim() становится мёртвой и удалена.
|
||||
*
|
||||
* В Фазе 1 заменил пилотный _pilots.js. SIMS/THEORY остаются источниками данных
|
||||
* (SIMS → БД в Фазе 4, THEORY сворачивается в манифесты позже).
|
||||
*/
|
||||
(function () {
|
||||
if (!window.LabRegistry) return;
|
||||
if (typeof SIMS === 'undefined') return;
|
||||
var R = window.LabRegistry;
|
||||
var T = (typeof THEORY !== 'undefined') ? THEORY : {};
|
||||
|
||||
// id -> open(ctx). ctx.arg — параметр deep-link (после двоеточия): stereo:cube и т.п.
|
||||
var OPEN = {
|
||||
graph: function (c) { _openGraph(); },
|
||||
projectile: function (c) { _openProjectile(); },
|
||||
collision: function (c) { _openCollision(); },
|
||||
triangle: function (c) { _openTriangle(); },
|
||||
trigcircle: function (c) { _openTrigCircle(); },
|
||||
emfield: function (c) { _openEMField(c.arg || 'E'); },
|
||||
molphys: function (c) { _openMolPhys(c.arg); },
|
||||
circuit: function (c) { _openCircuit(); },
|
||||
chemistry: function (c) { _openChemistry(c.arg); },
|
||||
dynamics: function (c) { _openDynamics(c.arg); },
|
||||
crystal: function (c) { _openCrystal(); },
|
||||
orbitals: function (c) { _openOrbitals(); },
|
||||
stereo: function (c) { _openStereo(c.arg); },
|
||||
chemsandbox: function (c) { _openChemSandbox(); },
|
||||
celldivision: function (c) { _openCellDivision(); },
|
||||
photosynthesis: function (c) { _openPhotosynthesis(); },
|
||||
angrybirds: function (c) { _openAngryBirds(); },
|
||||
quadratic: function (c) { _openQuadratic(); },
|
||||
normaldist: function (c) { _openNormalDist(); },
|
||||
graphtransform: function (c) { _openGraphTransform(); },
|
||||
pendulum: function (c) { _openPendulum(); },
|
||||
equilibrium: function (c) { _openEquilibrium(); },
|
||||
opticsbench: function (c) { _openOpticsBench(c.arg || 'lens'); },
|
||||
isoprocess: function (c) { _openIsoprocess(); },
|
||||
titration: function (c) { _openTitration(); },
|
||||
probability: function (c) { _openProbability(); },
|
||||
bohratom: function (c) { _openBohrAtom(); },
|
||||
electrolysis: function (c) { _openElectrolysis(); },
|
||||
race: function (c) { _openRace(); },
|
||||
waves: function (c) { _openWaves(); },
|
||||
hydrostatics: function (c) { _openHydro(c.arg); },
|
||||
radioactive: function (c) { _openRadioactive(); },
|
||||
geometry: function (c) { _openGeometry(); },
|
||||
logic: function (c) { _openLogic(); },
|
||||
heatengine: function (c) { _openHeatEngine(); },
|
||||
stoichiometry: function (c) { _openStoich(); },
|
||||
qualanalysis: function (c) { _openQualAnalysis(); },
|
||||
periodic: function (c) { _openPeriodic(); },
|
||||
organic: function (c) { _openOrganic(); },
|
||||
solutions: function (c) { _openSolutions(); }
|
||||
};
|
||||
|
||||
SIMS.forEach(function (s) {
|
||||
if (!s.id) return; // "Скоро" — карточка без id
|
||||
var open = OPEN[s.id];
|
||||
if (!open) { // подстраховка: незамапленный id оставляем legacy-пути
|
||||
if (window.console) console.warn('[LabRegistry] нет open() для', s.id);
|
||||
return;
|
||||
}
|
||||
R.register({
|
||||
id: s.id,
|
||||
cat: s.cat,
|
||||
title: s.title,
|
||||
desc: s.desc,
|
||||
preview: s.preview, // уже готовая SVG-строка (P_* вычислены в SIMS)
|
||||
theory: T[s.id] || null,
|
||||
open: open
|
||||
// stop/destroy: глобальный «дробовик» _pauseAllSims()/closeSim() — паритет
|
||||
});
|
||||
});
|
||||
|
||||
// Алиасы deep-link → канонический id[:arg]. Диспетчер openSim() нормализует их
|
||||
// перед обращением к реестру (карточек у алиасов нет — только прямые ссылки).
|
||||
window.LAB_SIM_ALIASES = {
|
||||
magnetic: 'emfield:B',
|
||||
coulomb: 'emfield:E',
|
||||
thinlens: 'opticsbench:lens',
|
||||
mirrors: 'opticsbench:mirror',
|
||||
refraction: 'opticsbench:refraction'
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user