Is there a way to trigger a store change manually even it's still the same object?

Here is my case:
const adapter = await navigator.gpu.requestAdapter()!
const device = await adapter.requestDevice()!

const Foo = () => {
const [store, setStore] = createStore({
buffer: new Float32Array(10)
})

const gpuBuffer = device.createBuffer({
size: store.buffer.byteLength,
usage: GPUBufferUsage.COPY_DST
})

createEffect(() => {
console.log('buffer changed!', store.buffer)
// sync buffer data change to GPUBuffer
device.queue.writeBuffer(gpuBuffer, 0, store.buffer)
})

// this trigger a update as excepted
// setStore('buffer', v => {
// v[0] = 1
// return new Float32Array(v)
// })

// but I want to avoid buffer recreation for performance reason
setStore('buffer', v => {
v[0] = 1
// maybe somehow I can tell solid-js they are not same here?
return v
})

return null
}
const adapter = await navigator.gpu.requestAdapter()!
const device = await adapter.requestDevice()!

const Foo = () => {
const [store, setStore] = createStore({
buffer: new Float32Array(10)
})

const gpuBuffer = device.createBuffer({
size: store.buffer.byteLength,
usage: GPUBufferUsage.COPY_DST
})

createEffect(() => {
console.log('buffer changed!', store.buffer)
// sync buffer data change to GPUBuffer
device.queue.writeBuffer(gpuBuffer, 0, store.buffer)
})

// this trigger a update as excepted
// setStore('buffer', v => {
// v[0] = 1
// return new Float32Array(v)
// })

// but I want to avoid buffer recreation for performance reason
setStore('buffer', v => {
v[0] = 1
// maybe somehow I can tell solid-js they are not same here?
return v
})

return null
}
5 Replies
mdynnl
mdynnl2w ago
no but you can sort of hijack the store by stuffing getters/setters with signals or memos but that only gives us a signal point of update so anything more complex than that requires you to implement a custom store with proxy in combination with current store or completely replacing depending on your needs of course looking at your example, yeah, a simple custom signal should suffice
TaQuanMinhLong
So what you need is a reactive buffer?
TaQuanMinhLong
Gist
createSharedArrayBuffer
createSharedArrayBuffer. GitHub Gist: instantly share code, notes, and snippets.
Rubick
RubickOP2w ago
Thanks, I think I can just set a Signal<TypedArray> in store like this:
const [store, setStore] = createStore<{ buffer: Signal<Float32Array> }>({
buffer: createSignal(new Float32Array(10), { equals: false })
})

createEffect(() => {
console.log('store buffer change', store.buffer[0]())
})

store.buffer[1](v => {
v[0] = v[0] + 1
return v
})
const [store, setStore] = createStore<{ buffer: Signal<Float32Array> }>({
buffer: createSignal(new Float32Array(10), { equals: false })
})

createEffect(() => {
console.log('store buffer change', store.buffer[0]())
})

store.buffer[1](v => {
v[0] = v[0] + 1
return v
})
mdynnl
mdynnl2w ago
yep that's also an option, if you don't care about setting with store setter api
Want results from more Discord servers?
Add your server