成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Emscripten教程之Emscripten的運行時環(huán)境(二)

VishKozus / 1910人閱讀

摘要:運行時環(huán)境與大多數(shù)應(yīng)用程序所期望的環(huán)境不同。不過程序是要手動交換緩沖區(qū)的。第一個主題介紹代碼可移植性與限制第二個主題介紹的運行時環(huán)境第三個主題第一篇文章介紹連接和第三個主題第二篇文章介紹第四個主題介紹文件和文件系統(tǒng)第六個主題介紹如何調(diào)試代碼

翻譯:云荒杯傾
本文是Emscripten-WebAssembly專欄系列文章之一,更多文章請查看專欄。
也可以去作者的博客閱讀文章。

Emscripten運行時環(huán)境與大多數(shù)C/C++應(yīng)用程序所期望的環(huán)境不同。Emscripten努力抽象和減輕這些差異,因此在一般的代碼中,可以用很少或沒有更改來編譯。

本文描述了一些差異和由此產(chǎn)生的API限制,并概述了您可能需要對C/C++代碼做出的一些更改。

1、輸入/輸出

Emscripten為瀏覽器環(huán)境實現(xiàn)了簡單的DirectMedia Layer API(SDL),它提供了對音頻、鍵盤、鼠標、操縱桿和圖形硬件的底層訪問。使用了SDL的應(yīng)用程序通常不需要為了在瀏覽器中運行做輸入/輸出方面的更改。

不過,我們對glut, glfw, glew 和 xlib等庫有一些支持上的限制。

不使用SDL或其他api的應(yīng)用程序可以使用Emscripten特有的API來輸入和輸出,他們是:

html5.h,它定義了Emscripten底層膠水綁定以使得本地代碼可以與HTML5事件進行交互,包括訪問鍵盤、鼠標、滾輪、設(shè)備方向、電池級別、振動等。

多媒體和圖形API,包括OpenGL和EGL。

2、文件系統(tǒng)

很多C/C++代碼使用libc和libcxx中的同步文件系統(tǒng)APIs來訪問本地文件系統(tǒng)中的代碼。這是有問題的,因為瀏覽器是不會讓代碼直接訪問主機系統(tǒng)上的文件的,而且JavaScript只支持異步文件訪問(在web worker之外)。

Emscripten 提供了libc和libcxx的一種實現(xiàn),并且提供了一個虛擬文件系統(tǒng),這樣正常的C/C++代碼可以在不需要修改的情況下被編譯然后運行。開發(fā)者需要做的只是將文件集合在預加載階段打包放到這個虛擬文件系統(tǒng)。

NOTE:
文件數(shù)據(jù)在  “編譯期間”  打包,并在 “ 代碼運行之前 ” 使用異步JavaScript api下載到虛擬文件系統(tǒng)中。
編譯后的代碼發(fā)出“文件”調(diào)用操作,實際上只是調(diào)用程序內(nèi)存。

默認文件系統(tǒng)(MEMFS)在內(nèi)存存儲文件,如果文件做了修改但是頁面reload了,則修改的工作就白做了。如果想永久地存儲文件的更改,那么開發(fā)人員可以安裝IDBFS文件系統(tǒng),該系統(tǒng)允許在瀏覽器中持久化數(shù)據(jù)。
如果是在node.js中運行代碼,開發(fā)人員可以安裝NODEFS,它可以讓代碼直接訪問本地文件系統(tǒng)。

Emscripten也有一個API支持同步文件獲取。

更多信息

3、瀏覽器主循環(huán)

瀏覽器事件模型使用合作模式的多任務(wù)處理——每個事件都有一個運行的“turn”,然后必須將控制權(quán)返回給瀏覽器事件循環(huán),這樣其他事件就可以處理了。HTML頁面掛起的一個常見原因是JavaScript未完成并且未將控制權(quán)返回給瀏覽器。

