C ABI 與宿主服務
模塊與宿主之間,全約具焉。用 script.hpp 之基類與註冊宏,則此諸細務,SDK 悉代之——本頁為欲明疆界、自撰測試之驅、或排查載入之難者而作也。
模塊導出
每腳本庫導出 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_arena | UTF-8 字串流(貼圖 id、文字、聲音 id…) | 32 KB |
pixel_arena | BGRA8 像素流(紋理上傳) | 初 1 MB,按需增至 16 MB,閒則衰而復落 |
float_arena | float 流(體素碰撞匣等) | 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_TEXT | JcmDrawText | PIDS / 通用文字(TextWrapper 欄位逐一相準:對齊、溢出之式、跑馬燈、z 序、層、字體 id) |
JCM_DRAW_TEXTURE | JcmDrawTexture | 貼圖面片(UV、染色、z 序) |
JCM_DRAW_MODEL | JcmDrawModel | 車輛車廂 / 轉向架 / 裝飾模型(宿主模型之柄+姿態矩陣組) |
JCM_DRAW_SOUND | JcmDrawSound | 定位之音效(車廂局部坐標之偏) |
JCM_DRAW_LOCAL_SOUND | JcmDrawSound | 報站廣播(惟乘者所聞) |
JCM_DRAW_TEXTURE_UPLOAD | JcmDrawTextureUpload | GraphicsTexture 像素上傳(BGRA8+髒矩形) |
JCM_DRAW_OUTLINE_SHAPE | JcmDrawShape | 裝飾輪廓 / 碰撞匣(每匣 6 float;碰撞匣上限 1.5 格) |
JCM_DRAW_BLOCK_EVENT | — | 裝飾 onBlockUse 事件之握手 |
宿主回放此諸記錄,用與 JS 腳本全同之渲染程式碼路徑(PIDSDrawCall / ScriptRenderManager)——所繪者,同一物也。
宿主服務
JcmHostServices 者,函數指針之表也(in->host),渲染線程之內得而呼之。宿主之舊者,新槽為 null;呼前判其空,即得降級:
| 服務 | 始於 | 釋義 |
|---|---|---|
acquire_model / release_model | ABI 1 | 模型 JSON 柄之生命週期(映 ModelJS 之柄) |
create_texture / release_texture | ABI 1 | GraphicsTexture 之生命週期(映 Java 之類) |
rasterize_text | ABI 1 | 宿主 TTF 光柵之回呼(CJK 之屬);BGRA8 書於呼叫者之緩衝。返 -1 者,字體不覆該碼位也(宜退用內建之點陣字體) |
log | ABI 1 | console.log / console.error 之通道 |
acquire_quad_model | ABI 4 | 宿主構貼圖之面片(頂點四+UV+渲染階段+紋理之柄)——JS DisplayHelper 槽位模型之原生等物也;頂點屬模型空間,UV 以貼圖左上為原,y 則向下。無頭之驅返 -1,其時略而不繪 |
measure_font_text / draw_font_text | ABI 7 | 資源字體之度量與基線光柵(與 JS Graphics2D 同一字體、同一壓縮裁剪之義;髒邊界出參) |
invoke_api | ABI 8 | mtr::Api 之底層通道:UTF-8 JSON 之請入,結果出於線程局部緩衝(下次呼叫前有效) |
defer_free | ABI 10 | 以既死之大塊記憶體,付宿主後臺回收線程(詳見 疾徐與除錯) |
ABI 版本沿革
宿主所受,ABI 6–13 之模塊(各按其時代之布局而餵之,報其自家之 ABI 號)。以今 SDK 編譯,所出即 ABI 13:
| ABI | 所引入者 |
|---|---|
| 6 | mtrInit():宿主必構狀態之物件(零填充之塊施於非平凡之型,未定義之行也) |
| 7 | 資源字體度量+基線文字光柵入宿主服務 |
| 8 | invoke_api(完備 Java API 通道)、電梯快照、轉乘具型之模式;ABI 8 之庫,須 JCM 2.3.0-beta-2.yanyang.7 及以上之宿主 |
| 9 | 轉乘 / 車輛規範交通類型之 id(MAGIC MTR 所擴);宿主則止逐幀抄其快照,之區之容量出參焉 |
| 10 | defer_free 延遲回收之鉤(腳本自有大緩衝,離 JVM 線程而釋) |
| 11 | 車輛快照之 door_direction(開門之向,0..3 —— 舊 _pad0 之位元組升格而為之,布局尺寸皆如其舊,老模塊行如故) |
| 12 | MTR_RESOURCE_PSD(腳之第五類)暨 JcmPsdSnapshot / JcmPsdArrival / JcmPsdRoute / JcmPsdDoor 諸快照——純為增補,舊構一無所改;ABI 12 之庫,須晏陽 hotfix.2 以上之宿主 |
| 13 | JcmPsdSnapshot.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 而已。
繼之:疾徐與除錯 —— 使腳本行且疾且穩。