Skip to content
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

Introduce Signal Effects #945

Closed
aarthificial opened this issue Feb 8, 2024 · 1 comment · Fixed by #1043
Closed

Introduce Signal Effects #945

aarthificial opened this issue Feb 8, 2024 · 1 comment · Fixed by #1043
Assignees
Labels
a-core Relates to the core package b-enhancement New feature or request c-accepted The issue is ready to be worked on

Comments

@aarthificial
Copy link
Contributor

Description
The value of a signal is calculated only when something requests it by invoking it.
This works great with the current architecture because, during rendering, all signals necessary to display the animation will be invoked and therefore updated. It also automatically skips expensive calculations like matrix propagation (calculating the global matrix of a node) unless something actually needs it.

This approach, however, makes it impossible to "observe" for changes in signals. To do that, one would need to write a loop that accesses the signal in each frame. There should be a built-in, simpler way to achieve this.

Proposed solution
Most UI libraries have a concept of effect that does exactly this. While their signal implementation is usually different than ours (relying on registration rather than laziness), we should be able to replicate a familiar API.
This is when signals in MC are computed:

const radius = createSignal(1);
const area = createSignal(() => {
  console.log('area recalculated!');
  return Math.PI * radius() * radius();
});

area(); // area recalculated!
area();
radius(2);
area(); // area recalculated!
radius(3);
radius(4);
area(); // area recalculated!

And here's how the createEffect function would work:

const radius = createSignal(1);
createEffect(() => {
  // watch for changes to radius
  radius();
  console.log('area recalculated!');
}); // area recalculated!

radius(2); // area recalculated!
radius(3); // area recalculated!
radius(4); // area recalculated!

Additionally it would be useful to have a variant of effect that is deferred until the end of the frame:

const radius = createSignal(1);
createDeferredEffect(() => {
  // watch for changes to radius
  radius();
  console.log('area recalculated!');
}); // area recalculated!

radius(2);
radius(3); 
yield; // area recalculated!
radius(4);
yield; // area recalculated!
@aarthificial aarthificial added b-enhancement New feature or request c-accepted The issue is ready to be worked on a-core Relates to the core package labels Feb 8, 2024
@mancopp

This comment was marked as outdated.

@aarthificial aarthificial self-assigned this Apr 6, 2024
aarthificial added a commit to aarthificial/motion-canvas that referenced this issue May 15, 2024
aarthificial added a commit to aarthificial/motion-canvas that referenced this issue May 15, 2024
aarthificial added a commit to aarthificial/motion-canvas that referenced this issue May 16, 2024
aarthificial added a commit that referenced this issue May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a-core Relates to the core package b-enhancement New feature or request c-accepted The issue is ready to be worked on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants