Skip to content

Instantly share code, notes, and snippets.

@poying
Last active June 25, 2016 13:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save poying/29ac7946fcc46cab6a1f2fae2d55889a to your computer and use it in GitHub Desktop.
Save poying/29ac7946fcc46cab6a1f2fae2d55889a to your computer and use it in GitHub Desktop.
Elm 0.17 Native Module 筆記

持續新增

製作 Native Module

Elm 裡的每個 Native module 就只是一個擁有許多 method 的 object,跟 CMD 的 exports 一樣,但存放物件的變數需要按照 Elm 的規則命名:

  • 基本規則:_{github_user_name}${github_repo_name}${module_name}
  • 使用 _ 替代 -elm-lang => elm_lang
  • module_name_ 替代 .Native.Electron.Window => Native_Electron_Window

大致上會長這樣:

var _user$repo$Native_ModuleName = {
  func: function () {}
};

為了避免 module 內部使用的變數污染全局,通常會使用 IIFE:

var _user$repo$Native_ModuleName = (function () {
  return {
    func: function () {}
  };
})();

Curry 化 Function/執行 Curry 化的 Function

Elm 提供了 F2 ~ F9 8 個 function(src/Pipeline/Generate.hs#L244-L326),FNN 代表參數個數,舉個例子:

var f1 = a => b => a + b;
var f2 = F2((a, b) => a + b);
// f1, f2 相同

Elm 也提供了執行 Curry 化的 Function 的 Function,A2 ~ A9 (src/Pipeline/Generate.hs#L328-L375):

var f = F2((a, b) => a + b);
A2(f, 1, 2) === f(1)(2);

建立 Task

_elm_lang$core$Native_Scheduler.nativeBinding(cb => {
  // 失敗時:
  // 這邊假設 Elm 已經有一個叫做 `Error` 的 Constructor:`type Error = Error String`
  cb(_elm_lang$core$Native_Scheduler.fail({ ctor: 'Error', _0: err.message }));

  // 成功時:
  // 回傳資料的方式同失敗時的處理方式,沒有資料回傳時回傳 `_Tuple0`
  cb(_elm_lang$core$Native_Scheduler.succeed({ ctor: '_Tuple0' }));
});

Electron

包裝 Electron API

https://gist.github.com/poying/45e6b176017d3a797109289750041513

Settings 處理方式

使用 Electron 製作 Desktop application 一定會有需要保留使用者設定的時候,但這些動作都是在 Elm architecture 之外,在 Elm 裡面不好使用,勢必要想一個比較漂亮的方式跟 Elm architecture 串在一起。Elm 提供兩種方式跟 JavaScript 溝通。

port 還是 native module?

兩種方法都可以。但 port 只能回傳 Cmd msg,無法知道成功或失敗。native module 可以建立 TaskTask 的好處在於可以使用 andThenonError 等 function 跟其他 Task 串聯,而且可以區分成功、失敗的 Cmd msg,所以我是傾向於都寫 native module。

載入 Settings

  1. [Node] 建立 Electron 的 Window
  2. [Node] 聽 ipcMaininit 事件
  3. [Browser] 聽 ipcRendererready 事件
  4. [Browser] 透過 ipcRendererinit 事件
  5. [Node] 讀取並 parse 檔案內容
  6. [Node] 透過 init 事件 listener 的第一個參數的 sender property 送 ready 事件連同設定內容回原來送 init 事件的那個 Window
  7. [Browser] 把設定內容餵給 Elm.Main.fullscreen 建立 Elm app,Elm 會自動幫我們把 JSON 轉成 Elm 內部我們定義的 data type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment