« get me outta code hell

http-music - Command-line music player + utils (not a server!)
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/pickers2.js25
-rw-r--r--todo.txt1
2 files changed, 21 insertions, 5 deletions
diff --git a/src/pickers2.js b/src/pickers2.js
index f1b53eb..f07cd91 100644
--- a/src/pickers2.js
+++ b/src/pickers2.js
@@ -187,6 +187,8 @@ function sortFlattenGrouplike(grouplike, sort, seed) {
   }
 }
 
+const flattenedCache = Symbol('Cache of flattened')
+
 function generalPicker(playlist, lastTrack, options) {
   const { sort, loop } = options
 
@@ -204,11 +206,22 @@ function generalPicker(playlist, lastTrack, options) {
     throw new Error(`Invalid loop mode: ${loop}`)
   }
 
-  const flattened = sortFlattenGrouplike(playlist, sort, options.seed)
-  if (typeof options.seed === 'undefined') {
-    options.seed = flattened.newSeed
+  // Regenerating the flattened list is really time-expensive, so we make sure
+  // to cache the result of the operation (in the 'options' property, which is
+  // used to store "state"-specific data for the picker).
+  let flattened
+  if (options.hasOwnProperty(flattenedCache)) {
+    flattened = options[flattenedCache]
+  } else {
+    flattened = sortFlattenGrouplike(playlist, sort, options.seed)
+
+    if (typeof options.seed === 'undefined') {
+      options.seed = flattened.newSeed
+    }
+    delete flattened.newSeed
+
+    options[flattenedCache] = flattened
   }
-  delete flattened.newSeed
 
   const index = flattened.items.indexOf(lastTrack)
 
@@ -225,9 +238,11 @@ function generalPicker(playlist, lastTrack, options) {
       // Deletes the random number generation seed then starts over. Assigning
       // a new RNG seed makes it so we get a new shuffle the next time, and
       // clearing the lastTrack value makes generalPicker thinks we're
-      // starting over.
+      // starting over. We also need to destroy the flattenedCache, or else it
+      // won't actually recalculate the list.
       const newSeed = seedRandom(options.seed)()
       options.seed = newSeed
+      delete options[flattenedCache]
       return generalPicker(playlist, null, options)
     }
 
diff --git a/todo.txt b/todo.txt
index 5cde299..65c2281 100644
--- a/todo.txt
+++ b/todo.txt
@@ -339,3 +339,4 @@ TODO: Now that we're using seeded randomness, generating the entire timeline
       every time we want to call the picker is definitely really slow. There
       should be some way to make it faster. (Maybe store the playlist on the
       mutable options object?).
+      (Done!)