replace to nf7:yield() from a custom type of Node::Lambda in Lua script
This commit is contained in:
@@ -368,43 +368,6 @@ void PushMutableVector(lua_State* L, std::vector<uint8_t>&& v) noexcept {
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
void PushNodeLambda(lua_State* L,
|
||||
const std::shared_ptr<nf7::Node::Lambda>& callee,
|
||||
const std::weak_ptr<nf7::Node::Lambda>& caller) noexcept {
|
||||
constexpr auto kTypeName = "nf7::Node::Lambda";
|
||||
struct Data {
|
||||
std::shared_ptr<nf7::Node::Lambda> callee;
|
||||
std::weak_ptr<nf7::Node::Lambda> caller;
|
||||
};
|
||||
new (lua_newuserdata(L, sizeof(Data))) Data { .callee = callee, .caller = caller };
|
||||
|
||||
if (luaL_newmetatable(L, kTypeName)) {
|
||||
lua_pushcfunction(L, [](auto L) {
|
||||
const auto& d = *reinterpret_cast<Data*>(luaL_checkudata(L, 1, kTypeName));
|
||||
|
||||
auto caller = d.caller.lock();
|
||||
if (!caller) return luaL_error(L, "caller expired");
|
||||
|
||||
std::string n = luaL_checkstring(L, 2);
|
||||
auto v = nf7::luajit::CheckValue(L, 3);
|
||||
|
||||
auto callee = d.callee;
|
||||
callee->env().ExecSub(callee, [callee, caller, n = std::move(n), v = std::move(v)]() {
|
||||
callee->Handle(n, v, caller);
|
||||
});
|
||||
return 0;
|
||||
});
|
||||
lua_setfield(L, -2, "__call");
|
||||
|
||||
lua_pushcfunction(L, [](auto L) {
|
||||
reinterpret_cast<Data*>(luaL_checkudata(L, 1, kTypeName))->~Data();
|
||||
return 0;
|
||||
});
|
||||
lua_setfield(L, -2, "__gc");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
|
||||
std::optional<nf7::Value> ToValue(lua_State* L, int idx) noexcept {
|
||||
if (lua_isnoneornil(L, idx)) {
|
||||
|
@@ -9,7 +9,6 @@
|
||||
|
||||
#include <lua.hpp>
|
||||
|
||||
#include "common/node.hh"
|
||||
#include "common/value.hh"
|
||||
|
||||
|
||||
@@ -20,9 +19,6 @@ void PushImmEnv(lua_State*) noexcept;
|
||||
void PushValue(lua_State*, const nf7::Value&) noexcept;
|
||||
void PushVector(lua_State*, const nf7::Value::ConstVector&) noexcept;
|
||||
void PushMutableVector(lua_State*, std::vector<uint8_t>&&) noexcept;
|
||||
void PushNodeLambda(lua_State*,
|
||||
const std::shared_ptr<nf7::Node::Lambda>& callee,
|
||||
const std::weak_ptr<nf7::Node::Lambda>& caller) noexcept;
|
||||
|
||||
std::optional<nf7::Value> ToValue(lua_State*, int) noexcept;
|
||||
std::optional<nf7::Value::ConstVector> ToVector(lua_State*, int) noexcept;
|
||||
|
@@ -147,9 +147,6 @@ static void PushMeta(lua_State* L) noexcept {
|
||||
|
||||
// nf7:yield(results...)
|
||||
lua_pushcfunction(L, [](auto L) {
|
||||
auto th = Thread::GetPtr(L, 1);
|
||||
th->ExecResume(L);
|
||||
th->ExpectYield(L);
|
||||
return lua_yield(L, lua_gettop(L)-1);
|
||||
});
|
||||
lua_setfield(L, -2, "yield");
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -17,6 +18,7 @@
|
||||
#include "common/logger_ref.hh"
|
||||
#include "common/luajit.hh"
|
||||
#include "common/luajit_ref.hh"
|
||||
#include "common/node.hh"
|
||||
|
||||
|
||||
namespace nf7::luajit {
|
||||
@@ -40,9 +42,14 @@ class Thread final : public std::enable_shared_from_this<Thread> {
|
||||
|
||||
// Creates a handler to finalize a promise.
|
||||
template <typename T>
|
||||
static Handler CreatePromiseHandler(
|
||||
static inline Handler CreatePromiseHandler(
|
||||
nf7::Future<T>::Promise& pro, std::function<T(lua_State*)>&&) noexcept;
|
||||
|
||||
// Creates a handler to emit yielded value to Node::Lambda.
|
||||
static inline Handler CreateNodeLambdaHandler(
|
||||
const std::shared_ptr<nf7::Node::Lambda>& caller,
|
||||
const std::shared_ptr<nf7::Node::Lambda>& callee) noexcept;
|
||||
|
||||
// must be called on luajit thread
|
||||
static std::shared_ptr<Thread> GetPtr(lua_State* L, int idx) {
|
||||
auto th = CheckWeakPtr<Thread>(L, idx, kTypeName);
|
||||
@@ -176,4 +183,42 @@ Thread::Handler Thread::CreatePromiseHandler(
|
||||
};
|
||||
}
|
||||
|
||||
Thread::Handler Thread::CreateNodeLambdaHandler(
|
||||
const std::shared_ptr<nf7::Node::Lambda>& caller,
|
||||
const std::shared_ptr<nf7::Node::Lambda>& callee) noexcept {
|
||||
return [caller, callee](auto& th, auto L) {
|
||||
switch (th.state()) {
|
||||
case nf7::luajit::Thread::kPaused:
|
||||
switch (lua_gettop(L)) {
|
||||
case 0:
|
||||
th.ExecResume(L);
|
||||
return;
|
||||
case 2: {
|
||||
auto k = luaL_checkstring(L, 1);
|
||||
auto v = nf7::luajit::CheckValue(L, 2);
|
||||
caller->env().ExecSub(
|
||||
caller, [caller, callee, k = std::string {k}, v = std::move(v)]() {
|
||||
caller->Handle(k, v, callee);
|
||||
});
|
||||
} return;
|
||||
default:
|
||||
if (auto log = th.logger()) {
|
||||
log->Warn("invalid use of yield, nf7:yield() or nf7:yield(name, value)");
|
||||
}
|
||||
th.Resume(L, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
case nf7::luajit::Thread::kFinished:
|
||||
return;
|
||||
|
||||
default:
|
||||
if (auto log = th.logger()) {
|
||||
log->Warn(std::string {"luajit execution error: "}+lua_tostring(L, -1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace nf7::luajit
|
||||
|
Reference in New Issue
Block a user