summaryrefslogtreecommitdiff
path: root/src/ui/screen_lua.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-04-18 10:06:45 +1000
committerjacqueline <me@jacqueline.id.au>2024-04-18 10:06:45 +1000
commitcc255f6d779b0478ae3eb795c2cae5ec864d8ef0 (patch)
tree036218815269099cc3c5cada4a8812e22b70e7c2 /src/ui/screen_lua.cpp
parent874218e3ff0ffd244936b3d56f1645efc3f9519f (diff)
downloadtangara-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.cpp66
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