📄 tree.c
字号:
playlist_item_t * playlist_GetPreferredNode( playlist_t *p_playlist, playlist_item_t *p_node ){ PL_ASSERT_LOCKED; int i; if( p_node->p_parent == p_playlist->p_root_category ) { if( p_playlist->b_tree || p_node->p_input->b_prefers_tree ) return p_node; for( i = 0 ; i< p_playlist->p_root_onelevel->i_children; i++ ) { if( p_playlist->p_root_onelevel->pp_children[i]->p_input->i_id == p_node->p_input->i_id ) return p_playlist->p_root_onelevel->pp_children[i]; } } else if( p_node->p_parent == p_playlist->p_root_onelevel ) { if( !p_playlist->b_tree || !p_node->p_input->b_prefers_tree ) return p_node; for( i = 0 ; i< p_playlist->p_root_category->i_children; i++ ) { if( p_playlist->p_root_category->pp_children[i]->p_input->i_id == p_node->p_input->i_id ) return p_playlist->p_root_category->pp_children[i]; } } return NULL;}/********************************************************************** * Tree walking functions **********************************************************************/playlist_item_t *playlist_GetLastLeaf(playlist_t *p_playlist, playlist_item_t *p_root ){ PL_ASSERT_LOCKED; int i; playlist_item_t *p_item; for ( i = p_root->i_children - 1; i >= 0; i-- ) { if( p_root->pp_children[i]->i_children == -1 ) return p_root->pp_children[i]; else if( p_root->pp_children[i]->i_children > 0) { p_item = playlist_GetLastLeaf( p_playlist, p_root->pp_children[i] ); if ( p_item != NULL ) return p_item; } else if( i == 0 ) return NULL; } return NULL;}/** * Finds the next item to play * * \param p_playlist the playlist * \param p_root the root node * \param p_item the previous item (NULL if none ) * \return the next item to play, or NULL if none found */playlist_item_t *playlist_GetNextLeaf( playlist_t *p_playlist, playlist_item_t *p_root, playlist_item_t *p_item, bool b_ena, bool b_unplayed ){ PL_ASSERT_LOCKED; playlist_item_t *p_next; assert( p_root && p_root->i_children != -1 ); PL_DEBUG2( "finding next of %s within %s", PLI_NAME( p_item ), PLI_NAME( p_root ) ); /* Now, walk the tree until we find a suitable next item */ p_next = p_item; while( 1 ) { bool b_ena_ok = true, b_unplayed_ok = true; p_next = GetNextItem( p_playlist, p_root, p_next ); if( !p_next || p_next == p_root ) break; if( p_next->i_children == -1 ) { if( b_ena && p_next->i_flags & PLAYLIST_DBL_FLAG ) b_ena_ok = false; if( b_unplayed && p_next->p_input->i_nb_played != 0 ) b_unplayed_ok = false; if( b_ena_ok && b_unplayed_ok ) break; } } if( p_next == NULL ) PL_DEBUG2( "at end of node" ); return p_next;}/** * Finds the previous item to play * * \param p_playlist the playlist * \param p_root the root node * \param p_item the previous item (NULL if none ) * \return the next item to play, or NULL if none found */playlist_item_t *playlist_GetPrevLeaf( playlist_t *p_playlist, playlist_item_t *p_root, playlist_item_t *p_item, bool b_ena, bool b_unplayed ){ PL_ASSERT_LOCKED; playlist_item_t *p_prev; PL_DEBUG2( "finding previous os %s within %s", PLI_NAME( p_item ), PLI_NAME( p_root ) ); assert( p_root && p_root->i_children != -1 ); /* Now, walk the tree until we find a suitable previous item */ p_prev = p_item; while( 1 ) { bool b_ena_ok = true, b_unplayed_ok = true; p_prev = GetPrevItem( p_playlist, p_root, p_prev ); if( !p_prev || p_prev == p_root ) break; if( p_prev->i_children == -1 ) { if( b_ena && p_prev->i_flags & PLAYLIST_DBL_FLAG ) b_ena_ok = false; if( b_unplayed && p_prev->p_input->i_nb_played != 0 ) b_unplayed_ok = false; if( b_ena_ok && b_unplayed_ok ) break; } } if( p_prev == NULL ) PL_DEBUG2( "at beginning of node" ); return p_prev;}/************************************************************************ * Following functions are local ***********************************************************************//** * Get the next item in the tree * If p_item is NULL, return the first child of root **/playlist_item_t *GetNextItem( playlist_t *p_playlist, playlist_item_t *p_root, playlist_item_t *p_item ){ playlist_item_t *p_parent; int i; /* Node with children, get the first one */ if( p_item && p_item->i_children > 0 ) return p_item->pp_children[0]; if( p_item != NULL ) p_parent = p_item->p_parent; else p_parent = p_root; for( i= 0 ; i < p_parent->i_children ; i++ ) { if( p_item == NULL || p_parent->pp_children[i] == p_item ) { if( p_item == NULL ) i = -1; if( i+1 >= p_parent->i_children ) { /* Was already the last sibling. Look for uncles */ PL_DEBUG2( "Current item is the last of the node," "looking for uncle from %s", p_parent->p_input->psz_name ); if( p_parent == p_root ) { PL_DEBUG2( "already at root" ); return NULL; } return GetNextUncle( p_playlist, p_item, p_root ); } else { return p_parent->pp_children[i+1]; } } } return NULL;}playlist_item_t *GetNextUncle( playlist_t *p_playlist, playlist_item_t *p_item, playlist_item_t *p_root ){ playlist_item_t *p_parent = p_item->p_parent; playlist_item_t *p_grandparent; bool b_found = false; (void)p_playlist; if( p_parent != NULL ) { p_grandparent = p_parent->p_parent; while( p_grandparent ) { int i; for( i = 0 ; i< p_grandparent->i_children ; i++ ) { if( p_parent == p_grandparent->pp_children[i] ) { PL_DEBUG2( "parent %s found as child %i of grandparent %s", p_parent->p_input->psz_name, i, p_grandparent->p_input->psz_name ); b_found = true; break; } } if( b_found && i + 1 < p_grandparent->i_children ) { return p_grandparent->pp_children[i+1]; } /* Not found at root */ if( p_grandparent == p_root ) { return NULL; } else { p_parent = p_grandparent; p_grandparent = p_parent->p_parent; } } } /* We reached root */ return NULL;}playlist_item_t *GetPrevUncle( playlist_t *p_playlist, playlist_item_t *p_item, playlist_item_t *p_root ){ playlist_item_t *p_parent = p_item->p_parent; playlist_item_t *p_grandparent; bool b_found = false; (void)p_playlist; if( p_parent != NULL ) { p_grandparent = p_parent->p_parent; while( 1 ) { int i; for( i = p_grandparent->i_children -1 ; i >= 0; i-- ) { if( p_parent == p_grandparent->pp_children[i] ) { b_found = true; break; } } if( b_found && i - 1 > 0 ) { return p_grandparent->pp_children[i-1]; } /* Not found at root */ if( p_grandparent == p_root ) { return NULL; } else { p_parent = p_grandparent; p_grandparent = p_parent->p_parent; } } } /* We reached root */ return NULL;}/* Recursively search the tree for previous item */playlist_item_t *GetPrevItem( playlist_t *p_playlist, playlist_item_t *p_root, playlist_item_t *p_item ){ playlist_item_t *p_parent; int i; /* Node with children, get the last one */ if( p_item && p_item->i_children > 0 ) return p_item->pp_children[p_item->i_children - 1]; /* Last child of its parent ? */ if( p_item != NULL ) p_parent = p_item->p_parent; else { msg_Err( p_playlist, "Get the last one" ); abort(); }; for( i = p_parent->i_children -1 ; i >= 0 ; i-- ) { if( p_parent->pp_children[i] == p_item ) { if( i-1 < 0 ) { /* Was already the first sibling. Look for uncles */ PL_DEBUG2( "current item is the first of its node," "looking for uncle from %s", p_parent->p_input->psz_name ); if( p_parent == p_root ) { PL_DEBUG2( "already at root" ); return NULL; } return GetPrevUncle( p_playlist, p_item, p_root ); } else { return p_parent->pp_children[i-1]; } } } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -