晏陽增補

增補一覽

增補門戶一言
JS 與 C++ 相雜之條宣告之條一條之內,JS 與 C++ 模塊隨意相雜,雙引擎並時而繪
開門方向之記VehicleWrapper.getDirectionOfDoorOpening()到站何側啟門——站台之期、正線之測,跨視距者服端為記
交通類型之細分VehicleWrapper.getTransportType() 之屬線路細分類型之 id(與 MAGIC MTR 相連)與轉乘增益之欄
直寫像素之上傳GraphicsTexture.uploadRawABGR()字節行陣直書,惟上傳髒區——逐像素高頻更新省頻寬之途
相容之別名宣告之條受 NTE 文檔示例 script_input 之鍵名;nativeLibrary / nativeLibraries 得與 .js 相雜而用

JS 與 C++ 相雜之條

上游之式,一條腳本,其語惟一。晏陽以判定之權付諸文件之徵:scriptLocations 每條各自觀之——*.js(不辨大小寫)者歸 JavaScript,餘者悉按 C++ 模塊解之。一條之內,二種隨意相雜,其數無限:

"vehicleScripts": [
    {
        "id": "demo:sp1900",
        "scriptLocations": [
            "demo:js/sp1900_ui.js",
            "demo:natives/sp1900_motor",
            {"windows": "demo:natives/win-x64/libmotor.dll",
             "linux":   "demo:natives/linux-x64/libmotor.so",
             "macos":   "demo:natives/macos-arm64/libmotor.dylib"}
        ],
        "prependExpressions": ["print('JS 側照常執行')"],
        "input": { "era": 2004 }
    }
]

C++ 之宣告,其式有三:

式書法所解
平臺無關之 stem"demo:natives/sp1900_motor"每平臺各自展之:natives/linux-x64/libsp1900_motor.so、natives/windows-x64/sp1900_motor.dll、natives/macos-arm64/libsp1900_motor.dylib……(目錄之布局,詳見 入門)
完整庫之徑"demo:natives/linux-x64/libfoo.so"按副檔名而繫其系統;他系則略此條
按平臺而映之表{"windows": ..., "linux": ..., "macos": ...}鍵得精至架構(macos-arm64、linux-x64……),精確之鍵先於通用之鍵;值之本身,又為 stem 或完整之徑

二引擎各繪其所:JS 之部(連 prependExpressions 與 input 併之)拼為一份腳本而解析;C++ 之部悉懸於同一腳本 id 之下,由原生管理器載之。渲染之時,兩側各自捕、各自回放,繪製之令互不相犯;一側缺焉或載敗焉,惟彼側不畫而已,不至累及他側。

language 欄(兜底之關)

值其效
不書(薦)按文件之徵自判——諸景之眾,一無配置
"cpp"純原生之條(舊義也):scriptLocations 中之 .js 見略,日誌留示;配 nativeLibrary / nativeLibraries 而用
"javascript" / "js"強使全按 JS 而解——無副檔名 JS 文件名之生路也

欄名依格式而定:MTR 四代之鍵曰 language,舊式則 scriptLang(駝峰)/ script_lang(下劃線)。nativeLibrary / nativeLibraries(後者使一 id 懸多庫)無論何時,皆按 C++ 處之,亦得與 .js 同條共存。

與純 JS 條之關係

prependExpressions / input / rateLimit / dataFetchMode 諸 JS 之欄,其義不變;純 JS 之條(悉為 .js),所行與上游全同。C++ 側讀 input 之法,見 C++ 之檔。

開門方向之記

VehicleWrapper.getDirectionOfDoorOpening(): String 所以答「此列將啟何側之門」;其值:"not"(兩側皆弗啟)/ "left"(車頭之左)/ "right"(車頭之右)/ "all"(兩側):

  • 泊於站台之時:門未啟、半啟、方闔、既闔,所答皆與全啟無異——站台之塊(或既解鎖之 PSD / APG 門)在何側,何側即謂「將啟」。門值 > 0,則逕讀本幀逐廂之判。
  • 行於正線之時:測下一站啟門之側——置列車於當泊之點於自家路徑之上,循 MTR 同款 canOpenDoors 察塊之法。停點之區既載,立即可用;逾視距則改由服端作答:服端全圖既掃一遭而恆存之(站台之塊有增刪改,自為增補重掃),按線路緩其兩側之答以應所請——中途登車、重啟遊戲、初至之站,皆行如常。
  • 服端未具本模組,或未之應:則退為客端自家視距內之掃;此時遠處站台之測,或不可得。
  • 聚之規:一側苟有一廂之門旁具站台之塊,舉側悉記可啟(按側而聚,不按單門)。左右以車頭(轉向架 1 端)為準:每廂於自家坐標系中評之(-X 者,車頭之左,MTR 模型之慣例);行向與折返,皆弗易其讀。
  • 純詢而已:惟佐顯示之邏輯(啟門側之指示、車內屏之箭矢),門實啟閉,仍司於 MTR。
