[Go Library]Loca-カウンタ



ライブラリLORCAを使用してカウンタページを作成します.
例題ページでは、Lorcaで関数を使用する方法について説明します.

counter.go

//go:embed index.html
var fs embed.FS

type counter struct {
	sync.Mutex
	count int
}

織機と沈布機構造体


コーランを用いたリンベドは,index.htmlファイルを変数に含めた.// go:embed [파일이름]に注記するだけで、その内容を変数に格納できます.
開発者がしなければならないのはembedを構築することだけです.
ファイルを読み込むときに、シンボルが無効または読み込めない場合は、コンパイルエラーが発生します.embed.FS形式のファイルシステムとしてのみならず、バイトまたは文字列としても使用できます.
UIにバインドされている高タイプは、スレッドを安全にする必要があります.各バインディング自体が高スレッドで実行されるため、counter構造体ではMutexが使用される.
上記の場合、原子性は使用できます.
ただし、より複雑な場合は、適切な同期を使用してください.

カウンタ

func (c *counter) Add(n int) {
	c.Lock()
	defer c.Unlock()
	c.count = c.count + n
}

func (c *counter) Value() int {
	c.Lock()
	defer c.Unlock()
	return c.count
}
Addトランシーバはスレッドを安全にロック解除し、countnを追加する.Valueトランシーバは同様に安全にロックを解除し、countに戻る.

かんすうカウンタ


インデックスUIを解放し、カウンタオブジェクトをバインドします.
func Couter() {
	...
}

Lorca


ローカを始めよう
args := []string{}
if runtime.GOOS == "linux" {
	args = append(args, "--class=Lorca")
}
ui, err := lorca.New("", "", 480, 320, args...)
if err != nil {
	log.Fatal(err)
}
defer ui.Close()
lorca.Newを通じて最終買収に様々な情報を伝える.
2行目のユーザのオペレーティングシステムがLinuxであることを確認すると--class=Lorcaのメッセージが送信される.
GUIの幅および高さをさらに指定し、deferによって遅延されたClose()を実行する.

UIバインド

ui.Bind("start", func() {
	log.Println("UI is ready")
})

c := &counter{}
ui.Bind("counterAdd", c.Add)
ui.Bind("counterValue", c.Value)
フォーマットはui.Bind(name string, f interface{})です.nameは、jsにおける関数名に使用される変数名である.
従って、上記の場合には、出力"start"UI is readyにログする"counterAdd"にバインドc.Add"couterValue"にバインドされます.

HTMLのロード

ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
	log.Fatal(err)
}
defer ln.Close()
go http.Serve(ln, http.FileServer(http.FS(fs)))
ui.Load(fmt.Sprintf("http//%s/index.html", ln.Addr()))
前述したようにChromeによるリモートバインディングはソケットによる交換であるため,c.Value関数を用いてネットワーク接続を行う.
その後,Lorcaはユーザがインストールしたクロムで交換する.
その後、net.Listen関数により、対応するネットワークでHTTP接続を受け付け、新しい高スレッドを作成する.次に、以前保存したhttp.Serveファイルのパスにリダイレクトします.
その後、アドレスの内容は、以前に生成されたindex.htmlにロードされる.

JavaScript

ui.Eval(`
	console.log("Hello, world!");
	console.log('Multiple values:', [1, false, {"x":5}]);
`)
前述したように、JSコードはui関数でデバッグすることもできる.

の最後の部分

sigc := make(chan os.Signal)
signal.Notify(sigc, os.Interrupt)
select {
case <-sigc:
case <-ui.Done():
}
チャネルを作成し、UIの割り込みまたは終了を待機します.

index.html

<!doctype html>
<html>
<head>
    ...
</head>
<body onload=start()>
  ...
</body>
</html>
上のbodyのEvalを見ると、前にバインドされたonload=start()が呼び出されていることがわかります.

アプリケーションを実行すると、上図に示すbodyロードがgoのstartを完了したことを確認できます.
<script>
    const counter = document.querySelector('.counter');
    const btnIncr = document.querySelector('.btn-incr');
    const btnDecr = document.querySelector('.btn-decr');

    // GO 기능이 비동기적이기 때문에 async/await 를 사용한다.
    const render = async () => {
        counter.innerText = `Count: ${await counterValue()}`;
    };

    btnIncr.addEventListener('click', async () => {
        await counterAdd(1); // Call Go function
        render();
    });

    btnDecr.addEventListener('click', async () => {
        await counterAdd(-1); // Call Go function
        render();
    });

    render();
</script>
上のコードも、クリックイベントリスナー内でgoがバインドされた関数を呼び出していることを示しています.
goの機能は非同期なので、JavaScriptでもstartキーワードを使用して同じ非同期を使用する必要があります.