diff options
| author | jacqueline <me@jacqueline.id.au> | 2024-01-17 11:48:40 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2024-01-17 11:48:40 +1100 |
| commit | 71b46730394979ea528d152dbe884cc35c368759 (patch) | |
| tree | 516b3af32f8822a5f900ea10fd6ffba2e3de1ebb /src/lua/property.cpp | |
| parent | 7cdcd44e0ca10ebdc796638190ed1d9b45d99ef0 (diff) | |
| download | tangara-fw-71b46730394979ea528d152dbe884cc35c368759.tar.gz | |
all screens basically working, but bluetooth is rough
Diffstat (limited to 'src/lua/property.cpp')
| -rw-r--r-- | src/lua/property.cpp | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/src/lua/property.cpp b/src/lua/property.cpp index 89351579..2d702447 100644 --- a/src/lua/property.cpp +++ b/src/lua/property.cpp @@ -10,7 +10,9 @@ #include <cmath> #include <memory> #include <string> +#include <variant> +#include "bluetooth_types.hpp" #include "lua.h" #include "lua.hpp" #include "lua_thread.hpp" @@ -185,6 +187,35 @@ static auto pushTagValue(lua_State* L, const database::TagValue& val) -> void { val); } +static void pushDevice(lua_State* L, const drivers::bluetooth::Device& dev) { + lua_createtable(L, 0, 4); + + lua_pushliteral(L, "address"); + auto* mac = reinterpret_cast<drivers::bluetooth::mac_addr_t*>( + lua_newuserdata(L, sizeof(drivers::bluetooth::mac_addr_t))); + *mac = dev.address; + lua_rawset(L, -3); + + // What I just did there was perfectly safe. Look, I can prove it: + static_assert( + std::is_trivially_copy_assignable<drivers::bluetooth::mac_addr_t>()); + static_assert( + std::is_trivially_destructible<drivers::bluetooth::mac_addr_t>()); + + lua_pushliteral(L, "name"); + lua_pushlstring(L, dev.name.data(), dev.name.size()); + lua_rawset(L, -3); + + // FIXME: This field deserves a little more structure. + lua_pushliteral(L, "class"); + lua_pushinteger(L, dev.class_of_device); + lua_rawset(L, -3); + + lua_pushliteral(L, "signal_strength"); + lua_pushinteger(L, dev.signal_strength); + lua_rawset(L, -3); +} + auto Property::PushValue(lua_State& s) -> int { std::visit( [&](auto&& arg) { @@ -222,6 +253,16 @@ auto Property::PushValue(lua_State& s) -> int { lua_pushliteral(&s, "encoding"); lua_pushstring(&s, codecs::StreamTypeToString(arg.encoding).c_str()); lua_settable(&s, table); + } else if constexpr (std::is_same_v<T, drivers::bluetooth::Device>) { + pushDevice(&s, arg); + } else if constexpr (std::is_same_v< + T, std::vector<drivers::bluetooth::Device>>) { + lua_createtable(&s, arg.size(), 0); + size_t i = 1; + for (const auto& dev : arg) { + pushDevice(&s, dev); + lua_rawseti(&s, -2, i++); + } } else { static_assert(always_false_v<T>, "PushValue missing type"); } @@ -230,6 +271,34 @@ auto Property::PushValue(lua_State& s) -> int { return 1; } +auto popRichType(lua_State* L) -> LuaValue { + lua_pushliteral(L, "address"); + lua_gettable(L, -2); + + if (lua_isuserdata(L, -1)) { + // This must be a bt device! + drivers::bluetooth::mac_addr_t mac = + *reinterpret_cast<drivers::bluetooth::mac_addr_t*>( + lua_touserdata(L, -1)); + lua_pop(L, 1); + + lua_pushliteral(L, "name"); + lua_gettable(L, -2); + + std::pmr::string name = lua_tostring(L, -1); + lua_pop(L, 1); + + return drivers::bluetooth::Device{ + .address = mac, + .name = name, + .class_of_device = 0, + .signal_strength = 0, + }; + } + + return std::monostate{}; +} + auto Property::PopValue(lua_State& s) -> bool { LuaValue new_val; switch (lua_type(&s, 2)) { @@ -250,7 +319,14 @@ auto Property::PopValue(lua_State& s) -> bool { new_val = lua_tostring(&s, 2); break; default: - return false; + if (lua_istable(&s, 2)) { + new_val = popRichType(&s); + if (std::holds_alternative<std::monostate>(new_val)) { + return false; + } + } else { + return false; + } } if (cb_ && std::invoke(*cb_, new_val)) { |
