diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-11-23 14:08:46 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-11-23 14:08:46 +1100 |
| commit | 09c0e1608f2d88f56d8bf87ff90482459376ad95 (patch) | |
| tree | e675756aff8c8f78fe89c4f2f9e30c713f10cbfe /src/lua | |
| parent | b07bfbc6c70fd0bba8dff85fe4149feb9fa9b8d4 (diff) | |
| download | tangara-fw-09c0e1608f2d88f56d8bf87ff90482459376ad95.tar.gz | |
Implement adding to the playback queue from lua
Diffstat (limited to 'src/lua')
| -rw-r--r-- | src/lua/include/lua_database.hpp | 4 | ||||
| -rw-r--r-- | src/lua/lua_database.cpp | 72 | ||||
| -rw-r--r-- | src/lua/lua_queue.cpp | 21 |
3 files changed, 69 insertions, 28 deletions
diff --git a/src/lua/include/lua_database.hpp b/src/lua/include/lua_database.hpp index e47ace08..b0d2acbd 100644 --- a/src/lua/include/lua_database.hpp +++ b/src/lua/include/lua_database.hpp @@ -8,8 +8,12 @@ #include "lua.hpp" +#include "database.hpp" + namespace lua { +auto db_check_iterator(lua_State*, int stack_pos) -> database::Iterator*; + auto RegisterDatabaseModule(lua_State*) -> void; } // namespace lua diff --git a/src/lua/lua_database.cpp b/src/lua/lua_database.cpp index 4a7c82a5..d41f4794 100644 --- a/src/lua/lua_database.cpp +++ b/src/lua/lua_database.cpp @@ -32,7 +32,7 @@ namespace lua { static constexpr char kDbIndexMetatable[] = "db_index"; static constexpr char kDbRecordMetatable[] = "db_record"; -static constexpr char kDbIteratorMetatable[] = "db_record"; +static constexpr char kDbIteratorMetatable[] = "db_iterator"; static auto indexes(lua_State* state) -> int { Bridge* instance = Bridge::Get(state); @@ -94,13 +94,37 @@ static auto push_lua_record(lua_State* L, const database::IndexRecord& r) std::memcpy(record->text, text.data(), text.size()); } +auto db_check_iterator(lua_State* L, int stack_pos) -> database::Iterator* { + database::Iterator* it = *reinterpret_cast<database::Iterator**>( + luaL_checkudata(L, stack_pos, kDbIteratorMetatable)); + return it; +} + +static auto push_iterator(lua_State* state, + std::variant<database::Iterator*, + database::Continuation, + database::IndexInfo> val) -> void { + Bridge* instance = Bridge::Get(state); + 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); + luaL_setmetatable(state, kDbIteratorMetatable); +} + static auto db_iterate(lua_State* state) -> int { - luaL_checktype(state, 1, LUA_TFUNCTION); + database::Iterator* it = db_check_iterator(state, 1); + luaL_checktype(state, 2, LUA_TFUNCTION); int callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); - database::Iterator* it = *reinterpret_cast<database::Iterator**>( - lua_touserdata(state, lua_upvalueindex(1))); - it->Next([=](std::optional<database::IndexRecord> res) { events::Ui().RunOnTask([=]() { lua_rawgeti(state, LUA_REGISTRYINDEX, callback_ref); @@ -116,29 +140,22 @@ static auto db_iterate(lua_State* state) -> int { return 0; } +static auto db_iterator_clone(lua_State* state) -> int { + database::Iterator* it = db_check_iterator(state, 1); + push_iterator(state, it); + return 1; +} + static auto db_iterator_gc(lua_State* state) -> int { - database::Iterator** it = reinterpret_cast<database::Iterator**>( - luaL_checkudata(state, 1, kDbIteratorMetatable)); - if (it != NULL) { - delete *it; - } + database::Iterator* it = db_check_iterator(state, 1); + delete it; return 0; } -static auto push_iterator( - lua_State* state, - std::variant<database::Continuation, database::IndexInfo> val) -> void { - Bridge* instance = Bridge::Get(state); - database::Iterator** data = reinterpret_cast<database::Iterator**>( - lua_newuserdata(state, sizeof(uintptr_t))); - std::visit( - [&](auto&& arg) { - *data = new database::Iterator(instance->services().database(), arg); - }, - val); - luaL_setmetatable(state, kDbIteratorMetatable); - lua_pushcclosure(state, db_iterate, 1); -} +static const struct luaL_Reg kDbIteratorFuncs[] = {{"next", db_iterate}, + {"clone", db_iterator_clone}, + {"__gc", db_iterator_gc}, + {NULL, NULL}}; static auto record_text(lua_State* state) -> int { LuaRecord* data = reinterpret_cast<LuaRecord*>( @@ -219,9 +236,10 @@ static auto lua_database(lua_State* state) -> int { luaL_setfuncs(state, kDbIndexFuncs, 0); luaL_newmetatable(state, kDbIteratorMetatable); - lua_pushliteral(state, "__gc"); - lua_pushcfunction(state, db_iterator_gc); - lua_settable(state, -3); + lua_pushliteral(state, "__index"); + lua_pushvalue(state, -2); + lua_settable(state, -3); // metatable.__index = metatable + luaL_setfuncs(state, kDbIteratorFuncs, 0); luaL_newmetatable(state, kDbRecordMetatable); lua_pushliteral(state, "__index"); diff --git a/src/lua/lua_queue.cpp b/src/lua/lua_queue.cpp index 500940a2..929a7159 100644 --- a/src/lua/lua_queue.cpp +++ b/src/lua/lua_queue.cpp @@ -21,6 +21,7 @@ #include "index.hpp" #include "property.hpp" #include "service_locator.hpp" +#include "source.hpp" #include "ui_events.hpp" namespace lua { @@ -28,10 +29,28 @@ namespace lua { [[maybe_unused]] static constexpr char kTag[] = "lua_queue"; static auto queue_add(lua_State* state) -> int { + Bridge* instance = Bridge::Get(state); + + if (lua_isinteger(state, 1)) { + instance->services().track_queue().AddLast(luaL_checkinteger(state, 1)); + } else { + database::Iterator* it = db_check_iterator(state, 1); + instance->services().track_queue().IncludeLast( + std::make_shared<playlist::IteratorSource>(*it)); + } + + return 0; +} + +static auto queue_clear(lua_State* state) -> int { + Bridge* instance = Bridge::Get(state); + instance->services().track_queue().Clear(); return 0; } -static const struct luaL_Reg kQueueFuncs[] = {{"add", queue_add}, {NULL, NULL}}; +static const struct luaL_Reg kQueueFuncs[] = {{"add", queue_add}, + {"clear", queue_clear}, + {NULL, NULL}}; static auto lua_queue(lua_State* state) -> int { luaL_newlib(state, kQueueFuncs); |
