Jelajahi Sumber

fix: improve texture disposal logic in useTexture composable

- Added a `disposeTexture` function to safely dispose of textures when they are no longer needed, preventing memory leaks.
- Updated the `useTexture` composable to call `disposeTexture` before loading new textures and during component unmounting.
- Removed the immediate option from the texture watcher in `SimpleTexture.vue` for cleaner logic.
alvarosabu 5 bulan lalu
induk
melakukan
438e214d58

+ 1 - 1
playground/vue/src/pages/composables/useTexture/SimpleTexture.vue

@@ -19,7 +19,7 @@ watch(isLoading, (newVal) => {
 
 watch(texture, (newVal) => {
   console.log('Outside useTexture texture', newVal)
-}, { immediate: true })
+})
 
 /* eslint-enable no-console */
 </script>

+ 21 - 0
src/composables/useTexture/index.ts

@@ -7,6 +7,16 @@ import { onUnmounted, toValue, watch } from 'vue'
  */
 export type TexturePath = string | string[]
 
+/**
+ * Safely disposes of a texture if it exists
+ * @param texture - The texture to dispose
+ */
+function disposeTexture(texture: Texture | null | undefined): void {
+  if (texture) {
+    texture.dispose()
+  }
+}
+
 export function useTexture<T extends MaybeRef<TexturePath>, Shallow extends boolean>(
   path: T,
   {
@@ -51,6 +61,8 @@ export function useTexture<T extends MaybeRef<TexturePath>, Shallow extends bool
   const unsub = watch(() => toValue(path), (newPath) => {
     if (newPath) {
       if (typeof newPath === 'string' && singleResult) {
+        // Dispose of the old texture before loading the new one
+        disposeTexture(singleResult.state.value)
         // Handle single path update
         singleResult.execute(0, newPath)
       }
@@ -58,6 +70,8 @@ export function useTexture<T extends MaybeRef<TexturePath>, Shallow extends bool
         // Handle array of paths update
         newPath.forEach((path, index) => {
           if (arrayResult && index < arrayResult.length) {
+            // Dispose of the old texture before loading the new one
+            disposeTexture(arrayResult[index].state.value)
             arrayResult[index].execute(0, path)
           }
         })
@@ -67,6 +81,13 @@ export function useTexture<T extends MaybeRef<TexturePath>, Shallow extends bool
 
   onUnmounted(() => {
     unsub()
+    // Dispose of all textures on unmount
+    if (singleResult) {
+      disposeTexture(singleResult.state.value)
+    }
+    if (arrayResult) {
+      arrayResult.forEach(result => disposeTexture(result.state.value))
+    }
   })
 
   // Return the appropriate result based on the input type