圖形化C++應(yīng)用程序通常在一個無限循環(huán)中運行。在循環(huán)的每個迭代中,應(yīng)用程序執(zhí)行事件獲取、處理和渲染,接著是延遲(“等待”)以保持幀速率為常數(shù)。無限循環(huán)在瀏覽器環(huán)境中是一個問題,因為沒有辦法把控制權(quán)返回到瀏覽器以執(zhí)行其他代碼。通常是在一段時間之后,瀏覽器將通知用戶該頁面被卡住并提供停止或關(guān)閉它的操作。

同樣,js中的webGL API也需要當上一個事件完成之后,才開始運行的,然后自動渲染并且交換緩沖區(qū)。不過OpenGL C++程序是要手動交換緩沖區(qū)的。

C/C++中實現(xiàn)異步主循環(huán)

這個問題的標準解決方案是定義一個C函數(shù),它執(zhí)行主循環(huán)的一次迭代(不包括“延遲”)。對于本機編譯,可以在無限循環(huán)中調(diào)用這個函數(shù),從而有效地保持行為不變。

但在Emscripten編譯的代碼中,我們使用emscripten_set_main_loop()來獲得環(huán)境,從而以指定頻率調(diào)用相同的函數(shù)。迭代仍然是“無限的”,但現(xiàn)在可以在迭代之間運行其他代碼,而且瀏覽器不會掛起。

下面給個示例:

int main() {
...
#ifdef __EMSCRIPTEN__
  // void emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop);
  emscripten_set_main_loop(one_iter, 60, 1);
#else
  while (1) {
    one_iter();
    // Delay to keep frame rate constant (using SDL)
    SDL_Delay(time_to_next_frame());
  }
#endif
}

// The "main loop" function.
void one_iter() {
  // process input
  // render to screen
}
NOTE:
當你使用SDL時,您可能需要設(shè)置主循環(huán)。你也應(yīng)該注意:
1. As the page is shut, it will force a final direct call to the main loop, giving it a chance to
 notice the SDL_QUIT event. If you do not use a main loop, your app will close before you have
 had an opportunity to notice this event.
2.There are limitations to what you can do as the page shuts (in onunload). Some actions like
 showing alerts are banned by browsers at this point.
4、執(zhí)行生命周期

當你的Emscripten編譯后程序已經(jīng)加載完畢后,就開始預加載文件的階段。(可以通過emcc --preload-file設(shè)置要預加載的文件,也可以使用 FS.createPreloadedFile()手動加載),在這個階段進行文件安裝。

您可以使用addRunDependency()添加額外的操作,這是一個依賴項計數(shù)器,他要在編譯后的代碼運行之前執(zhí)行。當這些已經(jīng)完成,您可以調(diào)用removeRunDependency()來刪除已完成的依賴項。

一般來說,不需要添加額外的操作,預加載幾乎能滿足你的需求。

當滿足所有依賴項時,Emscripten將調(diào)用run()函數(shù),run()函數(shù)將調(diào)用您的main()函數(shù)。main()函數(shù)應(yīng)該用于執(zhí)行初始化任務(wù),并且通常main()要調(diào)用emscripten_set_main_loop()(如上所述)。然后主循環(huán)函數(shù)將按請求的頻率被調(diào)用。

您可以通過多種方式影響主循環(huán)的操作:

emscripten_push_main_loop_blocker()添加一個函數(shù),該函數(shù)阻塞主循環(huán),直到攔截器完成為止。舉個例子,當你加載一個新的游戲級別的時候,這是有用的。一個游戲級別完成,你放一個一些阻塞塊來做解包文件,生成數(shù)據(jù)結(jié)構(gòu)

等操作。當所有阻塞塊完成,主循環(huán)就可以重新開始一個新等級的游戲。emscripten_push_main_loop_blocker()可以和emscripten_set_main_loop_expected_blockers()函數(shù)一起使用,這能讓用戶知道進度。

