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

Reactivity: Support for TypedArrays #802

Closed
filonik opened this issue Mar 5, 2020 · 4 comments
Closed

Reactivity: Support for TypedArrays #802

filonik opened this issue Mar 5, 2020 · 4 comments
Labels

Comments

@filonik
Copy link

filonik commented Mar 5, 2020

What problem does this feature solve?

Currently the set of "Observable Types" is limited to: Object, Array, Map, Set, WeakMap, WeakSet.

This feature would extend the set of "Observable Types" to include TypedArrays:

Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, Uint32Array, Uint8ClampedArray, Float32Array, Float64Array

These types are common in low-level APIs, such as WebGL. They are standard built-in objects, so it would be nice if they would work with Vue out of the box. The Proxy-based approach to reactivity makes it feasible to support them.

The feature would treat these types just like plain Arrays, simplifying usage and reducing potential problems due to unexpected behavior (lack of reactivity). For instance, I encountered the lack of reactivity when trying to write a Vue component to interactively edit WebGL shader uniforms.

The problem has been reported in the past, however I believe that it is worth revisiting with the new Proxy-based approach to reactivity.

What does the proposed API look like?

The API remains unchanged, the feature just expands the set of "Observable Types", enabling the following code to work as expected:

<template>
  <h1>Arrays</h1>
  <p>Index: <input type="text" v-model="index"></p>
  <p>Plain Array: {{ plainArr }}</p>
  <p>Change element #{{index}} <input type="text" v-model="plainArr[index]"></p>
  <p>Typed Array: {{ typedArr }}</p>
  <p>Change element #{{index}} <input type="text" v-model="typedArr[index]"></p>
</template>

<script>
import { reactive, toRefs } from 'vue'

export default {
  setup() {
    const state = reactive({
      index: 0,
      plainArr: [0,1,2],
      typedArr: new Float32Array([0,1,2]),
    })
    return toRefs(state);
  }
}
</script>

<style scoped>
h1 {
  font-family: Arial, Helvetica, sans-serif;
}
</style>

Edit: Sandbox example of current behaviour.

@filonik
Copy link
Author

filonik commented Mar 7, 2020

I just want to add that I have a "working" proof-of-concept implementation, but due to my lack of familiarity with the internals of Vue, I am not confident enough to create a pull request. However, I am more than happy to share the details if there is interest.

Essentially, it boils down to one change, adding TypedArrays in reactive.ts:

const isObservableType = /*#__PURE__*/ makeMap(
  'Object,Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint16Array,Uint32Array,Uint8ClampedArray,Float32Array,Float64Array,Map,Set,WeakMap,WeakSet'
)

Unfortunately, due to reasons I do not fully understand, by itself this causes some exceptions. My best explanation is that built-in TypedArray methods are incorrectly being called on a Proxy. Therefore, to make it work, I had to create some additional arrayInstrumentations in baseHandlers.ts. However, I am not sure whether this is the best approach.

himself65 added a commit to himself65/vue-next that referenced this issue Apr 19, 2020
@himself65
Copy link
Contributor

And I think this issue won't fix. See #991 (comment)

@filonik
Copy link
Author

filonik commented Apr 29, 2020

@himself65 Thank you for taking a stab at it nonetheless. It seems like supporting this feature is more of a philosophical/design decision, rather than a technical issue.

I do wonder if there might be a mechanism to implement this functionality while avoiding some of the costs/penalties that were mentioned. Also, I do not think the fact that TypedArrays are typically used in performance-sensitive scenarios necessarily means that there aren't scenarios in which it would be useful to observe them (e.g. think of a web-based visual editor for 3d content).

Still, I respect @yyx990803 position, and I am happy to go along with it, provided that the suggested workaround works and is well documented.

@LinusBorg
Copy link
Member

Judging from the convo in the PR, this issue can be closed.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants