UNPKG

rock-mod

Version:

Rock-Mod is a powerful framework designed for creating and managing mods for Grand Theft Auto (GTA) games.

75 lines (74 loc) 4.71 kB
import { type INativeCallerManager } from "../../common/native/INativeCallerManager"; /** * Реализация `INativeCallerManager` под CCMP — полноценный generic dispatch * GTA V-нативов по hex-хэшу. * * ### Архитектура * * **Таблица hash→method** генерируется на build-time скриптом * `scripts/generate-native-dispatch.mjs` из alloc8or-format nativedb * (`scripts/data/natives.json`, ~6649 натов). Output: * `_generated/nativeDispatch.ts`. Каждая запись — `{ns: "<ccmp-namespace>", * methods: ["<camelMethod1>", "<camelMethod2-fallback>"]}`, где `methods[]` * содержит канонический имя натива + все `old_names` алиасы (нужно потому * что CCMP-биндинги могут использовать либо новое каноническое, либо * легаси-имя в зависимости от момента генерации `@classic-mp/types`). * * **Runtime resolve**: при первом вызове `callNative(hash, ...args)`: * 1. Lookup в `NATIVE_DISPATCH[hash.toLowerCase()]``{ns, methods[]}`. * 2. `ccmp.natives[ns]` — берём namespace-объект. * 3. Перебираем `methods[]` в порядке: для первой существующей функции — * биндим `[nsObj, fn]` в `_resolved` кэш. * 4. Зовём с args через `fn.apply(nsObj, args)`. * 5. Адаптируем return-shape (см. ниже). * * Lookup-кэш `_resolved` — Map с hash-ключом, чтобы не дёргать * `NATIVE_DISPATCH[]` + `_resolve()` на каждый вызов (multiple natives * вызываются на каждый render-tick). * * ### Адаптация return-shape (CCMP → RageMP-конвенция) * * CCMP-нативы для multi-return значений возвращают **объект** с именованными * полями (например, `getGameplayCamCoord()``{x, y, z}`). Геймод (написанный * под RageMP-конвенцию) ожидает **массив-кортеж** (`[x, y, z]`). * * Generic `_adaptResult`: * - `boolean` (top-level) → `0` или `1` (RageMP'шный native-bool протокол: * `mp.game.invoke(boolNative)` возвращает число). * - Object с string-keys → `Object.values(obj)` (порядок гарантирован ES2015 * insertion-order для non-integer keys; CCMP-типы декларируют поля в * каноническом порядке). * - Nested object внутри tuple → рекурсивно тоже `Object.values()` * (для нативов вроде `getShapeTestResult` с nested `endcoords: {x,y,z}`). * - Bool **внутри** объекта/tuple → не конвертим (нужен для tuple-полей * типа `[bool, x, y]` где геймод-тип честно ожидает boolean). * - Primitives / arrays / null → passthrough. * * ### Hot path * * `callNative` вызывается из render-tick consumer'ов: `HudController` * (drawBlip), `CameraIdleController.onInterval`, `VehicleIndicatorService`, * `PolygonZoneRenderer`, `ScriptedMarker`, `ConeDebugRenderer`. После прогрева * `_resolved`-кэша — один Map.get + `fn.apply` + adapt-проход. Адапт — линейный * по числу полей возврата (обычно ≤ 5), стоимость незначительная. * * ### Ошибки * * - **Hash не в DB**: натив отсутствует в nativedb. Throws с подсказкой * "обновите scripts/data/natives.json" — обычно случается для свежих * build-specific натов, не вошедших в last-snapshot базы. * - **Namespace не в `ccmp.natives`**: CCMP-runtime версия не имеет такого * namespace'а. Throws с указанием ns. * - **Все method-кандидаты отсутствуют в namespace'е**: CCMP-биндинг не * экспонирует ни одного из known-имён. Throws с перечислением кандидатов. */ export declare class CCMPNativeCallerManager implements INativeCallerManager { private readonly _resolved; callNative(hash: string, ...args: unknown[]): unknown; private _resolve; /** * Конвертация CCMP object-return → RageMP tuple-return. * См. block-комментарий класса (Адаптация return-shape). */ private static _adaptResult; }