Enable interrupting pure Lua loops

This commit is contained in:
redfast00 2021-09-16 18:16:30 +02:00
parent ec7290984e
commit f5501273e2
No known key found for this signature in database
GPG Key ID: 5946E0E34FD0553C
6 changed files with 46 additions and 9 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
.build/
build/
editor/.idea/
editor/.cache
editor/dist

View File

@ -5,7 +5,6 @@ function all_leds(red, green, blue)
end
while true do
print(ledamount())
all_leds(255, 128, 0)
delay(1000)
all_leds(0, 128, 255)

2
demo/2.lua Normal file
View File

@ -0,0 +1,2 @@
print("script begin")
while true do end

View File

@ -1,3 +1,4 @@
#!/bin/bash
scp -r main root@10.1.0.212:ledstrip_sandbox/
scp -r main root@10.1.0.212:ledstrip_sandbox/
ssh root@10.1.0.212 "cd ledstrip_sandbox/ && cmake --build build"

View File

@ -17,6 +17,9 @@
#include "httplib.h"
using json = nlohmann::json;
using std::chrono::duration_cast;
using std::chrono::milliseconds;
using std::chrono::system_clock;
#define TARGET_FREQ WS2811_TARGET_FREQ
@ -62,9 +65,28 @@ ws2811_t ledstring =
},
},
};
void hook(lua_State* L, lua_Debug *ar);
inline bool kill_thread_if_desired(lua_State *L) {
if (!statemap[L]->enabled)
{
cout << "putting errors on the stack" << endl;
lua_sethook(L, hook, LUA_MASKLINE, 0);
luaL_error(L, "killed by manager");
return true;
}
return false;
}
// TODO also call this hook about once every second
void hook(lua_State* L, lua_Debug *ar)
{
kill_thread_if_desired(L);
}
extern "C" {
static int c_override_print (lua_State *L) {
kill_thread_if_desired(L);
int n = lua_gettop(L); /* number of arguments */
int i;
for (i = 1; i <= n; i++) { /* for each argument */
@ -80,6 +102,7 @@ extern "C" {
}
static int c_led (lua_State *L) {
kill_thread_if_desired(L);
int virtual_location = luaL_checkinteger(L, 1);
int red = luaL_checkinteger(L, 2);
int green = luaL_checkinteger(L, 3);
@ -115,17 +138,27 @@ extern "C" {
}
static int c_ledamount(lua_State *L) {
kill_thread_if_desired(L);
lua_pushinteger(L, statemap[L]->length);
return 1;
}
static int c_delay(lua_State *L) {
int millis = luaL_checkinteger (L, 1);
std::this_thread::sleep_for(std::chrono::milliseconds(millis));
if (kill_thread_if_desired(L)) {return 0;}
uint64_t millis = luaL_checkinteger (L, 1);
uint64_t begin = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
while (duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count() - begin < millis - 100) {
std::this_thread::sleep_for(std::chrono::milliseconds(100-5));
if (kill_thread_if_desired(L)) {return 0;}
}
uint64_t passed = (duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count() - begin);
std::this_thread::sleep_for(std::chrono::milliseconds(millis-passed));
return 0;
}
static int c_waitframes(lua_State *L) {
kill_thread_if_desired(L);
int amount = luaL_checkinteger(L, 1);
uint64_t destination = amount + framecounter;
if (amount >= 2 * FPS) {
@ -186,6 +219,8 @@ lua_State* setup_lua_sandbox(const char* luacode) {
lua_setglobal(L, "print");
luaL_loadbuffer(L, luacode, strlen(luacode), "script");
lua_sethook(L, hook, LUA_MASKCOUNT, 1000);
return L;
}
@ -258,7 +293,6 @@ int main(int argc, char** argv)
});
svr.Put("/api/code.json", [](const httplib::Request &req, httplib::Response &res, const httplib::ContentReader &content_reader) {
cout << "put request" << endl;
if (req.is_multipart_form_data()) {
res.set_content("No multipart forms allowed", "text/plain");
return true;
@ -266,15 +300,16 @@ int main(int argc, char** argv)
content_reader([&](const char *raw_data, size_t data_length) {
std::string data(raw_data, data_length);
auto j = json::parse(data);
cout << j << endl;
LedSegment* selected = ledsegments.at(j["id"].get<unsigned int>());
if (selected->lua_thread.has_value()) {
// TODO kill lua thread
selected->interpreter_config->enabled = false;
selected->lua_thread.value().join();
}
selected->owner = j["owner"].get<std::string>();
selected->lua_code = j["code"].get<std::string>();
selected->interpreter_config->enabled = true;
selected->lua_thread = spawn_lua_tread(selected->lua_code.c_str(), selected->interpreter_config);
cout << "Uploaded new code from " << selected->owner << " to segment " << j["id"].get<unsigned int>() << endl;
return true;
});
}

View File

@ -13,7 +13,6 @@ for i in range(10):
c = codefile.read()
except:
continue
time.sleep(0.3)
j = {
"code": c,
"owner": "j",