例:門側之示燈
function render(ctx, state, vehicle) {
    let dir = vehicle.getDirectionOfDoorOpening();   // "not"/"left"/"right"/"all"
    if (dir == "left" || dir == "all") drawLamp(ctx, state, "left", 0x00FF00);
    if (dir == "right" || dir == "all") drawLamp(ctx, state, "right", 0x00FF00);
}

交通類型之細分

MTR 之 TransportMode,惟基礎之式凡四(train / boat / cable_car / airplane),於顯示有所不贍。MAGIC MTR 附加之模組,許玩家於「列車」復細分顯示之類(存於其 route_types.json,以線路 id 為鍵)。本支使此諸類貫通乎腳本:

  • VehicleWrapper.getTransportType(): String —— 當前線路規範類型之 id:MAGIC 既指其細分(train_normal / train_light_rail / train_high_speed / train_metro / train_bus / train_tram / train_sbahn)則用之;否則回落基礎模式之 id(train / boat / cable_car / airplane);不可解者為 unknown,永不為 null。
  • Stop.routeInterchanges[i](RouteInterchange)所增:getTransportMode(): TransportMode?(轉乘線路交通之模式,舊數據或為 null)、getTransportType(): String(同上規範之 id)、getRouteId(): long(來源線路之 id,服端數據缺者為 0)——轉乘之牌按類擇圖 / 配色之時,不復惟色可讀。
  • MAGIC 未裝,或該線路未蒙指派,則一切照舊回落基礎之式——腳本無須探附加模組之存亡。類型所詢之果,按線路為之短緩存(約一秒);MTR 之中改其類,俄頃可見。

用之諸處

規範類型之 id,非惟 vehicle.getTransportType() 一處用之——宿主之內、兩側之腳本,凡所用之處,具列於下:

用之之處所在之側釋之
vehicle.getTransportType()JS · 車輛腳本本節之主門;車若掛 C++ 之腳本,宿主築快照亦呼之(每車每幀一遭),以其字串書入快照字串之池
stop.routeInterchanges[i].getTransportType()
stop.connectingInterchanges[相連車站之名][i].getTransportType()
JS · 車輛腳本轉乘諸條,逐條同一 id;類型由服端預解,隨轉乘之數據同下(以服端所指為準,客端 MAGIC 有無皆得之);舊版數據缺此字段,客端方按 getRouteId() 自查以補
mtr::Vehicle::getTransportType()(舊名 mtr::Train)
mtr::Stop::interchange(i).getTransportType()
C++ 快照 · ABI 9 起直讀快照字串之池中宿主預書之串,與 JS 所得全然一致;詳見 數據快照

以上諸處所讀,同出一源——一處所得之 id,諸處必同。

直寫像素之上傳

GraphicsTexture.uploadRawABGR(source: byte[], dstOffsetX: int, dstOffsetY: int, width: int, height: int, ppm: int[]): void

以 width × height × 4 字節、行先、BGRA 之序之像素行陣,直書於紋理之緩衝,且惟以此矩形上諸顯存:

  • 其位:逐像素高頻更新省頻寬之途也。尋常 AWT 之 upload() 搬全圖;4 Mpx 之屏每幀整傳,即十數 MB 之搬運;而逐點之動(進度之條、跳字之屬),尋常惟改一小條——以此法,數百 KB 足矣。
  • ppm 者,4 × 256 項預乘之查表(依次 B / G / R / A 四段,各 256 項),呼者執之;字節按表展開而書,免逐像素為乘。
  • 既書,自惟上傳該矩形,紋理之餘仍其故——較 upload(x, y, w, h),省「先於 AWT 畫布改之」之一步。
  • JS 之中亦得用之(配 Java.newArray 以組字節之陣列);然其設計之初衷,乃為 C++ 橋幀像素之回傳;純 JS 之作者,用 AWT 加子域上傳即可。

JS 與 C++ 詞彙之一致

同一數據,二語同名——相雜之條,兩側共繪一物,不致迷亂也:

JSC++(SDK)所引入
vehicle.getTransportType()mtr::Vehicle::getTransportType()ABI 9
Stop.routeInterchanges[i].getTransportType() 等mtr::Stop::interchange(i) 之類型欄ABI 9
vehicle.getDirectionOfDoorOpening()mtr::Vehicle::doorDirection() / getDirectionOfDoorOpening()ABI 11

純 JS 之讀者,記一事足矣:本頁之增補,C++ 側同樣可用(快照之欄直讀,零搬運之費),見 數據快照。


返:JS 之腳類型 · JS 公器;欲同類之數據而無 JVM 之費乎?觀 C++ 原生腳本。