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

Render mode policies #689

Open
4 tasks done
alvarosabu opened this issue May 23, 2024 · 0 comments
Open
4 tasks done

Render mode policies #689

alvarosabu opened this issue May 23, 2024 · 0 comments
Labels
feature pending-triage Ticket is pending to be prioritised

Comments

@alvarosabu
Copy link
Member

alvarosabu commented May 23, 2024

Description

Via @andretchen0:

About answering the question, "Should the next tick update/render?", we currently have renderMode, manual, etc.

Problem?

The v4 implementation is mostly located in useTresContext, which is already very busy.
<TresCanvas /> currently only accepts 1 string flag from the user. Using only flags means the system relies solely on us predicting users' needs and implementing a "mode" for them.
Accepting only a single flag means we can't have a compound policy, e.g., "rerender if advance or invalidate were called or the window resized. Afaik, this currently leads to cases where manual is the mode – the canvas will be blank if the window is resized, until invalidate is called.

Suggested solution

Encapsulate the logic for "Should the next tick update/render?" in a module – maybe src/core/renderPolicy.ts?
Let the render policy be specified via functions/objects as follows:

import { createRenderPolicy, manual } from '...'
const policy = createRenderPolicy(manual)
const { invalidate } = policy
...
<TresCanvas :render-policy="policy" />

Above,

  • manual is "rule" function that contains its own state, tracking if invalidate() was called since the last update.
  • policy is an object that relays calls to invalidate and advance to its rules, then asks the rules if the next tick should update/render or not.

In this way, we could have compound policies. E.g.,

// NOTE: This policy will approve the next tick of jobs if ...
// - `invalidate()` was called
// - the window was resized
// but cancel if ...
// - the canvas is off-screen
const { shouldUpdate, invalidate } = createRenderPolicy([manual, windowResize, cancelIfOffScreen])
shouldUpdate() // false
invalidate()
shouldUpdate() // true

Rules would be evaluated in FILO order, with the result of lower ranking rules being passed to higher ranking rules, so this ...

createRenderPolicy([manual, cancelIfOffScreen, windowResize])

... cancels true from windowResize if the canvas is offscreen. But if the canvas is off-screen, manual's advance(n) will still take precedence.

Whereas here ...

createRenderPolicy([cancelIfOffScreen, manual, windowResize])

... cancelIfOffScreen takes precedence over the other 2 rules and cancels both if the canvas is off-screen.

Rules are relatively simple to write and users could supply their own rules, if we surface that in the API. Here's a "complicated" rule – windowResize – in its current form:

export const windowResize: CreateUpdateRule = () => {
  let invalidated = true
  const invalidate = () => { invalidated = true }
  window.addEventListener('resize', invalidate)
  return {
    shouldUpdate: (lowRankResult: boolean) => {
      const result = invalidated
      invalidated = false
      return result || lowRankResult
    },
    dispose: () => {
      window.removeEventListener('resize', invalidate)
    }
  }
}

Here's manual:

export const manual: CreateUpdateRule = () => {
  let numFramesToAdvance = 0
  return {
    advance: (numFrames = 1) => {
      numFramesToAdvance = Math.max(numFramesToAdvance, numFrames)
    },
    shouldUpdate: (lowRankResult: boolean) => {
      const result = numFramesToAdvance > 0
      numFramesToAdvance = Math.max(0, numFramesToAdvance - 1)
      return result || lowRankResult
    }
  }
}

Alternative

No response

Additional context

No response

Validations

Edit (andretchen0): fixed formatting

@alvarosabu alvarosabu added feature pending-triage Ticket is pending to be prioritised labels May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature pending-triage Ticket is pending to be prioritised
Projects
Status: No status
Development

No branches or pull requests

1 participant