20210729lua

luv

main loop がブロックするので luv を取り入れてみる。

https://github.com/luvit/luv

cmake で build

luv に CMake が付属しており簡単。

$ cmake -S {LUV_DIR} -B {BUILD_DIR}
$ cmake --build {BUILD_DIR} --config Release

main loop を idle へ

-- Main loop
while app:new_frame() do
    gui:update()
    app:render(gui.clear_color)
end
local uv = require("luv")

-- Main loop
local idle = uv.new_idle()
idle:start(function()
    if not app:new_frame() then
        idle:stop()
    end
    gui:update()
    app:render(gui.clear_color)
end)

uv.run("default")

重い処理を thread へ

    local ctx = uv.new_work(
        on_thread, --work,in threadpool
        on_end --after work, in loop thread
    )
    uv.queue_work(ctx, mp.pack({ ... }))
Error: thread arg not support type 'table' at 2Error: thread arg not support type table at 1Uncaught Error: attempt to call a nil value

thread 間で受け渡しのできる型

unknown: blockquote => {"type":"blockquote","children":[{"type":"paragraph","children":[{"type":"text","value":"threadargs: variable arguments (...) of type nil, boolean, number, string, or userdata","position":{"start":{"line":61,"column":3,"offset":983},"end":{"line":61,"column":89,"offset":1069}}}],"position":{"start":{"line":61,"column":3,"offset":983},"end":{"line":61,"column":89,"offset":1069}}}],"position":{"start":{"line":61,"column":1,"offset":981},"end":{"line":61,"column":89,"offset":1069}}}

nvim ではそこで messagepack なわけか。

Kyoto Tycoon+Lua-JIT拡張+MessagePack=無敵 経由で The state of MessagePack in Lua をたどり着く。

unknown: blockquote => {"type":"blockquote","children":[{"type":"paragraph","children":[{"type":"text","value":"If you want pure LuaJIT -> luajit-msgpack-pure","position":{"start":{"line":67,"column":3,"offset":1288},"end":{"line":67,"column":49,"offset":1334}}}],"position":{"start":{"line":67,"column":3,"offset":1288},"end":{"line":67,"column":49,"offset":1334}}}],"position":{"start":{"line":67,"column":1,"offset":1286},"end":{"line":67,"column":49,"offset":1334}}}

たしかに、これだ。

https://github.com/catwell/luajit-msgpack-pure

  • Windows なので malloc, free, realloc が cdef できなかったのを修正

  • functioncdata を nil にしてスキップする処理を追加してみた

結果、巨大なテーブルの pack/unpack でブロックしてしまう。 あとスレッド側のエラーハンドリングをしてないので、デバッガはアタッチできないし、何もわからない。 pcall などでエラーメッセージを取得して、失敗した場合はエラーメッセージを投げるようにしてあげる必要がある。

なんとなく、使い方はわかった。 後で、アニメーションシステムを実装するときのインフラにも使えるかもしれない。 OpenGL のレンダースレッドと、シーン更新を分離する。

関連