Open jsbean opened 7 years ago
Just spit-ballin' here:
In order to make this process generic, for more types than just Tempo
over MetricalDuration
, we could do the following?:
[ ] Extract out Easing
:
enum Easing {
case linear
case exponentialIn(exponent: Double)
case exponentialInOut(exponent: Double)
case sineInOut
func evaluate(at: Double) -> Double { ... }
func integrate(at: Double) -> Double { ... }
}
[ ] Refactor Interpolation
as InterpolationProtocol
protocol InterpolationProtocol {
associatedtype XType // naming, constraints?
associatedtype YType // naming, constraints?
let start: YType
let end: YType
let length: XType // naming?
let easing: Easing
// Transform associated types to `Easing`-acceptable values
func position(x: XType) -> Double // naming?
func x(position: Double) -> XType // naming?
func position(y: YType) -> Double // naming?
func y(position: Double) -> YType // naming?
}
[ ] Refactor Tempo.Interpolation
as an implementation of InterpolationProtocol
extension Tempo {
struct Interpolation: InterpolationProtocol {
var duration: Seconds { return position(x: length) }
let start: Tempo
let end: Tempo
let length: MetricalDuration
func concreteOffset(for metricalOffset: MetricalDuration) -> Seconds {
return easing.integrate(at: position(x: metricalOffset))
}
// MARK: - InterpolationProtocol
func position(x: MetricalDuration) -> Double { ... }
func position(y: Tempo) -> Double { ... }
func x(position: Double) -> MetricalDuration { ... }
func y(position: Double) -> Tempo { ... }
}
}
Could be on a completely different planet, but would like to hear your thoughts, @brianlheim.
Or, perhaps the InterpolationProtocol
could be much lighter:
protocol InterpolationProtocol {
let start: YType
let end: YType
let length: XType
func y(for x: XType) -> YType
}
Extract from
Rhythm
, and implement generically. See: dn-m/Rhythm/issues:40.