diff options
Diffstat (limited to 'src/lua')
| -rw-r--r-- | src/lua/bridge.cpp | 15 | ||||
| -rw-r--r-- | src/lua/lua_database.cpp | 144 | ||||
| -rw-r--r-- | src/lua/lua_queue.cpp | 12 |
3 files changed, 73 insertions, 98 deletions
diff --git a/src/lua/bridge.cpp b/src/lua/bridge.cpp index 070dee98..8d7b4fd0 100644 --- a/src/lua/bridge.cpp +++ b/src/lua/bridge.cpp @@ -37,23 +37,8 @@ static auto open_settings_fn(lua_State* state) -> int { return 0; } -static auto open_now_playing_fn(lua_State* state) -> int { - events::Ui().Dispatch(ui::internal::ShowNowPlaying{}); - return 0; -} - -static auto open_browse_fn(lua_State* state) -> int { - int index = luaL_checkinteger(state, 1); - events::Ui().Dispatch(ui::internal::IndexSelected{ - .id = static_cast<uint8_t>(index), - }); - return 0; -} - static const struct luaL_Reg kLegacyUiFuncs[] = { {"open_settings", open_settings_fn}, - {"open_now_playing", open_now_playing_fn}, - {"open_browse", open_browse_fn}, {NULL, NULL}}; static auto lua_legacy_ui(lua_State* state) -> int { diff --git a/src/lua/lua_database.cpp b/src/lua/lua_database.cpp index d41f4794..82b22343 100644 --- a/src/lua/lua_database.cpp +++ b/src/lua/lua_database.cpp @@ -8,7 +8,10 @@ #include <memory> #include <string> +#include <type_traits> +#include <variant> +#include "bridge.hpp" #include "lua.hpp" #include "esp_log.h" @@ -34,6 +37,17 @@ static constexpr char kDbIndexMetatable[] = "db_index"; static constexpr char kDbRecordMetatable[] = "db_record"; static constexpr char kDbIteratorMetatable[] = "db_iterator"; +struct LuaIndexInfo { + database::IndexId id; + size_t name_size; + char name_data[]; + + auto name() -> std::string_view { return {name_data, name_size}; } +}; + +static_assert(std::is_trivially_destructible<LuaIndexInfo>()); +static_assert(std::is_trivially_copy_assignable<LuaIndexInfo>()); + static auto indexes(lua_State* state) -> int { Bridge* instance = Bridge::Get(state); @@ -44,11 +58,15 @@ static auto indexes(lua_State* state) -> int { return 1; } - for (const auto& i : db->GetIndexes()) { - database::IndexInfo** data = reinterpret_cast<database::IndexInfo**>( - lua_newuserdata(state, sizeof(uintptr_t))); + for (const auto& i : db->getIndexes()) { + LuaIndexInfo* data = reinterpret_cast<LuaIndexInfo*>( + lua_newuserdata(state, sizeof(LuaIndexInfo) + i.name.size())); luaL_setmetatable(state, kDbIndexMetatable); - *data = new database::IndexInfo{i}; + *data = LuaIndexInfo{ + .id = i.id, + .name_size = i.name.size(), + }; + std::memcpy(data->name_data, i.name.data(), i.name.size()); lua_rawseti(state, -2, i.id); } @@ -65,33 +83,28 @@ static const struct luaL_Reg kDatabaseFuncs[] = {{"indexes", indexes}, * trivially copyable. */ struct LuaRecord { - database::TrackId id_or_zero; - database::IndexKey::Header header_at_next_depth; + std::variant<database::TrackId, database::IndexKey::Header> contents; size_t text_size; char text[]; }; -static_assert(std::is_trivially_copyable_v<LuaRecord> == true); - -static auto push_lua_record(lua_State* L, const database::IndexRecord& r) - -> void { - // Bake out the text into something concrete. - auto text = r.text().value_or(""); +static_assert(std::is_trivially_destructible<LuaRecord>()); +static_assert(std::is_trivially_copy_assignable<LuaRecord>()); +static auto push_lua_record(lua_State* L, const database::Record& r) -> void { // Create and init the userdata. LuaRecord* record = reinterpret_cast<LuaRecord*>( - lua_newuserdata(L, sizeof(LuaRecord) + text.size())); + lua_newuserdata(L, sizeof(LuaRecord) + r.text().size())); luaL_setmetatable(L, kDbRecordMetatable); // Init all the fields *record = { - .id_or_zero = r.track().value_or(0), - .header_at_next_depth = r.ExpandHeader(), - .text_size = text.size(), + .contents = r.contents(), + .text_size = r.text().size(), }; // Copy the string data across. - std::memcpy(record->text, text.data(), text.size()); + std::memcpy(record->text, r.text().data(), r.text().size()); } auto db_check_iterator(lua_State* L, int stack_pos) -> database::Iterator* { @@ -100,49 +113,30 @@ auto db_check_iterator(lua_State* L, int stack_pos) -> database::Iterator* { return it; } -static auto push_iterator(lua_State* state, - std::variant<database::Iterator*, - database::Continuation, - database::IndexInfo> val) -> void { - Bridge* instance = Bridge::Get(state); +static auto push_iterator(lua_State* state, const database::Iterator& it) + -> void { database::Iterator** data = reinterpret_cast<database::Iterator**>( lua_newuserdata(state, sizeof(uintptr_t))); - std::visit( - [&](auto&& arg) { - using T = std::decay_t<decltype(arg)>; - if constexpr (std::is_same_v<T, database::Iterator*>) { - *data = new database::Iterator(*arg); - } else { - *data = new database::Iterator(instance->services().database(), arg); - } - }, - val); + *data = new database::Iterator(it); luaL_setmetatable(state, kDbIteratorMetatable); } static auto db_iterate(lua_State* state) -> int { database::Iterator* it = db_check_iterator(state, 1); - luaL_checktype(state, 2, LUA_TFUNCTION); - int callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); - - it->Next([=](std::optional<database::IndexRecord> res) { - events::Ui().RunOnTask([=]() { - lua_rawgeti(state, LUA_REGISTRYINDEX, callback_ref); - if (res) { - push_lua_record(state, *res); - } else { - lua_pushnil(state); - } - CallProtected(state, 1, 0); - luaL_unref(state, LUA_REGISTRYINDEX, callback_ref); - }); - }); - return 0; + std::optional<database::Record> res = (*it)++; + + if (res) { + push_lua_record(state, *res); + } else { + lua_pushnil(state); + } + + return 1; } static auto db_iterator_clone(lua_State* state) -> int { database::Iterator* it = db_check_iterator(state, 1); - push_iterator(state, it); + push_iterator(state, *it); return 1; } @@ -154,6 +148,7 @@ static auto db_iterator_gc(lua_State* state) -> int { static const struct luaL_Reg kDbIteratorFuncs[] = {{"next", db_iterate}, {"clone", db_iterator_clone}, + {"__call", db_iterate}, {"__gc", db_iterator_gc}, {NULL, NULL}}; @@ -168,18 +163,22 @@ static auto record_contents(lua_State* state) -> int { LuaRecord* data = reinterpret_cast<LuaRecord*>( luaL_checkudata(state, 1, kDbRecordMetatable)); - if (data->id_or_zero) { - lua_pushinteger(state, data->id_or_zero); - } else { - std::string p = database::EncodeIndexPrefix(data->header_at_next_depth); - push_iterator(state, database::Continuation{ - .prefix = {p.data(), p.size()}, - .start_key = {p.data(), p.size()}, - .forward = true, - .was_prev_forward = true, - .page_size = 1, - }); - } + std::visit( + [&](auto&& arg) { + using T = std::decay_t<decltype(arg)>; + if constexpr (std::is_same_v<T, database::TrackId>) { + lua_pushinteger(state, arg); + } else if constexpr (std::is_same_v<T, database::IndexKey::Header>) { + Bridge* bridge = Bridge::Get(state); + auto db = bridge->services().database().lock(); + if (!db) { + lua_pushnil(state); + } else { + push_iterator(state, database::Iterator{db, arg}); + } + } + }, + data->contents); return 1; } @@ -190,38 +189,33 @@ static const struct luaL_Reg kDbRecordFuncs[] = {{"title", record_text}, {NULL, NULL}}; static auto index_name(lua_State* state) -> int { - database::IndexInfo** data = reinterpret_cast<database::IndexInfo**>( + LuaIndexInfo* data = reinterpret_cast<LuaIndexInfo*>( luaL_checkudata(state, 1, kDbIndexMetatable)); if (data == NULL) { return 0; } - lua_pushstring(state, (*data)->name.c_str()); + lua_pushlstring(state, data->name_data, data->name_size); return 1; } static auto index_iter(lua_State* state) -> int { - database::IndexInfo** data = reinterpret_cast<database::IndexInfo**>( + LuaIndexInfo* data = reinterpret_cast<LuaIndexInfo*>( luaL_checkudata(state, 1, kDbIndexMetatable)); if (data == NULL) { return 0; } - push_iterator(state, **data); - return 1; -} - -static auto index_gc(lua_State* state) -> int { - database::IndexInfo** data = reinterpret_cast<database::IndexInfo**>( - luaL_checkudata(state, 1, kDbIndexMetatable)); - if (data != NULL) { - delete *data; + Bridge* bridge = Bridge::Get(state); + auto db = bridge->services().database().lock(); + if (!db) { + lua_pushnil(state); } - return 0; + push_iterator(state, database::Iterator{db, data->id}); + return 1; } static const struct luaL_Reg kDbIndexFuncs[] = {{"name", index_name}, {"iter", index_iter}, {"__tostring", index_name}, - {"__gc", index_gc}, {NULL, NULL}}; static auto lua_database(lua_State* state) -> int { diff --git a/src/lua/lua_queue.cpp b/src/lua/lua_queue.cpp index fadcb51c..69d3b03d 100644 --- a/src/lua/lua_queue.cpp +++ b/src/lua/lua_queue.cpp @@ -21,7 +21,6 @@ #include "index.hpp" #include "property.hpp" #include "service_locator.hpp" -#include "source.hpp" #include "track.hpp" #include "track_queue.hpp" #include "ui_events.hpp" @@ -37,15 +36,13 @@ static auto queue_add(lua_State* state) -> int { database::TrackId id = luaL_checkinteger(state, 1); instance->services().bg_worker().Dispatch<void>([=]() { audio::TrackQueue& queue = instance->services().track_queue(); - auto editor = queue.Edit(); - queue.Append(editor, id); + queue.append(id); }); } else { - database::Iterator it = *db_check_iterator(state, 1); + database::Iterator* it = db_check_iterator(state, 1); instance->services().bg_worker().Dispatch<void>([=]() { audio::TrackQueue& queue = instance->services().track_queue(); - auto editor = queue.Edit(); - queue.Append(editor, database::TrackIterator{it}); + queue.append(database::TrackIterator{*it}); }); } @@ -55,8 +52,7 @@ static auto queue_add(lua_State* state) -> int { static auto queue_clear(lua_State* state) -> int { Bridge* instance = Bridge::Get(state); audio::TrackQueue& queue = instance->services().track_queue(); - auto editor = queue.Edit(); - queue.Clear(editor); + queue.clear(); return 0; } |
