-
-
Notifications
You must be signed in to change notification settings - Fork 23
Param as record and massively speed up type check #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b488c14
b39600c
18a38d3
2aaa286
8956da3
6960bde
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -6,7 +6,8 @@ | |||||
| [afterglow.show-context :refer [*show* with-show]] | ||||||
| [afterglow.util :as util] | ||||||
| [taoensso.timbre :as timbre]) | ||||||
| (:import [afterglow.rhythm Metronome])) | ||||||
| (:import [afterglow.rhythm Metronome] | ||||||
| [afterglow.effects.params Param])) | ||||||
|
|
||||||
| (defonce | ||||||
| ^{:private true | ||||||
|
|
@@ -63,11 +64,9 @@ | |||||
| :bar (fn [^afterglow.rhythm.MetronomeSnapshot snapshot] (.bar-phase snapshot)) | ||||||
| :phrase (fn [^afterglow.rhythm.MetronomeSnapshot snapshot] (.phrase-phase snapshot))) | ||||||
| ;; Must calculate enhanced phase based on the interval ratio | ||||||
| (case interval | ||||||
| :beat (fn [^afterglow.rhythm.MetronomeSnapshot snapshot] (rhythm/snapshot-beat-phase snapshot interval-ratio)) | ||||||
| :bar (fn [^afterglow.rhythm.MetronomeSnapshot snapshot] (rhythm/snapshot-bar-phase snapshot interval-ratio)) | ||||||
| :phrase (fn [^afterglow.rhythm.MetronomeSnapshot snapshot] | ||||||
| (rhythm/snapshot-phrase-phase snapshot interval-ratio))))) | ||||||
| (let [fm {:beat rhythm/snapshot-beat-phase :bar rhythm/snapshot-bar-phase :phrase rhythm/snapshot-phrase-phase}] | ||||||
| (fn [^afterglow.rhythm.MetronomeSnapshot snapshot] | ||||||
| ((interval fm) snapshot interval-ratio))))) | ||||||
|
|
||||||
| (defn- build-adjusted-phase-fn | ||||||
| "Constructs the function which uses the oscillator phase function to | ||||||
|
|
@@ -99,21 +98,19 @@ | |||||
| [shape-fn interval interval-ratio phase] | ||||||
| (reify IOscillator | ||||||
| (evaluate [this show snapshot head] | ||||||
| (let [interval (params/resolve-param interval show snapshot head) | ||||||
| interval-ratio (params/resolve-param interval-ratio show snapshot head) | ||||||
| phase (params/resolve-param phase show snapshot head) | ||||||
| (let [[interval interval-ratio phase] | ||||||
| (map #(params/resolve-param % show snapshot head) [interval interval-ratio phase]) | ||||||
| base-phase-fn (build-base-phase-fn interval interval-ratio) | ||||||
| adjusted-phase-fn (build-adjusted-phase-fn base-phase-fn phase)] | ||||||
| (shape-fn (adjusted-phase-fn snapshot)))) | ||||||
| (resolve-non-frame-dynamic-elements [this show snapshot head] | ||||||
| (if (not-any? params/frame-dynamic-param? [interval interval-ratio phase]) | ||||||
| ;; Can now resolve and optimize | ||||||
| (let [interval (params/resolve-param interval show snapshot head) | ||||||
| interval-ratio (params/resolve-param interval-ratio show snapshot head) | ||||||
| phase (params/resolve-param phase show snapshot head)] | ||||||
| (fixed-oscillator shape-fn interval interval-ratio phase)) | ||||||
| (apply fixed-oscillator shape-fn | ||||||
| (map #(params/resolve-param % show snapshot head) | ||||||
| [interval interval-ratio phase]))) | ||||||
| ;; Can't optimize, there is at least one frame-dynamic parameter, so return self | ||||||
| this)))) | ||||||
| this))) | ||||||
|
|
||||||
| (defn- variable-oscillator | ||||||
| "Build an oscillator whose shape function relies on dynamic | ||||||
|
|
@@ -133,10 +130,9 @@ | |||||
| (if (ifn? shape-fn) ; The function simplified and no longer depends on dynamic parameters; we can optimize | ||||||
| (if (not-any? params/frame-dynamic-param? [interval interval-ratio phase]) | ||||||
| ;; No parameters are frame-dynamic, can resolve and optimize all the way to a fixed oscillator | ||||||
| (let [interval (params/resolve-param interval show snapshot head) | ||||||
| interval-ratio (params/resolve-param interval-ratio show snapshot head) | ||||||
| phase (params/resolve-param phase show snapshot head)] | ||||||
| (fixed-oscillator shape-fn interval interval-ratio phase)) | ||||||
| (apply fixed-oscillator shape-fn | ||||||
| (map #(params/resolve-param % show snapshot head) | ||||||
| [interval interval-ratio phase])) | ||||||
| ;; Can't fully optimize, there is at least one frame-dynamic parameter, so return a simple oscillator | ||||||
| (simple-oscillator shape-fn interval interval-ratio phase)) | ||||||
| ;; Can't optimize at all, shape-fn is frame-dynamic, so return self | ||||||
|
|
@@ -377,59 +373,27 @@ | |||||
| stuck at the value you gave with `:min`." | ||||||
| [osc & {:keys [min max metronome frame-dynamic] :or {min 0 max 255 frame-dynamic true}}] | ||||||
| {:pre [(some? *show*) (satisfies? IOscillator osc)]} | ||||||
| (let [min (params/bind-keyword-param min Number 0) | ||||||
| max (params/bind-keyword-param max Number 255) | ||||||
| metronome (params/bind-keyword-param metronome Metronome (:metronome *show*))] | ||||||
| (if (not-any? params/param? [min max metronome]) | ||||||
| ;; Optimize the simple case of all constant parameters | ||||||
| (let [max (clojure.core/max min max) ; Handle case where min > max | ||||||
| range (- max min) | ||||||
| dyn (boolean frame-dynamic) | ||||||
| eval-fn (if (some? metronome) | ||||||
| (let [[min max] (map #(params/bind-keyword-param %1 Number %2) [min max] [0 255]) | ||||||
| metronome (params/bind-keyword-param metronome Metronome (:metronome *show*)) | ||||||
| presolve-fn (fn [show snapshot head] | ||||||
| (with-show show | ||||||
| (let [[min max metronome] (map #(params/resolve-unless-frame-dynamic % show snapshot head) [min max metronome]) | ||||||
| osc (resolve-non-frame-dynamic-elements osc show snapshot head)] | ||||||
| (build-oscillated-param osc :min min :max max :metronome metronome :frame-dynamic frame-dynamic)))) | ||||||
| eval-fn (if (not-any? params/param? [min max metronome]) ;; Optimize the simple case of all constant parameters | ||||||
| (let [max (clojure.core/max min max) ; Handle case where min > max | ||||||
| range (- max min)] | ||||||
| (if (some? metronome) ;uh if none are params how could it be a metronome? | ||||||
|
||||||
| (if (some? metronome) ;uh if none are params how could it be a metronome? | |
| (if (some? metronome) ; metronome may still be a constant Metronome value even when none are Params |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The refactored code will throw a less descriptive NullPointerException if
intervalis a keyword other than:beat,:bar, or:phrase. The oldcasestatement would have thrown a clearer error. Consider adding error handling or validation to provide a better error message when an invalid interval keyword is used.