changeset 8174:014e0ea85bdb

Add random stepping support
author albeu
date Tue, 12 Nov 2002 23:39:35 +0000
parents 56e664c3bc24
children bf5d1da56ecd
files playtree.c playtree.h
diffstat 2 files changed, 96 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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);
 }
--- 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