main loop がブロックするので 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 できなかったのを修正
function と cdata を nil にしてスキップする処理を追加してみた
結果、巨大なテーブルの pack/unpack でブロックしてしまう。 あとスレッド側のエラーハンドリングをしてないので、デバッガはアタッチできないし、何もわからない。 pcall などでエラーメッセージを取得して、失敗した場合はエラーメッセージを投げるようにしてあげる必要がある。
なんとなく、使い方はわかった。 後で、アニメーションシステムを実装するときのインフラにも使えるかもしれない。 OpenGL のレンダースレッドと、シーン更新を分離する。