   (add-midi-control-metronome-mapping midi-device-name channel control-number metronome
                                       #(rhythm/metro-phrase-start % (rhythm/metro-phrase %))))
 
+(defn find-effect-internal
+  "Looks up the specified effect keyword in list of active effects.
+  Returns a map of the effect metadata, with the effect itself under
+  the key `:effect`. If the effect is in the process of ending, the
+  keyword `:ending` will have a `true` value."
+  {:doc/format :markdown}
+  [key show]
+  {:pre [(some? show) (some? key)]}
+  (when-let [index (get (:indices @(:active-effects *show*)) (keyword key))]
+    (assoc (get (:meta @(:active-effects *show*)) index)
+           :effect (get (:effects @(:active-effects *show*)) index)
+           :ending ((:ending @(:active-effects *show*)) (keyword key)))))
+
+(defn find-effect
+  "Looks up the specified effect keyword in list of active effects
+  for [[*show*]]. Returns a map of the effect metadata, with the
+  effect itself under the key `:effect`. If the effect is in the
+  process of ending, the keyword `:ending` will have a `true` value."
+  {:doc/format :markdown}
+  [key]
+  (find-effect-internal key *show*))
+
+(defn- warn-ending-effect
+  "If an effect is about to be removed from the set of active effects,
+  make sure that its end function has been called, in case it needs to
+  do any cleanup beyond simply being garbage collected."
+  [key show]
+  (let [found (find-effect-internal key show)
+        effect (:effect found)]
+    (when (and found (not (:ending found)))
+      (fx/end effect show (rhythm/metro-snapshot (:metronome show))))))
+
 (defn- vec-remove
   "Remove the element at the specified index from the collection."
   [coll pos]

  "Helper function which adds an effect with a specified key and priority to the priority
  list structure maintained for the show, replacing any existing effect with the same key.
  Tracks the effect instance id, cue-grid source, and variable binding map as metadata."
  [fns key f priority id from-cue x y var-map]
  (let [base (remove-effect-internal fns key)
        index (find-insertion-index (:meta base) priority)]
    {:effects (vec-insert (:effects base) index f)
     :indices (insert-key (:indices base) key index)

(defn- remove-effect-internal
  "Helper function which removes the effect with the specified key
  from the priority list structure maintained for the show."
  [active-effects key]
  (if-let [index (get (:indices active-effects) key)]
    {:effects (vec-remove (:effects active-effects) index)
     :indices (remove-key (:indices active-effects) key index)
     :meta (vec-remove (:meta active-effects) index)
     :ending (disj (:ending active-effects) key)}
    active-effects))

(defn- find-insertion-index
  "Determines where in the priority list an effect with the specified
