1.0.10 • Published 5 years ago

rebylon v1.0.10

Weekly downloads
44
License
-
Repository
-
Last release
5 years ago

Rebylon

Reactive programming library designed to use with BabylonJS

Effects

// Effect is just a function withouth arguments
const e1: Effect = () => console.log("test");
const e2: Effect = noop; // Do nothing

// Combine effects. In this case `composeEffects` will return e1, because e2 is noop
const e3: Effect = composeEffects(e1, e2);

Parameters

// Parameter declaration
const a: Param<number> = 5; // constant parameter
const b: Param<string> = () => Date.now().toFixed(); // variable parameter

// Parameters mapping
const c: Param<[number, string]> = map(a, b)((a: number, b: string) => {
    return [a * 5, b + "_mapped"];
});

// React on parameters change.
// Parameters modification will be checked on each `update` call
const update: Effect = changes(a, b)((a: number, b: string) => {
    console.log("Current parameters:", a, b);
});

// React on parameters change with some disposable state
const disposable: Component = stream(a, b)((a, b) => {
    if (a % 2) {
        const timeout = setTimeout(doSomething, 1000);
        return () => clearTimeout(timeout);
    }
});

// Write some parameters to object fields
const updateFields: Effect = write(myObject, {
    count: a,
    caption: b,
});

Components

Component is just an object with update and dispose effects. Minimal component is { update: noop, dispose: noop }.

// Some component pseudocode
function exampleComponent(scene, { color, position }: { position: Param<number>, color: Param<Color3> }): Component {
    const sphere = scene.createSphere(1);
    const update = write(sphere, { color, position });
    return {
        update: update,
        dispose: () => sphere.dispose(),
    };
}

// Optionaly append component to the scene
const visible: Param<boolean> = () => !(Date.now() % 2);
const optinalComponent: Component = optional(visible, () => {
    return exampleComponent(scene, { color: someColor, position: somePosition });
}); // component will be created/disposed depending on the `visible` flag

// Combine few components to one
const combined: Component = group(component1, component2, component3);

// Create a list of components
const someList: Param<number[]> = () => [1, 2, 3];
const many: Component = list(
    someList, // array parameter
    (value: number) => value, // key computation function (similar to React's key attribute)
    (value: Param<number>) => createMyComponent(scene, value) // function to create a component from the list item
);

// Cache havy calculations or parametrs that can change during updating
const time: Param<number> = () => Date.now();
const items: Param<number[]> = () => range(0, Date.now() % 100);
const cached: Component = cache(time, items)((time, items) => {
    return createMyComponent(
        scene, {
            // cached parameter time won't change during updating of my component and it's children
            time: time,
            // `items` parameter can be used multiple times without performance issues
            size: map(items)(items => items.length * 10),
            values: items
        },
    );
});

Component hooks

If you need to do something before/after update/dispose component, there are some hook functions. You can use beforeUpdate, afterUpdate, beforeDispose, and afterDispose functions.

const componentWithHook = beforeUpdate(createMyComponent(), () => {
    console.log("It runs before update");
})

Stateful components

const statefulComponent = state(0, (counter, setCounter) => {
    return // Return your component with state here
})

Animations

// Animated component example
interface AnimatedComponentProps {
    time: Param<number>;
    position: Param<"left" | "right">;
}

function animatedComponent(scene, { time, position }: AnimatedComponentProps): Component {
    const x: Param<number> = map(position)(p => p === "left" ? -1 : 1);
    const animatedX: Param<number> = numberTransition({
        time: time,
        value: x,
        duration: 300,
    });

    return createMyComponent(scene, {
        position: map(animatedX)(x => new Vector3(x, 0, 0)),
    });
}

// Create custom transition
export const vector3Transition = createTransition<Vector3>({
    equals: (a: Vector3, b: Vector3) => a.equals(b), // objects compare function
    mix: (a: Vector3, b: Vector3, t: number) => a.scale(1 - t).add(b.scale(t)), // objects mix function
});
1.0.10

5 years ago

1.0.9

5 years ago

1.0.8

5 years ago

1.0.7

5 years ago

1.0.6

5 years ago

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago