fix(color): add error handling for Lua LVGL object creation (#7215)
This commit is contained in:
@@ -205,7 +205,7 @@ void Widget::onCancel()
|
||||
|
||||
void Widget::setFullscreen(bool enable)
|
||||
{
|
||||
if (!!parent->isTopBar() || (enable == fullscreen)) return;
|
||||
if (parent->isTopBar() || (enable == fullscreen)) return;
|
||||
|
||||
fullscreen = enable;
|
||||
|
||||
|
||||
@@ -38,12 +38,17 @@ class LvglWidgetParams
|
||||
if (!strcmp(key, "type")) {
|
||||
if (lua_isinteger(L, -1)) {
|
||||
int n = lua_tointeger(L, -1);
|
||||
if (n > ETX_UNDEF && n < ETX_LAST)
|
||||
if (n > ETX_UNDEF && n < ETX_LAST) {
|
||||
type = (LuaLvglType)n;
|
||||
else
|
||||
} else {
|
||||
luaL_error(L, "Invalid type '%d'", n);
|
||||
type = ETX_UNDEF;
|
||||
}
|
||||
} else {
|
||||
type = getType(luaL_checkstring(L, -1));
|
||||
const char* s = luaL_checkstring(L, -1);
|
||||
type = getType(s);
|
||||
if (type == ETX_UNDEF)
|
||||
luaL_error(L, "Invalid type '%s'", s);
|
||||
}
|
||||
} else if (!strcmp(key, "name")) {
|
||||
name = luaL_checkstring(L, -1);
|
||||
@@ -184,6 +189,8 @@ static void buildLvgl(lua_State *L, int srcIndex, int refIndex)
|
||||
for (lua_pushnil(L); lua_next(L, srcIndex - 1); lua_pop(L, 1)) {
|
||||
auto t = lua_gettop(L);
|
||||
LvglWidgetParams p(L, -1);
|
||||
if (p.type == ETX_UNDEF)
|
||||
luaL_error(L, "Missing or bad type");
|
||||
if (p.type >= ETX_FIRST_CONTROL && !luaScriptManager->isFullscreen())
|
||||
continue;
|
||||
LvglWidgetObjectBase *obj = nullptr;
|
||||
|
||||
+16
-22
@@ -55,8 +55,6 @@ extern "C" {
|
||||
// #include "touch.h"
|
||||
// #endif
|
||||
|
||||
// Since we may not run FG every time, keep the events in a buffer
|
||||
event_t events[EVENT_BUFFER_SIZE] = { 0 };
|
||||
// The main thread - lsScripts is now a coroutine
|
||||
lua_State * mainState = nullptr;
|
||||
lua_State *lsScripts = nullptr;
|
||||
@@ -327,14 +325,10 @@ void luaDoGc(lua_State * L, bool full)
|
||||
void luaFree(lua_State * L, ScriptInternalData & sid)
|
||||
{
|
||||
PROTECT_LUA() {
|
||||
if (sid.run) {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, sid.run);
|
||||
sid.run = 0;
|
||||
}
|
||||
if (sid.background) {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, sid.background);
|
||||
sid.background = 0;
|
||||
}
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, sid.run);
|
||||
sid.run = LUA_REFNIL;
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, sid.background);
|
||||
sid.background = LUA_REFNIL;
|
||||
}
|
||||
else {
|
||||
luaDisable();
|
||||
@@ -857,7 +851,7 @@ static int luaRegisterFunction(const char * key)
|
||||
TRACE_ERROR("luaRegisterFunction(%s): Error: '%.*s' is not a function\n", LEN_SCRIPT_FILENAME, getScriptName(luaScriptsCount - 1), key);
|
||||
}
|
||||
lua_pop(lsScripts, 1);
|
||||
return LUA_NOREF;
|
||||
return LUA_REFNIL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -877,7 +871,7 @@ static void luaLoadScripts(bool init, const char * filename = nullptr)
|
||||
if (luaState == INTERPRETER_PANIC) return;
|
||||
|
||||
luaLcdAllowed = false;
|
||||
initFunction = LUA_NOREF;
|
||||
initFunction = LUA_REFNIL;
|
||||
luaEmptyEventBuffer();
|
||||
|
||||
// Initialize loop over references
|
||||
@@ -949,11 +943,11 @@ static void luaLoadScripts(bool init, const char * filename = nullptr)
|
||||
}
|
||||
else if (luaStatus == LUA_OK) {
|
||||
// Coroutine returned
|
||||
if (initFunction != LUA_NOREF) {
|
||||
if (initFunction != LUA_REFNIL) {
|
||||
// init() returned - clean up
|
||||
luaL_unref(lsScripts, LUA_REGISTRYINDEX, initFunction);
|
||||
lua_settop(lsScripts, 0);
|
||||
initFunction = LUA_NOREF;
|
||||
initFunction = LUA_REFNIL;
|
||||
}
|
||||
else {
|
||||
// chunk() returned
|
||||
@@ -964,10 +958,10 @@ static void luaLoadScripts(bool init, const char * filename = nullptr)
|
||||
sid.run = luaRegisterFunction("run");
|
||||
sid.background = luaRegisterFunction("background");
|
||||
initFunction = luaRegisterFunction("init");
|
||||
if (sid.run == LUA_NOREF) {
|
||||
if (sid.run == LUA_REFNIL) {
|
||||
snprintf(lua_warning_info, LUA_WARNING_INFO_LEN, "luaLoadScripts(%.*s): No run function\n", LEN_SCRIPT_FILENAME, getScriptName(idx));
|
||||
sid.state = SCRIPT_SYNTAX_ERROR;
|
||||
initFunction = LUA_NOREF;
|
||||
initFunction = LUA_REFNIL;
|
||||
}
|
||||
#if defined(LUA_MODEL_SCRIPTS)
|
||||
// Get input/output tables for mixer scripts
|
||||
@@ -985,14 +979,14 @@ static void luaLoadScripts(bool init, const char * filename = nullptr)
|
||||
else {
|
||||
snprintf(lua_warning_info, LUA_WARNING_INFO_LEN, "luaLoadScripts(%.*s): The script did not return a table\n", LEN_SCRIPT_FILENAME, getScriptName(idx));
|
||||
sid.state = SCRIPT_SYNTAX_ERROR;
|
||||
initFunction = LUA_NOREF;
|
||||
initFunction = LUA_REFNIL;
|
||||
}
|
||||
|
||||
// Pop the table off the stack
|
||||
lua_pop(lsScripts, 1);
|
||||
|
||||
// If init(), push it on the stack
|
||||
if (initFunction != LUA_NOREF) {
|
||||
if (initFunction != LUA_REFNIL) {
|
||||
lua_rawgeti(lsScripts, LUA_REGISTRYINDEX, initFunction);
|
||||
#if !defined(COLORLCD)
|
||||
if (ref == SCRIPT_STANDALONE) {
|
||||
@@ -1005,9 +999,9 @@ static void luaLoadScripts(bool init, const char * filename = nullptr)
|
||||
else {
|
||||
// Error
|
||||
sid.state = SCRIPT_SYNTAX_ERROR;
|
||||
initFunction = LUA_NOREF;
|
||||
initFunction = LUA_REFNIL;
|
||||
}
|
||||
} while(initFunction != LUA_NOREF);
|
||||
} while(initFunction != LUA_REFNIL);
|
||||
|
||||
if (sid.state != SCRIPT_OK) {
|
||||
luaError(lsScripts, sid.state);
|
||||
@@ -1149,14 +1143,14 @@ static bool resumeLua(bool init, bool allowLcdUsage)
|
||||
functionsContext->lastFunctionTime[idx] = tmr10ms;
|
||||
}
|
||||
else {
|
||||
if (sid.background == LUA_NOREF) continue;
|
||||
if (sid.background == LUA_REFNIL) continue;
|
||||
lua_rawgeti(lsScripts, LUA_REGISTRYINDEX, sid.background);
|
||||
}
|
||||
} else continue;
|
||||
}
|
||||
#if defined(PCBTARANIS)
|
||||
else if (ref <= SCRIPT_TELEMETRY_LAST) {
|
||||
if (sid.background == LUA_NOREF) continue;
|
||||
if (sid.background == LUA_REFNIL) continue;
|
||||
lua_rawgeti(lsScripts, LUA_REGISTRYINDEX, sid.background);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -339,7 +339,7 @@ LvglWidgetObjectBase *LvglWidgetObjectBase::checkLvgl(lua_State *L, int index, b
|
||||
if (p && *p) return *p;
|
||||
|
||||
if (required) {
|
||||
luaL_error(L, "Invalid lvgl object (it has been probably been cleared).");
|
||||
luaL_error(L, "Invalid object (it has been probably been cleared).");
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -656,6 +656,8 @@ void LvglWidgetObjectBase::parseParam(lua_State *L, const char *key)
|
||||
getPosFunction = ::getRef(L, LUA_REGISTRYINDEX);
|
||||
} else if (!strcmp(key, "floating")) {
|
||||
floating = getLuaBool(L);
|
||||
} else if (strcmp(key, "children") && strcmp(key, "type") && strcmp(key, "name")) {
|
||||
luaL_error(L, "Invalid property '%s'", key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -860,9 +862,12 @@ void LvglWidgetLabel::setAlign(LcdFlags newAlign)
|
||||
{
|
||||
if (lvobj) {
|
||||
align.flags = newAlign;
|
||||
if (align.flags & VCENTERED) {
|
||||
lv_obj_align(lvobj, LV_ALIGN_LEFT_MID, 0, 0);
|
||||
}
|
||||
if (align.flags & VCENTERED)
|
||||
lv_obj_set_style_align(lvobj, LV_ALIGN_LEFT_MID, LV_PART_MAIN);
|
||||
else if (align.flags & VTOP)
|
||||
lv_obj_set_style_align(lvobj, LV_ALIGN_TOP_LEFT, LV_PART_MAIN);
|
||||
else if (align.flags & VBOTTOM)
|
||||
lv_obj_set_style_align(lvobj, LV_ALIGN_BOTTOM_LEFT, LV_PART_MAIN);
|
||||
lv_obj_set_style_text_align(lvobj,
|
||||
(align.flags & RIGHT) ? LV_TEXT_ALIGN_RIGHT
|
||||
: (align.flags & CENTERED) ? LV_TEXT_ALIGN_CENTER
|
||||
|
||||
Reference in New Issue
Block a user