# HG changeset patch # User albeu # Date 1037144375 0 # Node ID 014e0ea85bdb356011cc8aa614ce759b7cee4fba # Parent 56e664c3bc2469f5182affdda37157e305138ee1 Add random stepping support diff -r 56e664c3bc24 -r 014e0ea85bdb playtree.c --- a/playtree.c Tue Nov 12 21:52:56 2002 +0000 +++ b/playtree.c Tue Nov 12 23:39:35 2002 +0000 @@ -406,6 +406,36 @@ } +// all childs if deep < 0 +void +play_tree_set_flag(play_tree_t* pt, int flags , int deep) { + play_tree_t* i; + + pt->flags |= flags; + + if(deep && pt->child) { + if(deep > 0) deep--; + for(i = pt->child ; i ; i = i->next) + play_tree_set_flag(i,flags,deep); + } +} + +void +play_tree_unset_flag(play_tree_t* pt, int flags , int deep) { + play_tree_t* i; + + pt->flags &= ~flags; + + if(deep && pt->child) { + if(deep > 0) deep--; + for(i = pt->child ; i ; i = i->next) + play_tree_unset_flag(i,flags,deep); + } +} + + +//////////////////////////////////// ITERATOR ////////////////////////////////////// + static void play_tree_iter_push_params(play_tree_iter_t* iter) { int n; @@ -480,6 +510,34 @@ free(iter); } +static play_tree_t* +play_tree_rnd_step(play_tree_t* pt) { + int count = 0; + int r; + play_tree_t *i,*head; + + // Count how many free choice we have + for(i = pt ; i->prev ; i = i->prev) + if(!(i->flags & PLAY_TREE_RND_PLAYED)) count++; + head = i; + if(!(i->flags & PLAY_TREE_RND_PLAYED)) count++; + for(i = pt->next ; i ; i = i->next) + if(!(i->flags & PLAY_TREE_RND_PLAYED)) count++; + + if(!count) return NULL; + + r = (int)((count-1.0) * rand() / RAND_MAX); + + for(i = head ; i ; i=i->next) { + if(!(i->flags & PLAY_TREE_RND_PLAYED)) r--; + if(r < 0) return i; + } + + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Random stepping error\n"); + return NULL; +} + + int play_tree_iter_step(play_tree_iter_t* iter, int d,int with_nodes) { play_tree_t* pt; @@ -503,14 +561,29 @@ m_config_pop(iter->config); } + if(iter->tree->parent && (iter->tree->parent->flags & PLAY_TREE_RND)) + iter->mode = PLAY_TREE_ITER_RND; + else + iter->mode = PLAY_TREE_ITER_NORMAL; + iter->file = -1; - if( d > 0 ) - pt = iter->tree->next; - else if(d < 0) - pt = iter->tree->prev; - else + if(iter->mode == PLAY_TREE_ITER_RND) + pt = play_tree_rnd_step(iter->tree); + else if( d > 0 ) { + int i; pt = iter->tree; - + for(i = d ; i > 0 && pt ; i--) + pt = pt->next; + d = i ? i : 1; + } else if(d < 0) { + int i; + pt = iter->tree; + for(i = d ; i < 0 && pt ; i++) + pt = pt->prev; + d = i ? i : -1; + } else + pt = iter->tree; + if(pt == NULL) { // No next // Must we loop? if(iter->tree->parent && iter->tree->parent->loop != 0 && ((d > 0 && iter->loop != 0) || ( d < 0 && (iter->loop < 0 || iter->loop < iter->tree->parent->loop) ) ) ) { @@ -562,6 +635,8 @@ if(iter->config) { play_tree_iter_push_params(iter); iter->entry_pushed = 1; + if(iter->mode == PLAY_TREE_ITER_RND) + pt->flags |= PLAY_TREE_RND_PLAYED; } return PLAY_TREE_ITER_ENTRY; @@ -625,8 +700,11 @@ iter->tree = iter->tree->parent; // Pop subtree params - if(iter->config) + if(iter->config) { m_config_pop(iter->config); + if(iter->mode == PLAY_TREE_ITER_RND) + iter->tree->flags |= PLAY_TREE_RND_PLAYED; + } return play_tree_iter_step(iter,d,with_nodes); } diff -r 56e664c3bc24 -r 014e0ea85bdb playtree.h --- a/playtree.h Tue Nov 12 21:52:56 2002 +0000 +++ b/playtree.h Tue Nov 12 23:39:35 2002 +0000 @@ -16,6 +16,15 @@ #define PLAY_TREE_ENTRY_TV 2 #define PLAY_TREE_ENTRY_FILE 3 +// Playtree flags +#define PLAY_TREE_RND (1<<0) +// Playtree flags used by the iter +#define PLAY_TREE_RND_PLAYED (1<<8) + +// Iter mode +#define PLAY_TREE_ITER_NORMAL 0 +#define PLAY_TREE_ITER_RND 1 + typedef struct play_tree play_tree_t; typedef struct play_tree_iter play_tree_iter_t; typedef struct play_tree_param play_tree_param_t; @@ -50,6 +59,7 @@ int loop; char** files; int entry_type; + int flags; }; struct play_tree_iter { @@ -60,6 +70,7 @@ int file; int num_files; int entry_pushed; + int mode; int* status_stack; // loop/valid stack to save/revert status when we go up/down int stack_size; // status stack size