Beispiel #1
0
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;
}
Beispiel #2
0
	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();
	}
Beispiel #3
0
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;
				}
			}
		}
	}
}