Переглянути джерело

refactor: 983 refactor usetrescontextprovider to use createinjectionstate (#1042)

* refactor: updated TresCanvas and useTresContextProvider for improved context handling

* fixed comment grammar
Tino Koch 1 тиждень тому
батько
коміт
781d5a3a58

+ 2 - 1
src/components/TresCanvas.vue

@@ -29,6 +29,7 @@ import {
 import pkg from '../../package.json'
 import type { RendererOptions, TresContext } from '../composables'
 import { useTresContextProvider } from '../composables'
+import { INJECTION_KEY as CONTEXT_INJECTION_KEY } from '../composables/useTresContextProvider'
 import { extend } from '../core/catalogue'
 import { nodeOps } from '../core/nodeOps'
 
@@ -114,7 +115,7 @@ const createInternalComponent = (context: TresContext, empty = false) =>
           })
       }
 
-      provide('useTres', context)
+      provide(CONTEXT_INJECTION_KEY, context)
       provide('extend', extend)
 
       if (typeof window !== 'undefined' && ctx?.app) {

+ 1 - 1
src/composables/index.ts

@@ -7,6 +7,6 @@ export * from './useLoop'
 export * from './useRenderer/useRendererManager'
 export * from './useTres'
 
-export * from './useTresContextProvider'
+export { type TresContext, useTresContext, useTresContextProvider } from './useTresContextProvider'
 
 export { UseLoader }

+ 16 - 11
src/composables/useTresContextProvider/index.ts

@@ -2,7 +2,7 @@ import type { MaybeRef, MaybeRefOrGetter, Ref, ShallowRef } from 'vue'
 
 import type { TresControl, TresScene } from '../../types'
 import type { RendererOptions, UseRendererManagerReturn } from '../useRenderer/useRendererManager'
-import { inject, provide, ref, shallowRef } from 'vue'
+import { ref, shallowRef } from 'vue'
 import { extend } from '../../core/catalogue'
 
 import type { UseCameraReturn } from '../useCamera/'
@@ -11,6 +11,7 @@ import { useCameraManager } from '../useCamera'
 import { useRendererManager } from '../useRenderer/useRendererManager'
 import useSizes, { type SizesType } from '../useSizes'
 import { useEventManager } from '../useEventManager'
+import { createInjectionState } from '@vueuse/core'
 
 export interface TresContext {
   scene: ShallowRef<TresScene>
@@ -22,7 +23,9 @@ export interface TresContext {
   events: ReturnType<typeof useEventManager>
 }
 
-export function useTresContextProvider({
+export const INJECTION_KEY = 'useTres' // this is intentionally not a symbol as it can not properly be bridged to the custom renderer
+
+const [useTresContextProvider, _useTresContext] = createInjectionState(({
   scene,
   canvas,
   windowSize,
@@ -32,7 +35,7 @@ export function useTresContextProvider({
   canvas: MaybeRef<HTMLCanvasElement>
   windowSize: MaybeRefOrGetter<boolean>
   rendererOptions: RendererOptions
-}): TresContext {
+}): TresContext => {
   const localScene = shallowRef(scene)
   const sizes = useSizes(windowSize, canvas)
 
@@ -62,22 +65,24 @@ export function useTresContextProvider({
     events,
   }
 
-  provide('useTres', ctx)
-
   // Add context to scene local state
   ctx.scene.value.__tres = {
     root: ctx,
   }
 
   return ctx
-}
+}, {
+  injectionKey: 'useTres',
+})
 
-export function useTresContext(): TresContext {
-  const context = inject<Partial<TresContext>>('useTres')
+const useTresContext = () => {
+  const ctx = _useTresContext()
 
-  if (!context) {
-    throw new Error('useTresContext must be used together with useTresContextProvider')
+  if (!ctx) {
+    throw new Error('useTresContext must be used together with useTresContextProvider.\n You probably tried to use it above or on the same level as a TresCanvas component.\n It should be used in child components of a TresCanvas instance.')
   }
 
-  return context as TresContext
+  return ctx!
 }
+
+export { useTresContext, useTresContextProvider }