From ef72b25660912ff247997089abfb93e9f0b52809 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 7 Mar 2024 10:59:03 +1100 Subject: use prototype inheritance for lua screens, rather than functions this gives us a way to give each screen nice little hooks, like 'onShown' and 'onHidden'. later we can use these hooks to disable bindings for screens that aren't in-use. --- src/lua/CMakeLists.txt | 1 + src/lua/bridge.cpp | 2 ++ src/lua/include/lua_screen.hpp | 15 +++++++++ src/lua/lua_screen.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 src/lua/include/lua_screen.hpp create mode 100644 src/lua/lua_screen.cpp (limited to 'src/lua') diff --git a/src/lua/CMakeLists.txt b/src/lua/CMakeLists.txt index ff0831c9..cee738bd 100644 --- a/src/lua/CMakeLists.txt +++ b/src/lua/CMakeLists.txt @@ -5,6 +5,7 @@ idf_component_register( SRCS "lua_thread.cpp" "bridge.cpp" "property.cpp" "lua_database.cpp" "lua_queue.cpp" "lua_version.cpp" "lua_controls.cpp" "registry.cpp" + "lua_screen.cpp" INCLUDE_DIRS "include" REQUIRES "drivers" "lvgl" "tinyfsm" "events" "system_fsm" "database" "esp_timer" "battery" "esp-idf-lua" "luavgl" "lua-linenoise" "lua-term" diff --git a/src/lua/bridge.cpp b/src/lua/bridge.cpp index a26f74bb..2bef1c30 100644 --- a/src/lua/bridge.cpp +++ b/src/lua/bridge.cpp @@ -19,6 +19,7 @@ #include "lua_controls.hpp" #include "lua_database.hpp" #include "lua_queue.hpp" +#include "lua_screen.hpp" #include "lua_version.hpp" #include "lvgl.h" @@ -84,6 +85,7 @@ auto Bridge::installBaseModules(lua_State* L) -> void { RegisterDatabaseModule(L); RegisterQueueModule(L); RegisterVersionModule(L); + RegisterScreenModule(L); } auto Bridge::installLvgl(lua_State* L) -> void { diff --git a/src/lua/include/lua_screen.hpp b/src/lua/include/lua_screen.hpp new file mode 100644 index 00000000..1c3bed1a --- /dev/null +++ b/src/lua/include/lua_screen.hpp @@ -0,0 +1,15 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include "lua.hpp" + +namespace lua { + +auto RegisterScreenModule(lua_State*) -> void; + +} // namespace lua diff --git a/src/lua/lua_screen.cpp b/src/lua/lua_screen.cpp new file mode 100644 index 00000000..27843bc7 --- /dev/null +++ b/src/lua/lua_screen.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "lua_screen.hpp" + +#include +#include + +#include "lua.hpp" + +#include "esp_log.h" +#include "lauxlib.h" +#include "lua.h" +#include "lvgl.h" + +#include "bridge.hpp" +#include "database.hpp" +#include "event_queue.hpp" +#include "index.hpp" +#include "property.hpp" +#include "service_locator.hpp" +#include "track.hpp" +#include "track_queue.hpp" +#include "ui_events.hpp" + +namespace lua { + +static auto screen_new(lua_State* L) -> int { + // o = o or {} + if (lua_gettop(L) != 2) { + lua_settop(L, 1); + lua_newtable(L); + } + // Swap o and self on the stack. + lua_insert(L, 1); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, 1); + lua_settable(L, 1); // self.__index = self + + lua_setmetatable(L, 1); // setmetatable(o, self) + + return 1; // return o +} + +static auto screen_noop(lua_State* state) -> int { + return 0; +} + +static const struct luaL_Reg kScreenFuncs[] = {{"new", screen_new}, + {"createUi", screen_noop}, + {"onShown", screen_noop}, + {"onHidden", screen_noop}, + {NULL, NULL}}; + +static auto lua_screen(lua_State* state) -> int { + luaL_newlib(state, kScreenFuncs); + + lua_pushliteral(state, "__index"); + lua_pushvalue(state, -2); + lua_rawset(state, -3); + + return 1; +} + +auto RegisterScreenModule(lua_State* s) -> void { + luaL_requiref(s, "screen", lua_screen, true); + + lua_pop(s, 1); +} + +} // namespace lua -- cgit v1.2.3 From a78614a5806c9800956f10f993e1c70b74fbf323 Mon Sep 17 00:00:00 2001 From: ailurux Date: Thu, 7 Mar 2024 12:12:32 +1100 Subject: WIP: Getting styles from lua --- src/lua/CMakeLists.txt | 4 +- src/lua/bridge.cpp | 2 + src/lua/include/lua_theme.hpp | 15 ++++++++ src/lua/lua_theme.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 src/lua/include/lua_theme.hpp create mode 100644 src/lua/lua_theme.cpp (limited to 'src/lua') diff --git a/src/lua/CMakeLists.txt b/src/lua/CMakeLists.txt index ff0831c9..72e48aa0 100644 --- a/src/lua/CMakeLists.txt +++ b/src/lua/CMakeLists.txt @@ -3,8 +3,8 @@ # SPDX-License-Identifier: GPL-3.0-only idf_component_register( - SRCS "lua_thread.cpp" "bridge.cpp" "property.cpp" "lua_database.cpp" - "lua_queue.cpp" "lua_version.cpp" "lua_controls.cpp" "registry.cpp" + SRCS "lua_theme.cpp" "lua_thread.cpp" "bridge.cpp" "property.cpp" "lua_database.cpp" + "lua_queue.cpp" "lua_version.cpp" "lua_theme.cpp" "lua_controls.cpp" "registry.cpp" INCLUDE_DIRS "include" REQUIRES "drivers" "lvgl" "tinyfsm" "events" "system_fsm" "database" "esp_timer" "battery" "esp-idf-lua" "luavgl" "lua-linenoise" "lua-term" diff --git a/src/lua/bridge.cpp b/src/lua/bridge.cpp index a26f74bb..44be06f8 100644 --- a/src/lua/bridge.cpp +++ b/src/lua/bridge.cpp @@ -20,6 +20,7 @@ #include "lua_database.hpp" #include "lua_queue.hpp" #include "lua_version.hpp" +#include "lua_theme.hpp" #include "lvgl.h" #include "font/lv_font_loader.h" @@ -84,6 +85,7 @@ auto Bridge::installBaseModules(lua_State* L) -> void { RegisterDatabaseModule(L); RegisterQueueModule(L); RegisterVersionModule(L); + RegisterThemeModule(L); } auto Bridge::installLvgl(lua_State* L) -> void { diff --git a/src/lua/include/lua_theme.hpp b/src/lua/include/lua_theme.hpp new file mode 100644 index 00000000..fed710e0 --- /dev/null +++ b/src/lua/include/lua_theme.hpp @@ -0,0 +1,15 @@ +/* + * Copyright 2024 ailurux + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include "lua.hpp" + +namespace lua { + +auto RegisterThemeModule(lua_State*) -> void; + +} // namespace lua diff --git a/src/lua/lua_theme.cpp b/src/lua/lua_theme.cpp new file mode 100644 index 00000000..a95e634b --- /dev/null +++ b/src/lua/lua_theme.cpp @@ -0,0 +1,89 @@ + +/* + * Copyright 2023 ailurux + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "lua_version.hpp" + +#include + +#include "bridge.hpp" +#include "lua.hpp" + +#include "esp_app_desc.h" +#include "esp_log.h" +#include "lauxlib.h" +#include "lua.h" +#include "lua_thread.hpp" +#include "luavgl.h" +#include "themes.hpp" + +namespace lua { + +static auto set_theme(lua_State* L) -> int { + // lv_style_t* style = luavgl_to_style(L, -1); + // if (style == NULL) { + // ESP_LOGI("DANIEL", "Style was null or malformed??"); + // return 0; + // } + + // ESP_LOGI("DANIEL", "GOT ONE!"); + // themes::Theme::instance()->...; + + /* table is in the stack at index 't' */ + std::string class_name; + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + /* uses 'key' (at index -2) and 'value' (at index -1) */ + if (lua_type(L, -2) == LUA_TSTRING) { + class_name = lua_tostring(L, -2); + } + if (lua_type(L, -1) == LUA_TTABLE) { + // Nesting + lua_pushnil(L); // First key + while (lua_next(L, -2) != 0) { + // Nesting the second + int selector = -1; + lv_style_t* style = NULL; + lua_pushnil(L); // First key + while (lua_next(L, -2) != 0) { + int idx = lua_tointeger(L, -2); + if (idx == 1) { + // Selector + selector = lua_tointeger(L, -1); + } else if (idx == 2) { + // Style + lv_style_t* style = luavgl_to_style(L, -1); + if (style == NULL) { + ESP_LOGI("DANIEL", "Style was null or malformed??"); + return 0; + } else { + ESP_LOGI("DANIEL", "Got style for class %s with selector %d", class_name.c_str(), selector); + } + } + lua_pop(L, 1); + } + lua_pop(L, 1); + } + } + /* removes 'value'; keeps 'key' for next iteration */ + lua_pop(L, 1); + } + return 0; +} + +static const struct luaL_Reg kThemeFuncs[] = {{"set", set_theme}, {NULL, NULL}}; + +static auto lua_theme(lua_State* L) -> int { + luaL_newlib(L, kThemeFuncs); + return 1; +} + +auto RegisterThemeModule(lua_State* L) -> void { + luaL_requiref(L, "theme", lua_theme, true); + lua_pop(L, 1); +} + +} // namespace lua -- cgit v1.2.3 From 312b70f9f6a2e3d7d387dfe3502f12f091e8fe37 Mon Sep 17 00:00:00 2001 From: ailurux Date: Thu, 7 Mar 2024 14:20:06 +1100 Subject: WIP: Base styles are applied --- src/lua/lua_theme.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/lua') diff --git a/src/lua/lua_theme.cpp b/src/lua/lua_theme.cpp index a95e634b..7b007f4d 100644 --- a/src/lua/lua_theme.cpp +++ b/src/lua/lua_theme.cpp @@ -60,6 +60,7 @@ static auto set_theme(lua_State* L) -> int { ESP_LOGI("DANIEL", "Style was null or malformed??"); return 0; } else { + ui::themes::Theme::instance()->AddStyle(class_name, selector, style); ESP_LOGI("DANIEL", "Got style for class %s with selector %d", class_name.c_str(), selector); } } -- cgit v1.2.3 From 1133d4621508b7ec6bac4ab8731f3493066ceeee Mon Sep 17 00:00:00 2001 From: ailurux Date: Sun, 10 Mar 2024 13:20:17 +1100 Subject: WIP Lua Theming- style classes --- src/lua/lua_theme.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'src/lua') diff --git a/src/lua/lua_theme.cpp b/src/lua/lua_theme.cpp index 7b007f4d..2fcd71e5 100644 --- a/src/lua/lua_theme.cpp +++ b/src/lua/lua_theme.cpp @@ -22,17 +22,19 @@ namespace lua { -static auto set_theme(lua_State* L) -> int { - // lv_style_t* style = luavgl_to_style(L, -1); - // if (style == NULL) { - // ESP_LOGI("DANIEL", "Style was null or malformed??"); - // return 0; - // } - - // ESP_LOGI("DANIEL", "GOT ONE!"); - // themes::Theme::instance()->...; +static auto set_style(lua_State* L) -> int { + // Get the object and class name from the stack + if (lua_type(L, -1) == LUA_TSTRING) { + std::string class_name = lua_tostring(L, -1); + lv_obj_t* obj = luavgl_to_obj(L, -2); + if (obj != NULL) { + ui::themes::Theme::instance()->ApplyStyle(obj, class_name); + } + } + return 0; +} - /* table is in the stack at index 't' */ +static auto set_theme(lua_State* L) -> int { std::string class_name; lua_pushnil(L); /* first key */ while (lua_next(L, -2) != 0) { @@ -61,7 +63,6 @@ static auto set_theme(lua_State* L) -> int { return 0; } else { ui::themes::Theme::instance()->AddStyle(class_name, selector, style); - ESP_LOGI("DANIEL", "Got style for class %s with selector %d", class_name.c_str(), selector); } } lua_pop(L, 1); @@ -75,7 +76,7 @@ static auto set_theme(lua_State* L) -> int { return 0; } -static const struct luaL_Reg kThemeFuncs[] = {{"set", set_theme}, {NULL, NULL}}; +static const struct luaL_Reg kThemeFuncs[] = {{"set", set_theme}, {"set_style", set_style}, {NULL, NULL}}; static auto lua_theme(lua_State* L) -> int { luaL_newlib(L, kThemeFuncs); -- cgit v1.2.3 From 684ff50ef4931aeb8cfb15c5a2d62e55520f04a5 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 21 Mar 2024 10:50:23 +1100 Subject: Add support for screens declaring that they can't be popped Needed as prep for usb msc support; you really shouldn't leave the MSC settings screen until you've disabled usb msc. --- src/lua/lua_screen.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/lua') diff --git a/src/lua/lua_screen.cpp b/src/lua/lua_screen.cpp index 27843bc7..f17f6b1a 100644 --- a/src/lua/lua_screen.cpp +++ b/src/lua/lua_screen.cpp @@ -50,11 +50,15 @@ static auto screen_noop(lua_State* state) -> int { return 0; } -static const struct luaL_Reg kScreenFuncs[] = {{"new", screen_new}, - {"createUi", screen_noop}, - {"onShown", screen_noop}, - {"onHidden", screen_noop}, - {NULL, NULL}}; +static auto screen_true(lua_State* state) -> int { + lua_pushboolean(state, true); + return 1; +} + +static const struct luaL_Reg kScreenFuncs[] = { + {"new", screen_new}, {"createUi", screen_noop}, + {"onShown", screen_noop}, {"onHidden", screen_noop}, + {"canPop", screen_true}, {NULL, NULL}}; static auto lua_screen(lua_State* state) -> int { luaL_newlib(state, kScreenFuncs); -- cgit v1.2.3 From 175bfc4e3e9f7aa39e084d3f1625347f1d5711ec Mon Sep 17 00:00:00 2001 From: jacqueline Date: Mon, 25 Mar 2024 17:34:41 +1100 Subject: WIP rewrie audio pipeline+fsm guts for more reliability --- src/lua/include/property.hpp | 2 +- src/lua/property.cpp | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) (limited to 'src/lua') diff --git a/src/lua/include/property.hpp b/src/lua/include/property.hpp index 7d160fba..f19fdeec 100644 --- a/src/lua/include/property.hpp +++ b/src/lua/include/property.hpp @@ -23,7 +23,7 @@ using LuaValue = std::variant>; diff --git a/src/lua/property.cpp b/src/lua/property.cpp index f721f9ce..200f4d5c 100644 --- a/src/lua/property.cpp +++ b/src/lua/property.cpp @@ -221,7 +221,7 @@ static auto pushTagValue(lua_State* L, const database::TagValue& val) -> void { val); } -static void pushTrack(lua_State* L, const audio::Track& track) { +static void pushTrack(lua_State* L, const audio::TrackInfo& track) { lua_newtable(L); for (const auto& tag : track.tags->allPresent()) { @@ -229,19 +229,18 @@ static void pushTrack(lua_State* L, const audio::Track& track) { pushTagValue(L, track.tags->get(tag)); lua_settable(L, -3); } - if (track.db_info) { - lua_pushliteral(L, "id"); - lua_pushinteger(L, track.db_info->id); + + if (track.duration) { + lua_pushliteral(L, "duration"); + lua_pushinteger(L, track.duration.value()); lua_settable(L, -3); } - lua_pushliteral(L, "duration"); - lua_pushinteger(L, track.duration); - lua_settable(L, -3); - - lua_pushliteral(L, "bitrate_kbps"); - lua_pushinteger(L, track.bitrate_kbps); - lua_settable(L, -3); + if (track.bitrate_kbps) { + lua_pushliteral(L, "bitrate_kbps"); + lua_pushinteger(L, track.bitrate_kbps.value()); + lua_settable(L, -3); + } lua_pushliteral(L, "encoding"); lua_pushstring(L, codecs::StreamTypeToString(track.encoding).c_str()); @@ -289,7 +288,7 @@ auto Property::PushValue(lua_State& s) -> int { lua_pushboolean(&s, arg); } else if constexpr (std::is_same_v) { lua_pushstring(&s, arg.c_str()); - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v) { pushTrack(&s, arg); } else if constexpr (std::is_same_v) { pushDevice(&s, arg); -- cgit v1.2.3 From bf58cb7acf402420158f3ac2530f62ddc3057914 Mon Sep 17 00:00:00 2001 From: ailurux Date: Wed, 27 Mar 2024 16:11:36 +1100 Subject: Minor fixes --- src/lua/lua_theme.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lua') diff --git a/src/lua/lua_theme.cpp b/src/lua/lua_theme.cpp index 2fcd71e5..32d6f660 100644 --- a/src/lua/lua_theme.cpp +++ b/src/lua/lua_theme.cpp @@ -59,7 +59,7 @@ static auto set_theme(lua_State* L) -> int { // Style lv_style_t* style = luavgl_to_style(L, -1); if (style == NULL) { - ESP_LOGI("DANIEL", "Style was null or malformed??"); + ESP_LOGI(kTag, "Style was null or malformed"); return 0; } else { ui::themes::Theme::instance()->AddStyle(class_name, selector, style); -- cgit v1.2.3 From 78c708e9390047ef24ccd8fbe0cd2d38ff758654 Mon Sep 17 00:00:00 2001 From: ailurux Date: Thu, 28 Mar 2024 15:36:27 +1100 Subject: Fix log message --- src/lua/lua_theme.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lua') diff --git a/src/lua/lua_theme.cpp b/src/lua/lua_theme.cpp index 32d6f660..fe69aa6a 100644 --- a/src/lua/lua_theme.cpp +++ b/src/lua/lua_theme.cpp @@ -59,7 +59,7 @@ static auto set_theme(lua_State* L) -> int { // Style lv_style_t* style = luavgl_to_style(L, -1); if (style == NULL) { - ESP_LOGI(kTag, "Style was null or malformed"); + ESP_LOGI("lua_theme", "Style was null or malformed"); return 0; } else { ui::themes::Theme::instance()->AddStyle(class_name, selector, style); -- cgit v1.2.3 From f1c8866b815a92aeda3133fd27051ce7c873cc57 Mon Sep 17 00:00:00 2001 From: ailurux Date: Thu, 28 Mar 2024 16:03:37 +1100 Subject: Check type is actually a table --- src/lua/lua_theme.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/lua') diff --git a/src/lua/lua_theme.cpp b/src/lua/lua_theme.cpp index fe69aa6a..4eb46499 100644 --- a/src/lua/lua_theme.cpp +++ b/src/lua/lua_theme.cpp @@ -36,6 +36,7 @@ static auto set_style(lua_State* L) -> int { static auto set_theme(lua_State* L) -> int { std::string class_name; + luaL_checktype(L, -1, LUA_TTABLE); lua_pushnil(L); /* first key */ while (lua_next(L, -2) != 0) { /* uses 'key' (at index -2) and 'value' (at index -1) */ -- cgit v1.2.3 From 79b6c3b393a1ff351b437ef59b2a4e472da0c38c Mon Sep 17 00:00:00 2001 From: ailurux Date: Thu, 28 Mar 2024 16:29:23 +1100 Subject: Use luaL_checkstring in set_style --- src/lua/lua_theme.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/lua') diff --git a/src/lua/lua_theme.cpp b/src/lua/lua_theme.cpp index 4eb46499..d7f099cc 100644 --- a/src/lua/lua_theme.cpp +++ b/src/lua/lua_theme.cpp @@ -24,12 +24,10 @@ namespace lua { static auto set_style(lua_State* L) -> int { // Get the object and class name from the stack - if (lua_type(L, -1) == LUA_TSTRING) { - std::string class_name = lua_tostring(L, -1); - lv_obj_t* obj = luavgl_to_obj(L, -2); - if (obj != NULL) { - ui::themes::Theme::instance()->ApplyStyle(obj, class_name); - } + std::string class_name = luaL_checkstring(L, -1); + lv_obj_t* obj = luavgl_to_obj(L, -2); + if (obj != NULL) { + ui::themes::Theme::instance()->ApplyStyle(obj, class_name); } return 0; } -- cgit v1.2.3 From 7c5dae84175aa750ca1b8beeb066f5607ca73181 Mon Sep 17 00:00:00 2001 From: ailurux Date: Thu, 28 Mar 2024 16:34:04 +1100 Subject: Remove unused variable --- src/lua/lua_theme.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/lua') diff --git a/src/lua/lua_theme.cpp b/src/lua/lua_theme.cpp index d7f099cc..72434d97 100644 --- a/src/lua/lua_theme.cpp +++ b/src/lua/lua_theme.cpp @@ -47,7 +47,6 @@ static auto set_theme(lua_State* L) -> int { while (lua_next(L, -2) != 0) { // Nesting the second int selector = -1; - lv_style_t* style = NULL; lua_pushnil(L); // First key while (lua_next(L, -2) != 0) { int idx = lua_tointeger(L, -2); -- cgit v1.2.3