emscripten_pause_main_loop()會暫停主循環(huán),emscripten_resume_main_loop()重新開始主循環(huán)。不推薦使用這兩個函數(shù),因為他們其實是blocker函數(shù)(上面那條)的更底層替代品。

*emscripten_async_call()讓你在特定間隔調(diào)用一個函數(shù)。這個是在模擬requestAnimationFrame(默認)和setTimeout。

這里有很多其他方法來控制執(zhí)行

5、Emscripten中內(nèi)存表示

Emscripten中內(nèi)存模型是Typed Arrays Mode 2。他使用單種類型數(shù)組表達內(nèi)存,不過提供了多種類型視圖來讀取內(nèi)存。(HEAPU8、HEAPU16、HEAPU32等)。

NOTE:
Typed Arrays Mode 2是Fastcomp編譯器支持的唯一內(nèi)存模型,它是舊編譯器的默認內(nèi)存模型。
與本項目所嘗試的其他內(nèi)存模型相比,它適用于許多的任意編譯后的代碼,而且速度相對較快。

這個模型以與普通C和C++相同的方式在內(nèi)存中l(wèi)ays out items,它和C/C++使用相同數(shù)量的內(nèi)存。

這個模型允許您使用違背 load-store consistency假設(shè)的代碼。由于不同的視圖顯示了相同的數(shù)據(jù),所以您可以(比方說)編寫一個32位的整數(shù),然后從中間讀取一個字節(jié),它就像在大多數(shù)平臺上本地構(gòu)建C或C++那樣工作。

Emscripten代碼移植系列文章

Emscripten代碼移植主題系列文章是emscripten中文站點的一部分內(nèi)容。
第一個主題介紹代碼可移植性與限制
第二個主題介紹Emscripten的運行時環(huán)境
第三個主題第一篇文章介紹連接C++和JavaScript
第三個主題第二篇文章介紹embind
第四個主題介紹文件和文件系統(tǒng)
第六個主題介紹Emscripten如何調(diào)試代碼

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/91892.html

相關(guān)文章

  • Emscripten教程代碼可移植性與限制(一)

    摘要:教程之代碼可移植性與限制一翻譯云荒杯傾本文是專欄系列文章之一,更多文章請查看專欄。下面是正文代碼可移植性與限制幾乎可以編譯任何可移植的代碼到。如果標準機構(gòu)將共享狀態(tài)添加到中,支持多線程代碼將成為可能。 Emscripten教程之代碼可移植性與限制(一) 翻譯:云荒杯傾本文是Emscripten-WebAssembly專欄系列文章之一,更多文章請查看專欄。也可以去作者的博客閱讀文章。歡迎...

    yangrd 評論0 收藏0
  • Emscripten教程優(yōu)化你代碼

    摘要:優(yōu)化項也會引發(fā)一些問題。檢查你的代碼是否工作并修復問題。從起,及以上的優(yōu)化級別默認啟動了這項設(shè)置。目前正在進行改進。代碼移植系列文章代碼移植主題系列文章是中文站點的一部分內(nèi)容。 作者:云荒杯傾歡迎加入Wasm和emscripten技術(shù)交流群,群聊號碼:939206522。 這是關(guān)于Emscripten的系列文章,更多文章請看下面鏈接。 Emscripten代碼移植系列文章 Emscr...

    Jokcy 評論0 收藏0
  • Emscripten教程優(yōu)化你代碼

    摘要:優(yōu)化項也會引發(fā)一些問題。檢查你的代碼是否工作并修復問題。從起,及以上的優(yōu)化級別默認啟動了這項設(shè)置。目前正在進行改進。代碼移植系列文章代碼移植主題系列文章是中文站點的一部分內(nèi)容。 作者:云荒杯傾歡迎加入Wasm和emscripten技術(shù)交流群,群聊號碼:939206522。 這是關(guān)于Emscripten的系列文章,更多文章請看下面鏈接。 Emscripten代碼移植系列文章 Emscr...

    bladefury 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<