diff options
| author | jacqueline <me@jacqueline.id.au> | 2024-04-18 10:06:45 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2024-04-18 10:06:45 +1000 |
| commit | cc255f6d779b0478ae3eb795c2cae5ec864d8ef0 (patch) | |
| tree | 036218815269099cc3c5cada4a8812e22b70e7c2 /src/ui/screen_lua.cpp | |
| parent | 874218e3ff0ffd244936b3d56f1645efc3f9519f (diff) | |
| download | tangara-fw-cc255f6d779b0478ae3eb795c2cae5ec864d8ef0.tar.gz | |
Suspend property bindings when their screens aren't visible
Diffstat (limited to 'src/ui/screen_lua.cpp')
| -rw-r--r-- | src/ui/screen_lua.cpp | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/src/ui/screen_lua.cpp b/src/ui/screen_lua.cpp index d43c7ee7..685e43cb 100644 --- a/src/ui/screen_lua.cpp +++ b/src/ui/screen_lua.cpp @@ -9,6 +9,7 @@ #include "core/lv_obj_tree.h" #include "lua.h" #include "lua.hpp" +#include "property.hpp" #include "themes.hpp" #include "lua_thread.hpp" @@ -28,28 +29,46 @@ Lua::~Lua() { } auto Lua::onShown() -> void { + callMethod("onShown"); + forEachBinding([&](lua::Binding* b) { b->active = true; }); +} + +auto Lua::onHidden() -> void { + callMethod("onHidden"); + forEachBinding([&](lua::Binding* b) { b->active = false; }); +} + +auto Lua::canPop() -> bool { if (!s_ || !obj_ref_) { - return; + return true; } lua_rawgeti(s_, LUA_REGISTRYINDEX, *obj_ref_); - lua_pushliteral(s_, "onShown"); + lua_pushliteral(s_, "canPop"); if (lua_gettable(s_, -2) == LUA_TFUNCTION) { + // If we got a callback instead of a value, then invoke it to turn it into + // value. lua_pushvalue(s_, -2); - lua::CallProtected(s_, 1, 0); - } else { - lua_pop(s_, 1); + lua::CallProtected(s_, 1, 1); } + bool ret = lua_toboolean(s_, -1); - lua_pop(s_, 1); + lua_pop(s_, 2); + return ret; } -auto Lua::onHidden() -> void { +auto Lua::SetObjRef(lua_State* s) -> void { + assert(s_ == nullptr); + s_ = s; + obj_ref_ = luaL_ref(s, LUA_REGISTRYINDEX); +} + +auto Lua::callMethod(std::string name) -> void { if (!s_ || !obj_ref_) { return; } lua_rawgeti(s_, LUA_REGISTRYINDEX, *obj_ref_); - lua_pushliteral(s_, "onHidden"); + lua_pushlstring(s_, name.data(), name.size()); if (lua_gettable(s_, -2) == LUA_TFUNCTION) { lua_pushvalue(s_, -2); @@ -61,29 +80,28 @@ auto Lua::onHidden() -> void { lua_pop(s_, 1); } -auto Lua::canPop() -> bool { +auto Lua::forEachBinding(std::function<void(lua::Binding*)> fn) -> void { if (!s_ || !obj_ref_) { - return true; + return; } lua_rawgeti(s_, LUA_REGISTRYINDEX, *obj_ref_); - lua_pushliteral(s_, "canPop"); + lua_pushliteral(s_, "bindings"); - if (lua_gettable(s_, -2) == LUA_TFUNCTION) { - // If we got a callback instead of a value, then invoke it to turn it into - // value. - lua_pushvalue(s_, -2); - lua::CallProtected(s_, 1, 1); + if (lua_gettable(s_, -2) != LUA_TTABLE) { + lua_pop(s_, 2); + return; } - bool ret = lua_toboolean(s_, -1); - lua_pop(s_, 2); - return ret; -} + lua_pushnil(s_); + while (lua_next(s_, -2) != 0) { + lua::Binding* b = lua::Binding::get(s_, -1); + if (b) { + std::invoke(fn, b); + } + lua_pop(s_, 1); + } -auto Lua::SetObjRef(lua_State* s) -> void { - assert(s_ == nullptr); - s_ = s; - obj_ref_ = luaL_ref(s, LUA_REGISTRYINDEX); + lua_pop(s_, 2); } } // namespace screens |
