Skip to content

Commit

Permalink
feat: add composeBindings
Browse files Browse the repository at this point in the history
  • Loading branch information
littensy committed Oct 3, 2023
1 parent 49eb065 commit 50fe67b
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/utils/binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ export interface Lerpable<T> {

export type BindingOrValue<T> = Binding<T> | T;

type Bindable<T = unknown> = Binding<T> | NonNullable<T>;

type ComposeBindings<T extends Bindable[]> = {
[K in keyof T]: T[K] extends Bindable<infer U> ? U : T[K];
};

type BindingCombiner<T extends Bindable[], U> = (...values: ComposeBindings<T>) => U;

/**
* Returns whether the given value is a binding.
* @param value The value to check.
Expand Down Expand Up @@ -129,3 +137,20 @@ export function lerpBinding<T extends number | Lerpable<any>>(
}
});
}

/**
* Composes multiple bindings or values together into a single binding.
* Calls the combiner function with the values of the bindings when any
* of the bindings change.
* @param ...bindings A list of bindings or values.
* @param combiner The function that maps the bindings to a new value.
* @returns A binding that returns the result of the combiner.
*/
export function composeBindings<T extends Bindable[], U>(...bindings: [...T, BindingCombiner<T, U>]): Binding<U>;

export function composeBindings<T>(...values: [...Bindable[], BindingCombiner<Bindable[], T>]): Binding<T> {
const combiner = values.pop() as BindingCombiner<Bindable[], T>;
const bindings = values.map(toBinding);

return joinBindings(bindings).map((bindings) => combiner(...bindings));
}

0 comments on commit 50fe67b

Please sign in to comment.