bool playlist_manager::playlist_update_content(t_size playlist, metadb_handle_list_cref content, bool bUndoBackup) { metadb_handle_list old; playlist_get_all_items(playlist, old); if (old.get_size() == 0) { if (content.get_size() == 0) return false; if (bUndoBackup) playlist_undo_backup(playlist); playlist_add_items(playlist, content, bit_array_false()); return true; } pfc::avltree_t<metadb_handle::nnptr> itemsOld, itemsNew; for(t_size walk = 0; walk < old.get_size(); ++walk) itemsOld += old[walk]; for(t_size walk = 0; walk < content.get_size(); ++walk) itemsNew += content[walk]; bit_array_bittable removeMask(old.get_size()); bit_array_bittable filterMask(content.get_size()); bool gotNew = false, filterNew = false, gotRemove = false; for(t_size walk = 0; walk < content.get_size(); ++walk) { const bool state = !itemsOld.have_item(content[walk]); if (state) gotNew = true; else filterNew = true; filterMask.set(walk, state); } for(t_size walk = 0; walk < old.get_size(); ++walk) { const bool state = !itemsNew.have_item(old[walk]); if (state) gotRemove = true; removeMask.set(walk, state); } if (!gotNew && !gotRemove) return false; if (bUndoBackup) playlist_undo_backup(playlist); if (gotRemove) { playlist_remove_items(playlist, removeMask); } if (gotNew) { if (filterNew) { metadb_handle_list temp(content); temp.filter_mask(filterMask); playlist_add_items(playlist, temp, bit_array_false()); } else { playlist_add_items(playlist, content, bit_array_false()); } } { playlist_get_all_items(playlist, old); pfc::array_t<t_size> order; if (pfc::guess_reorder_pattern<pfc::list_base_const_t<metadb_handle_ptr> >(order, old, content)) { playlist_reorder_items(playlist, order.get_ptr(), order.get_size()); } } return true; }
t_size file_list_from_metadb_handle_list::g_get_count(metadb_handle_list_cref data, t_size max) { pfc::avltree_t<const char*, metadb::path_comparator> content; const t_size inCount = data.get_size(); for(t_size walk = 0; walk < inCount && content.get_count() < max; ++walk) { content += data[walk]->get_path(); } return content.get_count(); }
void playlist_manager::on_file_rechaptered(const char * path, metadb_handle_list_cref newItems) { if (newItems.get_size() == 0) return; const size_t numPlaylists = this->get_playlist_count(); for( size_t walkPlaylist = 0; walkPlaylist < numPlaylists; ++ walkPlaylist ) { if (!playlist_lock_is_present(walkPlaylist)) { auto itemCount = [=] () -> unsigned { return this->playlist_get_item_count( walkPlaylist ); }; auto itemHandle = [=] ( unsigned item ) -> metadb_handle_ptr { return this->playlist_get_item_handle( walkPlaylist, item ); }; auto itemMatch = [=] ( unsigned item ) -> bool { return metadb::path_compare(path, itemHandle(item)->get_path()) == 0; }; auto itemMatch2 = [=] ( metadb_handle_ptr item ) -> bool { return metadb::path_compare(path, item->get_path() ) == 0; }; for( size_t walkItem = 0; walkItem < itemCount(); ) { if (itemMatch( walkItem )) { pfc::avltree_t<uint32_t> subsongs; unsigned base = walkItem; bool bSel = false; for( ++walkItem ; walkItem < itemCount() ; ++ walkItem ) { auto handle = itemHandle( walkItem ); if (! itemMatch2( handle ) ) break; if (! subsongs.add_item_check(handle->get_subsong_index())) break; bSel = bSel || this->playlist_is_item_selected(walkPlaylist, walkItem); } // REMOVE base ... walkItem range and insert newHandles at base this->playlist_remove_items( walkPlaylist, pfc::bit_array_range(base, walkItem-base) ); this->playlist_insert_items( walkPlaylist, base, newItems, pfc::bit_array_val( bSel ) ); walkItem = base + newItems.get_size(); } else { ++walkItem; } } } } }