diff --git a/src/editor/engine/lua/RobloxShim.js b/src/editor/engine/lua/RobloxShim.js index 6a8bc07..cb71593 100644 --- a/src/editor/engine/lua/RobloxShim.js +++ b/src/editor/engine/lua/RobloxShim.js @@ -1857,27 +1857,22 @@ export function registerRobloxShim(lua, opts) { // Запускаем каждый в своей coroutine — wait() внутри безопасен. if (_pendingHandlerQueue.length > 0) { const queue = _pendingHandlerQueue.splice(0, _pendingHandlerQueue.length); - // eslint-disable-next-line no-console - console.warn(`[handler-drain] draining ${queue.length} handlers`); for (const h of queue) { try { - const a = h.args || []; - // wasmoon-функция возвращает Promise. Если внутри Lua - // вернулся nil — wasmoon упадёт на .then(null). Ловим - // через .catch + try-catch синхронно. - let result; - if (a.length === 0) result = luaDrainHandler(h.fn); - else if (a.length === 1) result = luaDrainHandler(h.fn, a[0]); - else if (a.length === 2) result = luaDrainHandler(h.fn, a[0], a[1]); - else if (a.length === 3) result = luaDrainHandler(h.fn, a[0], a[1], a[2]); - else result = luaDrainHandler(h.fn, a[0], a[1], a[2], a[3]); - // Подавляем Promise.then(null) error + // ПРЯМОЙ вызов JS-обёртки Lua-функции (без передачи fn + // обратно в Lua через luaDrainHandler — это создаёт + // wasmoon Promise-detection crash на null.then). + // wasmoon вернёт Promise — ловим через .catch. + const result = h.fn(...(h.args || [])); if (result && typeof result.then === 'function') { - result.catch(() => {}); + result.catch((err) => { + // eslint-disable-next-line no-console + console.warn('[handler-async-err]', err?.message || err); + }); } } catch (e) { // eslint-disable-next-line no-console - console.warn('[handler-drain-catch]', e?.message || e); + console.warn('[handler-sync-err]', e?.message || e); } } } @@ -1934,11 +1929,10 @@ export function registerRobloxShim(lua, opts) { const id = p.primId ?? p.target; const part = partById.get(Number(id)); if (!part) return; - // ДИАГНОСТИКА: пробуем сначала без аргумента — чтобы понять hrp ли виноват if (p.kind === 'touch' || p.kind === 'touched') { - part.Touched.Fire(); // БЕЗ hrp — тест + part.Touched.Fire(hrp); } else if (p.kind === 'untouch' || p.kind === 'untouched') { - part.TouchEnded.Fire(); + part.TouchEnded.Fire(hrp); } }, fireGlobalEvent(p) {