« get me outta code hell

http-music - Command-line music player + utils (not a server!)
about summary refs log tree commit diff
path: root/src/pickers.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/pickers.js')
-rw-r--r--src/pickers.js85
1 files changed, 79 insertions, 6 deletions
diff --git a/src/pickers.js b/src/pickers.js
index 014eee8..ec4d629 100644
--- a/src/pickers.js
+++ b/src/pickers.js
@@ -2,7 +2,25 @@
 
 const { flattenGrouplike } = require('./playlist-utils')
 
-function makeOrderedPlaylistPicker(grouplike) {
+function makeLoopingOrderedPlaylistPicker(grouplike) {
+  // Looping ordered playlist picker - this plays all the tracks in a group
+  // in order, while looping the same order forever.
+
+  const flatGroup = flattenGrouplike(grouplike)
+  let index = 0
+
+  return function() {
+    if (index >= flatGroup.items.length) {
+      index = 0
+    }
+
+    const picked = flatGroup.items[index]
+    index++
+    return picked
+  }
+}
+
+function makeNonLoopingOrderedPlaylistPicker(grouplike) {
   // Ordered playlist picker - this plays all the tracks in a group in
   // order, after flattening it.
 
@@ -20,7 +38,7 @@ function makeOrderedPlaylistPicker(grouplike) {
   }
 }
 
-function makeShufflePlaylistPicker(grouplike) {
+function makeLoopingShufflePlaylistPicker(grouplike) {
   // Shuffle playlist picker - this selects a random track at any index in
   // the playlist, after flattening it.
 
@@ -29,15 +47,70 @@ function makeShufflePlaylistPicker(grouplike) {
   return function() {
     if (flatGroup.items.length) {
       const index = Math.floor(Math.random() * flatGroup.items.length)
-      const picked = flatGroup.items[index]
-      return picked
+      return flatGroup.items[index]
+    } else {
+      return null
+    }
+  }
+}
+
+function makeNonLoopingShufflePlaylistPicker(grouplike) {
+  // No-loop shuffle playlist picker - this takes a playlist and randomly
+  // shuffles the order of the items in it, then uses that as an "ordered"
+  // playlist (i.e. it plays all the items in it then stops).
+
+  const flatGroup = flattenGrouplike(grouplike)
+  const items = shuffleArray(flatGroup.items)
+
+  return function() {
+    if (items.length) {
+      return items.splice(0, 1)[0]
     } else {
       return null
     }
   }
 }
 
+function shuffleArray(array) {
+  // Shuffles the items in an array. Super-interesting post on how it works:
+  // https://bost.ocks.org/mike/shuffle/
+
+  const workingArray = array.slice(0)
+
+  let m = array.length
+
+  while (m) {
+    let i = Math.floor(Math.random() * m)
+    m--
+
+    // Stupid lol; avoids the need of a temporary variable!
+    Object.assign(workingArray, {
+      [m]: workingArray[i],
+      [i]: workingArray[m]
+    })
+  }
+
+  return workingArray
+}
+
 module.exports = {
-  makeOrderedPlaylistPicker,
-  makeShufflePlaylistPicker
+  makeLoopingOrderedPlaylistPicker,
+  makeNonLoopingOrderedPlaylistPicker,
+  makeLoopingShufflePlaylistPicker,
+  makeNonLoopingShufflePlaylistPicker,
+
+  byName: {
+    'order':           makeNonLoopingOrderedPlaylistPicker,
+    'ordered':         makeNonLoopingOrderedPlaylistPicker,
+    'order-loop':      makeLoopingOrderedPlaylistPicker,
+    'ordered-loop':    makeLoopingOrderedPlaylistPicker,
+    'order-noloop':    makeNonLoopingOrderedPlaylistPicker,
+    'ordered-noloop':  makeNonLoopingOrderedPlaylistPicker,
+    'order-no-loop':   makeNonLoopingOrderedPlaylistPicker,
+    'ordered-no-loop': makeNonLoopingOrderedPlaylistPicker,
+    'shuffle':         makeLoopingShufflePlaylistPicker,
+    'shuffle-loop':    makeLoopingShufflePlaylistPicker,
+    'shuffle-noloop':  makeNonLoopingShufflePlaylistPicker,
+    'shuffle-no-loop': makeNonLoopingShufflePlaylistPicker,
+  }
 }