add LuaJIT/Context

This commit is contained in:
falsycat 2022-05-31 22:07:41 +09:00
parent 763d884a2d
commit b7240037d1
4 changed files with 120 additions and 0 deletions

View File

@ -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

25
common/lj_queue.hh Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include <memory>
#include <lua.hpp>
#include "nf7.hh"
namespace nf7::lj {
class Queue : public File::Interface {
public:
using Task = std::function<void(lua_State*)>;
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<nf7::Context>&, Task&&) noexcept = 0;
};
} // namespace nf7::lj

92
file/luajit_context.cc Normal file
View File

@ -0,0 +1,92 @@
#include <atomic>
#include <functional>
#include <memory>
#include <thread>
#include <imgui.h>
#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<LuaContext> 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<File> Clone(Env& env) const noexcept override {
return std::make_unique<LuaContext>(env);
}
void Push(const std::shared_ptr<nf7::Context>&,
std::function<void(lua_State*)>&& 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<nf7::DirItem, nf7::lj::Queue>(t).Select(this);
}
private:
std::atomic<bool> alive_ = true;
std::thread th_;
std::atomic<size_t> tasks_done_;
nf7::WaitQueue<std::function<void(lua_State*)>> 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<size_t>(tasks_done_));
if (alive_) {
ImGui::TextDisabled("LuaJIT thread is running normally");
} else {
ImGui::TextUnformatted("LuaJIT thread is **ABORTED**");
}
}
}
} // namespace nf7

View File

@ -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<std::string, L> {}, WINDOW_(false)) },
}, WINDOW_(true));