C ABI 與宿主服務

模塊導出

每腳本庫導出 C 函數凡七(mtr_native.h;註冊宏自生其全):

導出釋義
uint32_t mtrNativeAbiVersion()返編譯時之 ABI 版本(今為 13);宿主拒不相容之版——與 JCM 於 JS 腳本版本失配之重載策同也
const char* mtrScriptType()"vehicle" / "pids" / "eyecandy" / "lift" / "psd"
const char* mtrScriptId()腳本之 id(須與資源包宣告相符)
size_t mtrStateSize()逐實例狀態塊之大小;宿主為每實例配一塊
void mtrInit(const JcmFrameInput*)宿主甫配狀態之塊,即此一呼,以 placement-new 構 State(ABI 6 而後所必需;宿主設或漏呼,模塊則惰性構造以兜其底)
int32_t mtrCreate / mtrRender / mtrDispose(const JcmFrameInput*, …)生命週期之門也;返 0 者成,-1 者入參空,-2 者 ABI 不合,-3 者資源類型不符。宿主於每模塊單一後臺之線程,按實例而串行呼之

幀之輸入與輸出

JcmFrameInput(宿主 → 模塊)

typedef struct JcmFrameInput {
    uint32_t abi_version;              /* 協定既成之 ABI 版本 */
    int32_t  resource_kind;            /* MtrResourceKind:vehicle/pids/eyecandy/lift/psd */
    const void* snapshot;              /* 所對應之 Jcm*Snapshot */
    void*    state;                    /* 宿主所配逐實例狀態塊 */
    size_t   state_size;
    const struct JcmHostServices* host;/* 渲染線程所得呼之宿主服務 */
} JcmFrameInput;

快照內部之約:諸 *_offset 欄,皆自快照首位元組起算之偏移也;string_pool_offset/len 則述共享 UTF-8 字串池之所在。定址之勞,SDK 包裝器代君盡之。

JcmFrameOutput(模塊 → 宿主)

輸出者何?扁平記錄之流,加以輸出之區凡五也。之區(arena)者,預申之大塊記憶也:幀內順次而配,幀末舉而還之。mtrRender 既返,宿主即讀而收其幀(模塊間之雙緩衝,宿主為之):

之區內容容量(SDK 預設)
records順列之繪製記錄(變長,按 record_size 之步而歷)256 條
matrix_arena矩陣流(列主序 4×4,每矩陣 16 float)128 組
string_arenaUTF-8 字串流(貼圖 id、文字、聲音 id…)32 KB
pixel_arenaBGRA8 像素流(紋理上傳)初 1 MB,按需增至 16 MB,閒則衰而復落
float_arenafloat 流(體素碰撞匣等)1024 個

ABI 9 而後,輸出併給各區之完備容量——宿主為每區惟建一 ByteBuffer,每幀改其 limit 而復用之,不復逐幀而配五包裝之物。

繪製記錄

每記錄以 JcmRecordHeader{kind, flags, record_size} 為首,變長而順列。flags 載記錄級之開關:今所定者,惟 MTR_RECORD_FLAG_NATURAL_LIGHT(Text / Texture / Rect 之 natural_light()——取世間之光照,不用至亮之渲染光)。斯位元組者,舊 padding 就地升格而為之:舊 SDK 所編之模塊恆書 0,舊宿主置之不問——雙向二進制相容,不升 ABI 之版。凡八類:

kind結構所用 / 所映之 JS 呼
JCM_DRAW_TEXTJcmDrawTextPIDS / 通用文字(TextWrapper 欄位逐一相準:對齊、溢出之式、跑馬燈、z 序、層、字體 id)
JCM_DRAW_TEXTUREJcmDrawTexture貼圖面片(UV、染色、z 序)
JCM_DRAW_MODELJcmDrawModel車輛車廂 / 轉向架 / 裝飾模型(宿主模型之柄+姿態矩陣組)
JCM_DRAW_SOUNDJcmDrawSound定位之音效(車廂局部坐標之偏)
JCM_DRAW_LOCAL_SOUNDJcmDrawSound報站廣播(惟乘者所聞)
JCM_DRAW_TEXTURE_UPLOADJcmDrawTextureUploadGraphicsTexture 像素上傳(BGRA8+髒矩形)
JCM_DRAW_OUTLINE_SHAPEJcmDrawShape裝飾輪廓 / 碰撞匣(每匣 6 float;碰撞匣上限 1.5 格)
JCM_DRAW_BLOCK_EVENT—裝飾 onBlockUse 事件之握手

