feat(ncm): 三期第一批 — 歌单真分页(取消256截断)+专辑封面ncm_cache+歌词后台加载补锁
[agent-239] 仅改 patch_v2/ncm_app/。 1. 歌单分页(REPORT §14.1): track/all 全 404(§13.1) 弃用, 回 detail(n=1)全量 trackIds + song_detail 分批(≤NCM_SONG_BATCH=100) 触底逐页加载。appstate_load_playlist_songs_page offset=0 重建 song_ids[]/track_ids_count 载第0页, offset>0 追加(失败保留已载); playlist.c g_pl_more=(song_count<track_ids_count && <NCM_SONG_MAX), 触底 g_ploffset=song_count 起下一页(保留滚动), 首屏失败整页空态+点按重试, 追加失败 snack+保留已载。NCM_SONG_MAX 256→1000(单页渲染上限, bss +~1MB), NCM_SONG_BATCH 64→100, 删 NCM_PLAYLIST_PAGE(track/all 遗留)。 2. 专辑封面(§14.2): cover.c 封面改走 ncm_cache(LRU, 键=djb2(url)→song_cov<h>.jpg 同池), 缓存命中免下载/未命中下载→open/write/commit 落盘, 仍写 cover_current.jpg 供 launcher; 顺带修真 bug: save_cover_raw 在已持 g_cm 临界区内再 lock(非递归死锁)→封面永不刷新, 改调用方持锁。 歌单列表/详情头块封面保持现状。 3. 歌词后台加载(§14.3): lyric_worker 已异步(§11)未改线程模型; 补 lyric.c g_lyric_mu 数据竞争锁, 写侧 lyric_parse 整段持锁(清空用 lyric_clear_nolock 免二次取锁), 读侧 lyric_count/line_at/ line_text/line_tl 逐次取锁, 消除 UI/IPC 与 worker 间数据竞争(原 §10.9 FM4 良性竞态)。 验证(0 真实 NCM 请求): bench/pagination_sim.c 离线 stub 驱动真实 appstate 分页函数全 PASS (130首读全程/5191首封顶1000/空/越界无操作); mipsel build_ncm.sh 0 warning(text 842820/bss 2052068); 宿主 build_ncm_host.sh+MEOW_UI_DUMP home/playlist/player/lands 渲染正常无崩溃; host SDK_SRC 补 meow_pinyin(拼音IME py_predict 漏编致链接断)。ncm md5 b34bc1ed, ncm_host md5 1a2327e0。 未动 sdk/(主会话改 meow_ui_ime.c)/meow_launcherd/meow_amsd/vendor/core; 未 commit 它们。
This commit is contained in:
1 parent
5fac5e380d
commit
ee104f1b18
10 files changed
+471
-87
No files matched your search
@@ -39,11 +39,17 @@
|
||||
#define APP_OP_W 48 /* 行右侧操作区触达宽 */
|
||||
#define APP_FOOTER_H 26
|
||||
|
||||
/* ---- 数据规模(内存纪律:歌单/歌曲大列表虚拟化显示,数组有界)---- */
|
||||
/* ---- 数据规模(内存纪律:歌单/歌曲大列表虚拟化显示,数组有界;硬约束 R3P2 ~14MB)---- */
|
||||
#define NCM_PLAYLIST_MAX 120 /* 我的歌单上限 */
|
||||
#define NCM_SONG_MAX 256 /* 单个歌单曲目上限(大歌单截断前 256 条) */
|
||||
#define NCM_SONG_BATCH 64 /* song_detail 分批每批条数 */
|
||||
#define NCM_PLAYLIST_PAGE 50 /* 歌单曲目服务端分页每页条数(/api/playlist/track/all) */
|
||||
/* 单个歌单曲目上限 = 分页驱动下的「单页渲染上限」(REPORT §14,三期第一批):
|
||||
* detail(/v6/playlist/detail, n=1)取回全量 trackIds 入 song_ids[](≤ NCM_SONG_MAX);
|
||||
* song_detail 按 NCM_SONG_BATCH 分批拉歌词对象,列表触底自动加载下一页,直到
|
||||
* song_count == track_ids_count(歌单尾部)或 == NCM_SONG_MAX(内存上限,footer 显示 x/总数)。
|
||||
* 不再硬截断 256(NCM_SONG_MAX 从 256 提升到 1000,约 1.32KB/首 → 歌曲数组 ~1.37MB,14MB 内安全)。
|
||||
* 数值权衡见 REPORT §14.8(可再上调,代价是 bss 线性增长:每 +100 首 ≈ +132KB)。 */
|
||||
#define NCM_SONG_MAX 1000 /* 歌单曲目/歌曲对象上限(append-only 分页加载) */
|
||||
#define NCM_SONG_BATCH 100 /* song_detail 分批每批条数(≤500 安全窗内取保守 100;
|
||||
* 同时作「下一页」加载粒度;c 数组缓冲 clist[4096] 装 100 首 ≈2KB */
|
||||
#define NCM_LYRIC_LINES 600 /* 歌词行上限 */
|
||||
#define NCM_COVER_MAX 288*1024 /* 封面下载限幅 ~288KB */
|
||||
#define NCM_SEARCH_MAX 32 /* 搜索结果上限(v1 只显示前 32 条,无大缓冲) */
|
||||
@@ -106,10 +112,15 @@ typedef struct ncm_app_state {
|
||||
int playlist_count;
|
||||
int active_playlist; /* 当前打开歌单的下标;-1=无 */
|
||||
|
||||
/* 当前歌单曲目(id 用 int64_t:网易云歌曲 id 可 >2^31,MIPS32 long 溢出) */
|
||||
/* 当前歌单曲目(id 用 int64_t:网易云歌曲 id 可 >2^31,MIPS32 long 溢出)。
|
||||
* song_ids[] = detail 返回的全量 trackIds(≤ NCM_SONG_MAX,分页索引);
|
||||
* songs[] = 已物化的歌曲对象(append-only,与 song_ids[] 前 song_count 首一一对应);
|
||||
* song_count = 已物化数(列表 count = song_count);track_ids_count = trackIds 总数(≥ song_count,
|
||||
* 其差值 = 仍有「下一页」待 song_detail 分批拉取)。 */
|
||||
int64_t song_ids[NCM_SONG_MAX];
|
||||
ncm_song_t songs[NCM_SONG_MAX];
|
||||
int song_count;
|
||||
int track_ids_count; /* detail 取回的 trackIds 总数(≤ NCM_SONG_MAX) */
|
||||
|
||||
/* 播放页视图态 */
|
||||
int playing_song; /* 正在播放歌曲在 songs[] 下标(UI 侧缓存);-1=无 */
|
||||
@@ -249,8 +260,10 @@ int appstate_ensure_uid(void); /* 若 uid 缺失则 login_status_check 取
|
||||
int appstate_load_playlists(void); /* 拉我的歌单 */
|
||||
int appstate_load_playlist_songs(int idx); /* 兼容:整批载入(内部走分页循环) */
|
||||
int appstate_load_playlist_songs_page(int idx, int offset, int limit);
|
||||
/* 服务端分页载入第 offset 页(offset=0 重头填,
|
||||
* offset>0 追加到 g_st.songs[offset..]);写 g_st.song_count */
|
||||
/* detail(全量 trackIds)后按页拉 song_detail:
|
||||
* offset=0 重头(重建 song_ids[]/track_ids_count,清空后载第 0 页);
|
||||
* offset>0 追加第 offset 页到 g_st.songs[offset..];
|
||||
* 写 g_st.song_count(=offset+本页实际数)。 */
|
||||
void appstate_apply_playlist_cover(int idx);
|
||||
void appstate_set_playing_song(int idx, const char *cover_url);
|
||||
int appstate_current_playing(void); /* 返回当前播放歌曲下标(UI) */
|
||||
|
||||
Reference in new issue
Block a user