From b7240037d10dd7c4750bc9fd825dfc30eca5d1e4 Mon Sep 17 00:00:00 2001 From: falsycat Date: Tue, 31 May 2022 22:07:41 +0900 Subject: [PATCH] add LuaJIT/Context --- CMakeLists.txt | 1 + common/lj_queue.hh | 25 ++++++++++++ file/luajit_context.cc | 92 ++++++++++++++++++++++++++++++++++++++++++ tool/init.cc | 2 + 4 files changed, 120 insertions(+) create mode 100644 common/lj_queue.hh create mode 100644 file/luajit_context.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 0584474..d987ca0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ target_sources(nf7 common/wait_queue.hh common/yas.hh + file/luajit_context.cc file/node_network.cc file/system_dir.cc file/system_imgui_config.cc diff --git a/common/lj_queue.hh b/common/lj_queue.hh new file mode 100644 index 0000000..256a213 --- /dev/null +++ b/common/lj_queue.hh @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include + +#include "nf7.hh" + + +namespace nf7::lj { + +class Queue : public File::Interface { + public: + using Task = std::function; + + Queue() = default; + Queue(const Queue&) = delete; + Queue(Queue&&) = delete; + Queue& operator=(const Queue&) = delete; + Queue& operator=(Queue&&) = delete; + + virtual void Push(const std::shared_ptr&, Task&&) noexcept = 0; +}; + +} // namespace nf7::lj diff --git a/file/luajit_context.cc b/file/luajit_context.cc new file mode 100644 index 0000000..a14c842 --- /dev/null +++ b/file/luajit_context.cc @@ -0,0 +1,92 @@ +#include +#include +#include +#include + +#include + +#include "nf7.hh" + +#include "common/dir_item.hh" +#include "common/generic_type_info.hh" +#include "common/lj_queue.hh" +#include "common/ptr_selector.hh" +#include "common/wait_queue.hh" + + +namespace nf7 { +namespace { + +class LuaContext final : public nf7::File, + public nf7::DirItem, + public nf7::lj::Queue { + public: + static inline const GenericTypeInfo kType = {"LuaJIT/Context", {"DirItem",}}; + + LuaContext(Env& env) noexcept : + File(kType, env), DirItem(DirItem::kTooltip), + th_([this]() { Main(); }) { + } + ~LuaContext() noexcept { + alive_ = false; + q_.Notify(); + th_.join(); + } + + LuaContext(Env& env, Deserializer&) noexcept : LuaContext(env) { + } + void Serialize(Serializer&) const noexcept override { + } + std::unique_ptr Clone(Env& env) const noexcept override { + return std::make_unique(env); + } + + void Push(const std::shared_ptr&, + std::function&& f) noexcept override { + q_.Push(std::move(f)); + } + + void UpdateTooltip() noexcept override; + + File::Interface* interface(const std::type_info& t) noexcept override { + return nf7::InterfaceSelector(t).Select(this); + } + + private: + std::atomic alive_ = true; + std::thread th_; + + std::atomic tasks_done_; + + nf7::WaitQueue> q_; + + void Main() noexcept { + lua_State* L = luaL_newstate(); + if (!L) { + alive_ = false; + return; + } + bool alive = true; + while (std::exchange(alive, alive_)) { + while (auto task = q_.Pop()) { + lua_settop(L, 0); + (*task)(L); + ++tasks_done_; + } + if (alive_) q_.Wait(); + } + lua_close(L); + } +}; + +void LuaContext::UpdateTooltip() noexcept { + ImGui::Text("tasks done: %zu", static_cast(tasks_done_)); + if (alive_) { + ImGui::TextDisabled("LuaJIT thread is running normally"); + } else { + ImGui::TextUnformatted("LuaJIT thread is **ABORTED**"); + } +} + +} +} // namespace nf7 diff --git a/tool/init.cc b/tool/init.cc index 6df440f..969b9ac 100644 --- a/tool/init.cc +++ b/tool/init.cc @@ -46,6 +46,8 @@ int main(void) { Write(ar, "System/ImGuiConfig"s, ""s) }, { "_logger"s, Write(ar, "System/Logger"s, WINDOW_(true), 1024, false, false) }, + { "_luajit"s, + Write(ar, "LuaJIT/Context"s) }, { "home"s, Write(ar, "System/Dir"s, std::map {}, WINDOW_(false)) }, }, WINDOW_(true));