Enable interrupting pure Lua loops
This commit is contained in:
parent
ec7290984e
commit
f5501273e2
6 changed files with 46 additions and 9 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
.build/
|
.build/
|
||||||
|
build/
|
||||||
editor/.idea/
|
editor/.idea/
|
||||||
editor/.cache
|
editor/.cache
|
||||||
editor/dist
|
editor/dist
|
||||||
|
|
|
@ -5,7 +5,6 @@ function all_leds(red, green, blue)
|
||||||
end
|
end
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
print(ledamount())
|
|
||||||
all_leds(255, 128, 0)
|
all_leds(255, 128, 0)
|
||||||
delay(1000)
|
delay(1000)
|
||||||
all_leds(0, 128, 255)
|
all_leds(0, 128, 255)
|
||||||
|
|
2
demo/2.lua
Normal file
2
demo/2.lua
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
print("script begin")
|
||||||
|
while true do end
|
|
@ -1,3 +1,4 @@
|
||||||
#!/bin/bash
|
#!/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"
|
|
@ -17,6 +17,9 @@
|
||||||
#include "httplib.h"
|
#include "httplib.h"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
using std::chrono::duration_cast;
|
||||||
|
using std::chrono::milliseconds;
|
||||||
|
using std::chrono::system_clock;
|
||||||
|
|
||||||
|
|
||||||
#define TARGET_FREQ WS2811_TARGET_FREQ
|
#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" {
|
extern "C" {
|
||||||
static int c_override_print (lua_State *L) {
|
static int c_override_print (lua_State *L) {
|
||||||
|
kill_thread_if_desired(L);
|
||||||
int n = lua_gettop(L); /* number of arguments */
|
int n = lua_gettop(L); /* number of arguments */
|
||||||
int i;
|
int i;
|
||||||
for (i = 1; i <= n; i++) { /* for each argument */
|
for (i = 1; i <= n; i++) { /* for each argument */
|
||||||
|
@ -80,6 +102,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int c_led (lua_State *L) {
|
static int c_led (lua_State *L) {
|
||||||
|
kill_thread_if_desired(L);
|
||||||
int virtual_location = luaL_checkinteger(L, 1);
|
int virtual_location = luaL_checkinteger(L, 1);
|
||||||
int red = luaL_checkinteger(L, 2);
|
int red = luaL_checkinteger(L, 2);
|
||||||
int green = luaL_checkinteger(L, 3);
|
int green = luaL_checkinteger(L, 3);
|
||||||
|
@ -115,17 +138,27 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int c_ledamount(lua_State *L) {
|
static int c_ledamount(lua_State *L) {
|
||||||
|
kill_thread_if_desired(L);
|
||||||
lua_pushinteger(L, statemap[L]->length);
|
lua_pushinteger(L, statemap[L]->length);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int c_delay(lua_State *L) {
|
static int c_delay(lua_State *L) {
|
||||||
int millis = luaL_checkinteger (L, 1);
|
if (kill_thread_if_desired(L)) {return 0;}
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(millis));
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int c_waitframes(lua_State *L) {
|
static int c_waitframes(lua_State *L) {
|
||||||
|
kill_thread_if_desired(L);
|
||||||
int amount = luaL_checkinteger(L, 1);
|
int amount = luaL_checkinteger(L, 1);
|
||||||
uint64_t destination = amount + framecounter;
|
uint64_t destination = amount + framecounter;
|
||||||
if (amount >= 2 * FPS) {
|
if (amount >= 2 * FPS) {
|
||||||
|
@ -186,6 +219,8 @@ lua_State* setup_lua_sandbox(const char* luacode) {
|
||||||
lua_setglobal(L, "print");
|
lua_setglobal(L, "print");
|
||||||
|
|
||||||
luaL_loadbuffer(L, luacode, strlen(luacode), "script");
|
luaL_loadbuffer(L, luacode, strlen(luacode), "script");
|
||||||
|
lua_sethook(L, hook, LUA_MASKCOUNT, 1000);
|
||||||
|
|
||||||
return L;
|
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) {
|
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()) {
|
if (req.is_multipart_form_data()) {
|
||||||
res.set_content("No multipart forms allowed", "text/plain");
|
res.set_content("No multipart forms allowed", "text/plain");
|
||||||
return true;
|
return true;
|
||||||
|
@ -266,15 +300,16 @@ int main(int argc, char** argv)
|
||||||
content_reader([&](const char *raw_data, size_t data_length) {
|
content_reader([&](const char *raw_data, size_t data_length) {
|
||||||
std::string data(raw_data, data_length);
|
std::string data(raw_data, data_length);
|
||||||
auto j = json::parse(data);
|
auto j = json::parse(data);
|
||||||
cout << j << endl;
|
|
||||||
LedSegment* selected = ledsegments.at(j["id"].get<unsigned int>());
|
LedSegment* selected = ledsegments.at(j["id"].get<unsigned int>());
|
||||||
if (selected->lua_thread.has_value()) {
|
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->owner = j["owner"].get<std::string>();
|
||||||
selected->lua_code = j["code"].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);
|
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;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ for i in range(10):
|
||||||
c = codefile.read()
|
c = codefile.read()
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
time.sleep(0.3)
|
|
||||||
j = {
|
j = {
|
||||||
"code": c,
|
"code": c,
|
||||||
"owner": "j",
|
"owner": "j",
|
||||||
|
|
Loading…
Reference in a new issue