1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/*
* Copyright 2023 jacqueline <me@jacqueline.id.au>
*
* SPDX-License-Identifier: GPL-3.0-only
*/
#include "audio/audio_events.hpp"
#include "lua/lua_database.hpp"
#include <memory>
#include <string>
#include "lua.hpp"
#include "esp_log.h"
#include "lauxlib.h"
#include "lua.h"
#include "lvgl.h"
#include "audio/track_queue.hpp"
#include "database/database.hpp"
#include "database/index.hpp"
#include "database/track.hpp"
#include "events/event_queue.hpp"
#include "lua/bridge.hpp"
#include "lua/property.hpp"
#include "system_fsm/service_locator.hpp"
#include "ui/ui_events.hpp"
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)) {
database::TrackId id = luaL_checkinteger(state, 1);
instance->services().bg_worker().Dispatch<void>([=]() {
audio::TrackQueue& queue = instance->services().track_queue();
queue.append(id);
});
} else if (lua_isstring(state, 1)) {
size_t len;
const char* str = luaL_checklstring(state, 1, &len);
std::string path{str, len};
instance->services().bg_worker().Dispatch<void>([=]() {
audio::TrackQueue& queue = instance->services().track_queue();
queue.append(path);
});
} else {
database::Iterator* it = db_check_iterator(state, 1);
instance->services().bg_worker().Dispatch<void>([=]() {
audio::TrackQueue& queue = instance->services().track_queue();
queue.append(database::TrackIterator{*it});
});
}
return 0;
}
static auto queue_clear(lua_State* state) -> int {
Bridge* instance = Bridge::Get(state);
audio::TrackQueue& queue = instance->services().track_queue();
queue.clear();
return 0;
}
static auto queue_open_playlist(lua_State* state) -> int {
Bridge* instance = Bridge::Get(state);
audio::TrackQueue& queue = instance->services().track_queue();
size_t len = 0;
const char* str = luaL_checklstring(state, 1, &len);
if (!str) {
return 0;
}
queue.clear();
queue.openPlaylist(str);
return 0;
}
static auto queue_play_from(lua_State* state) -> int {
Bridge* instance = Bridge::Get(state);
audio::TrackQueue& queue = instance->services().track_queue();
size_t len = 0;
const char* str = luaL_checklstring(state, 1, &len);
if (!str) {
return 0;
}
auto pos = luaL_checkinteger(state, 2);
queue.playFromPosition(str, pos);
return 0;
}
static const struct luaL_Reg kQueueFuncs[] = {
{"add", queue_add},
{"clear", queue_clear},
{"open_playlist", queue_open_playlist},
{"play_from", queue_play_from},
{NULL, NULL}};
static auto lua_queue(lua_State* state) -> int {
luaL_newlib(state, kQueueFuncs);
// Repeat Mode Enum
lua_pushliteral(state, "RepeatMode");
lua_newtable(state);
lua_pushliteral(state, "OFF");
lua_pushinteger(state, (int)audio::TrackQueue::RepeatMode::OFF);
lua_rawset(state, -3);
lua_pushliteral(state, "REPEAT_TRACK");
lua_pushinteger(state, (int)audio::TrackQueue::RepeatMode::REPEAT_TRACK);
lua_rawset(state, -3);
lua_pushliteral(state, "REPEAT_QUEUE");
lua_pushinteger(state, (int)audio::TrackQueue::RepeatMode::REPEAT_QUEUE);
lua_rawset(state, -3);
lua_rawset(state, -3);
return 1;
}
auto RegisterQueueModule(lua_State* s) -> void {
luaL_requiref(s, "queue", lua_queue, true);
lua_pop(s, 1);
}
} // namespace lua
|