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

useEventListener bug in controls #457

Open
5 tasks done
alvarosabu opened this issue Jul 24, 2024 · 0 comments
Open
5 tasks done

useEventListener bug in controls #457

alvarosabu opened this issue Jul 24, 2024 · 0 comments
Assignees
Labels
bug Something isn't working p3-minor-bug An edge case that only affects very specific usage (priority)

Comments

@alvarosabu
Copy link
Member

alvarosabu commented Jul 24, 2024

Describe the bug

Some controls have long-standing bugs where changing props causes duplicate events to be added.

E.g., flipping makeDefault in CameraControls causes duplicate events to be added. This will add 100 duplicate events:

const makeDefault = shallowRef(true)
// Flip `makeDefault` 100 times, add 100 events! Lol
Array.from({length: 100}).fill(0).forEach(
  (_, i) => setTimeout(
    () => {
      makeDefault.value = !makeDefault.value
    }, i * 1000 / 25)
)
</script>

<template>
  <TresLeches />
  <TresCanvas v-bind="gl">
    <TresPerspectiveCamera :position="[5, 5, 5]" />
    <CameraControls
      v-bind="controlsState"
      ref="controlsRef"
      :make-default="makeDefault"
      @change="onChange"
      @start="onStart"
      @end="onEnd"
    />
    

That means every time these emits would be expected to fire once, they're fired 100 times:

function addEventListeners() {
  useEventListener(controlsRef.value as any, 'update', () => {
    emit('change', controlsRef.value)
    invalidateOnDemand()
  })
  useEventListener(controlsRef.value as any, 'controlend', () => emit('end', controlsRef.value))
  useEventListener(controlsRef.value as any, 'controlstart', () => emit('start', controlsRef.value))
}

The problem is the anonymous functions:

Note: If a particular anonymous function is in the list of event listeners registered for a certain target, and then later in the code, an identical anonymous function is given in an addEventListener call, the second function will also be added to the list of event listeners for that target.

Indeed, anonymous functions are not identical even if defined using the same unchanging source-code called repeatedly, even if in a loop.

Repeatedly defining the same unnamed function in such cases can be problematic. (See Memory issues, below.)

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
MDN Web Docs
EventTarget: addEventListener() method - Web APIs | MDN
The addEventListener() method of the EventTarget interface
sets up a function that will be called whenever the specified event is delivered to the target.

Reproduction

N/A

Steps to reproduce

No response

System Info

No response

Used Package Manager

npm

Code of Conduct

@alvarosabu alvarosabu added bug Something isn't working p3-minor-bug An edge case that only affects very specific usage (priority) labels Jul 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working p3-minor-bug An edge case that only affects very specific usage (priority)
Projects
Status: No status
Development

No branches or pull requests

2 participants