ncm search: 历史+单曲/歌单分类+分页+误触修复+不覆写歌单上下文 (§23)

- 搜索历史:进页自动弹键盘;meow_config 持久化 ≤12 去重最新在前;空态=历史列表(点搜/左滑删/清空)
- 结果分类单曲/歌单页签:独立结果集+独立滚动;歌单行进详情(playlist_open_pl);单曲行播放
- 触底分页:offset 累加 limit=30/页 cloudsearch 同参数;每类各记 offset
- 误触抑制:g_press_row + g_press_delta>10(对齐 home/playlist §13.3)
- 结果改独立数组(不写 g_st.songs[]);播放搜索单曲建搜索队列(queue_src=SEARCH),不弄丢歌单窗口
- core cloudsearch 扩展 type/offset/limit/total + 歌单解析
- bench/search_sim.c 离线回归(历史/独立集/翻页 offset/队列上下文);host searchtap 误触自检

验证:mipsel -Wall -Wextra 0 warning;core host/mipsel PASS;search_sim PASS;
宿主离屏 search(单曲)/searchpl(歌单)/searchhist(空态历史)/searchtap(误触) 均正常;0 真实 NCM 请求。
This commit is contained in:
MeowOS committed 2026-09-01 19:21:16 +08:00
1 parent d4928224a5
commit 1e97dbf54a
15 files changed
+1152 -121

No files matched your search

+10 -8
View File
@@ -126,7 +126,8 @@ void player_manager_next(int dir)
pthread_mutex_lock(&g_play.mu);
int c = g_play.cur_song + dir;
if (c < 0) c = 0;
if (c >= g_st.track_ids_count) c = g_st.track_ids_count - 1; /* 滑窗:边界=全量索引数 */
int cnt = appstate_queue_count(); /* §23:按队列来源(窗口全量 或 搜索条数) */
if (c >= cnt) c = cnt - 1;
if (c != g_play.cur_song) {
g_play.cur_song = c;
g_play.cmd = 0;
@@ -387,9 +388,9 @@ static void run_song(int idx)
/* §17 滑窗兼容:物化目标曲(窗内命中 / 盘缓存 / song_detail 单曲)并整体快照进
* g_play.play_song——之后本曲所有字段读快照,窗口滑出当前播放曲不影响播放。 */
ncm_song_t s;
if (appstate_song_copy(idx, &s) != 0) {
int fr = appstate_song_fetch(idx, &s);
if (fr != NCM_OK) { set_err(fr, "load failed"); return; }
if (appstate_queue_song(idx, &s) != 0) { /* §23:按 queue_src 取(窗口 或 搜索队列) */
set_err(NCM_ERR_ARG, "load failed");
return;
}
if (!still_current(idx)) return; /* 物化期间已切歌/停止:不写过期快照 */
pthread_mutex_lock(&g_play.mu);
@@ -571,7 +572,7 @@ static void *player_thread(void *arg)
int st = g_play.state;
pthread_mutex_unlock(&g_play.mu);
if (cur < 0 || cur >= g_st.track_ids_count || st == NCM_PC_STOPPED) {
if (cur < 0 || cur >= appstate_queue_count() || st == NCM_PC_STOPPED) {
usleep(60 * 1000);
continue;
}
@@ -583,9 +584,10 @@ static void *player_thread(void *arg)
int st2 = g_play.state;
pthread_mutex_unlock(&g_play.mu);
/* 自然播完且无新命令 → 顺延下一首;否则回到循环等待 */
if (cur2 >= 0 && cur2 < g_st.track_ids_count && st2 != NCM_PC_STOPPED && cur2 == cur) {
int qc = appstate_queue_count();
if (cur2 >= 0 && cur2 < qc && st2 != NCM_PC_STOPPED && cur2 == cur) {
int nx = cur + 1;
if (nx < g_st.track_ids_count) { player_manager_next(1); }
if (nx < qc) { player_manager_next(1); }
else { player_manager_stop(); }
} else {
usleep(50 * 1000);
@@ -616,7 +618,7 @@ static void *lyric_worker(void *arg)
int have = g_play.play_song_valid;
ncm_strlcpy(id, have ? g_play.play_song.id : "", sizeof id);
pthread_mutex_unlock(&g_play.mu);
if (idx < 0 || idx >= g_st.track_ids_count || !have) {
if (idx < 0 || idx >= appstate_queue_count() || !have) {
lyric_clear();
pthread_mutex_lock(&g_lyrmu);
g_lyr_song_id[0] = 0;