宿主回放此諸記錄,用與 JS 腳本全同之渲染程式碼路徑(PIDSDrawCall / ScriptRenderManager)——所繪者,同一物也。

宿主服務

JcmHostServices 者,函數指針之表也(in->host),渲染線程之內得而呼之。宿主之舊者,新槽為 null;呼前判其空,即得降級:

服務始於釋義
acquire_model / release_modelABI 1模型 JSON 柄之生命週期(映 ModelJS 之柄)
create_texture / release_textureABI 1GraphicsTexture 之生命週期(映 Java 之類)
rasterize_textABI 1宿主 TTF 光柵之回呼(CJK 之屬);BGRA8 書於呼叫者之緩衝。返 -1 者,字體不覆該碼位也(宜退用內建之點陣字體)
logABI 1console.log / console.error 之通道
acquire_quad_modelABI 4宿主構貼圖之面片(頂點四+UV+渲染階段+紋理之柄)——JS DisplayHelper 槽位模型之原生等物也;頂點屬模型空間,UV 以貼圖左上為原,y 則向下。無頭之驅返 -1,其時略而不繪
measure_font_text / draw_font_textABI 7資源字體之度量與基線光柵(與 JS Graphics2D 同一字體、同一壓縮裁剪之義;髒邊界出參)
invoke_apiABI 8mtr::Api 之底層通道:UTF-8 JSON 之請入,結果出於線程局部緩衝(下次呼叫前有效)
defer_freeABI 10以既死之大塊記憶體,付宿主後臺回收線程(詳見 疾徐與除錯)

ABI 版本沿革

宿主所受,ABI 6–13 之模塊(各按其時代之布局而餵之,報其自家之 ABI 號)。以今 SDK 編譯,所出即 ABI 13:

ABI所引入者
6mtrInit():宿主必構狀態之物件(零填充之塊施於非平凡之型,未定義之行也)
7資源字體度量+基線文字光柵入宿主服務
8invoke_api(完備 Java API 通道)、電梯快照、轉乘具型之模式;ABI 8 之庫,須 JCM 2.3.0-beta-2.yanyang.7 及以上之宿主
9轉乘 / 車輛規範交通類型之 id(MAGIC MTR 所擴);宿主則止逐幀抄其快照,之區之容量出參焉
10defer_free 延遲回收之鉤(腳本自有大緩衝,離 JVM 線程而釋)
11車輛快照之 door_direction(開門之向,0..3 —— 舊 _pad0 之位元組升格而為之,布局尺寸皆如其舊,老模塊行如故)
12MTR_RESOURCE_PSD(腳之第五類)暨 JcmPsdSnapshot / JcmPsdArrival / JcmPsdRoute / JcmPsdDoor 諸快照——純為增補,舊構一無所改;ABI 12 之庫,須晏陽 hotfix.2 以上之宿主
13JcmPsdSnapshot.station_offset(位元組之偏 124;-1 者無也——此欄於 ABI 12 猶填補之位)暨其後九十六位元組 JcmPsdStation 之記,以承 psd.stop() / mtr::Psd::stop():站名、其色(ARGB 及十六進位)、價區一至三、泊此站站諸線、鄰站線之分群、實體相通之站名、出口與所往、站台之號——純為增補,舊構一無所改;ABI 6–12 之模塊,照常載之
何以必拒舊宿主

函數指針之表,隨 ABI 而增:新模塊所呼之槽,舊宿主或闕焉。宿主視模塊所報之 ABI 號,擇所應之結構布局與餵料之法;不合則拒載——此刻意速敗之策也。

傳輸層(宿主之內,腳本所不見)

自 2.3.0-beta-2.yanyang.6(layout v2)以降,模組之內絕無 JNI:跨語言之流,悉承於二呼叫之平面——一曰 Panama FFM 平面(JDK 22+,libraryLookup + jcm_* downcall + upcall vtable),一曰共享記憶體輪詢之平面(任意 JDK ≥ 16;橋以建構子所啟後臺 poller 線程,經檔案系統之握手而得其區域,諸事皆經共享頁而役)。腳本之碼,於此全然無感——模塊所見,惟上述 C ABI 而已。


繼之:疾徐與除錯 —— 使腳本行且疾且穩。