Browse Source

Merge branch 'feature/25-extend-catalog-in-cientos' into feature/15-text3d-cientos

Alvaro 2 years ago
parent
commit
65b2c1c4b5

+ 6 - 6
packages/cientos/src/core/useCientos.ts

@@ -1,12 +1,12 @@
-import { useCatalogue } from '@tresjs/core'
-import { getCurrentInstance } from 'vue'
+import { inject } from 'vue'
 
 
 export function useCientos() {
 export function useCientos() {
-  const appContext = getCurrentInstance()?.appContext
-  const { catalogue, extend } = useCatalogue(appContext?.app)
-
+  const extend =
+    inject<(objects: any) => void>('extend') ||
+    (() => {
+      console.warn('No extend function provided')
+    })
   return {
   return {
-    catalogue,
     extend,
     extend,
   }
   }
 }
 }

+ 3 - 5
packages/tres/src/core/useCatalogue/index.ts

@@ -1,10 +1,10 @@
-import { App, ref, Component, Ref, provide } from 'vue'
+import { App, ref, Component, Ref } from 'vue'
 import * as THREE from 'three'
 import * as THREE from 'three'
 import { useInstanceCreator } from '/@/core'
 import { useInstanceCreator } from '/@/core'
 import { useLogger } from '/@/composables'
 import { useLogger } from '/@/composables'
 import { TresCatalogue } from '/@/types'
 import { TresCatalogue } from '/@/types'
 
 
-const catalogue: Ref<TresCatalogue> = ref({ ...THREE })
+const catalogue: Ref<TresCatalogue> = ref({ ...THREE, uuid: THREE.MathUtils.generateUUID() })
 
 
 delete catalogue.value.Scene
 delete catalogue.value.Scene
 
 
@@ -16,16 +16,14 @@ export function useCatalogue(app?: App, prefix = 'Tres') {
   }
   }
   const { createComponentInstances } = useInstanceCreator(prefix)
   const { createComponentInstances } = useInstanceCreator(prefix)
 
 
-  provide('catalogue', catalogue)
-
   const extend = (objects: any) => {
   const extend = (objects: any) => {
     if (!objects) {
     if (!objects) {
       logError('No objects provided to extend catalogue')
       logError('No objects provided to extend catalogue')
       return
       return
     }
     }
-    logMessage('Adding objects to catalogue', objects)
     catalogue.value = Object.assign(catalogue.value, objects)
     catalogue.value = Object.assign(catalogue.value, objects)
     const components = createComponentInstances(ref(objects))
     const components = createComponentInstances(ref(objects))
+    logMessage('Adding objects to catalogue', { objects, catalogue: catalogue.value.uuid })
 
 
     if (localApp) {
     if (localApp) {
       components.forEach(([key, cmp]) => {
       components.forEach(([key, cmp]) => {

+ 40 - 29
packages/tres/src/core/useInstanceCreator/index.ts

@@ -1,7 +1,7 @@
 /* eslint-disable new-cap */
 /* eslint-disable new-cap */
 /* eslint-disable @typescript-eslint/no-empty-function */
 /* eslint-disable @typescript-eslint/no-empty-function */
-import { OrthographicCamera, PerspectiveCamera } from 'three'
-import { defineComponent, Ref } from 'vue'
+import { OrthographicCamera, PerspectiveCamera, Scene } from 'three'
+import { defineComponent, inject, Ref } from 'vue'
 import { isArray, isDefined, isFunction } from '@alvarosabu/utils'
 import { isArray, isDefined, isFunction } from '@alvarosabu/utils'
 import { normalizeVectorFlexibleParam } from '/@/utils/normalize'
 import { normalizeVectorFlexibleParam } from '/@/utils/normalize'
 import { useCamera, useScene } from '/@/core/'
 import { useCamera, useScene } from '/@/core/'
@@ -59,34 +59,41 @@ export function useInstanceCreator(prefix: string) {
     })
     })
   }
   }
 
 
-  function createInstanceFromVNode(vnode: TresVNode, catalogue: Ref<TresCatalogue>): TresInstance {
-    const vNodeType = ((vnode.type as TresVNodeType).name as string).replace(prefix, '')
-
-    // check if args prop is defined on the vnode
-    let internalInstance
-    if (vnode?.props?.args) {
-      // if args prop is defined, create new instance of catalogue[vNodeType] with the provided arguments
-      internalInstance = new catalogue.value[vNodeType](...vnode.props.args)
+  function createInstanceFromVNode(vnode: TresVNode): TresInstance | TresInstance[] {
+    const regex = /^Symbol\(Fragment\)$/g
+    // Check if the vnode is a Fragment
+    if (regex.test(vnode.type.toString())) {
+      return vnode.children.map(child => createInstanceFromVNode(child as TresVNode)) as TresInstance[]
     } else {
     } else {
-      // if args prop is not defined, create a new instance of catalogue[vNodeType] without arguments
-      internalInstance = new catalogue.value[vNodeType]()
-    }
+      const vNodeType = ((vnode.type as TresVNodeType).name as string).replace(prefix, '')
+      const catalogue = inject<Ref<TresCatalogue>>('catalogue')
+      // check if args prop is defined on the vnode
+      let internalInstance
+      if (catalogue) {
+        if (vnode?.props?.args) {
+          // if args prop is defined, create new instance of catalogue[vNodeType] with the provided arguments
+          if (catalogue?.value[vNodeType]) {
+            internalInstance = new catalogue.value[vNodeType](...vnode.props.args)
+          } else {
+            logError(`There is no ${vNodeType} in the catalogue`, catalogue?.value.uuid)
+          }
+        } else {
+          // if args prop is not defined, create a new instance of catalogue[vNodeType] without arguments
+          internalInstance = new catalogue.value[vNodeType]()
+        }
+      }
 
 
-    // check if props is defined on the vnode
-    if (vnode?.props) {
-      // if props is defined, process the props and pass the internalInstance to update its properties
-      processProps(vnode.props, internalInstance)
-    }
+      // check if props is defined on the vnode
+      if (vnode?.props) {
+        // if props is defined, process the props and pass the internalInstance to update its properties
+        processProps(vnode.props, internalInstance)
+      }
 
 
-    return internalInstance
+      return internalInstance
+    }
   }
   }
 
 
-  function createInstance(
-    catalogue: Ref<TresCatalogue>,
-    threeObj: any,
-    attrs: TresAttributes,
-    slots: Record<string, any>,
-  ): TresInstance {
+  function createInstance(threeObj: any, attrs: TresAttributes, slots: Record<string, any>): TresInstance {
     /*
     /*
      * Checks if the component has slots,
      * Checks if the component has slots,
      * if it does, it will create a new Object3D instance passing the slots instances as properties
      * if it does, it will create a new Object3D instance passing the slots instances as properties
@@ -99,8 +106,8 @@ export function useInstanceCreator(prefix: string) {
      * const mesh = new Mesh(new BoxGeometry(), new MeshBasicMaterial())
      * const mesh = new Mesh(new BoxGeometry(), new MeshBasicMaterial())
      */
      */
     if (slots.default && slots?.default()) {
     if (slots.default && slots?.default()) {
-      const internal = slots.default().map((vnode: TresVNode) => createInstanceFromVNode(vnode, catalogue))
-      return new threeObj(...internal)
+      const internal = slots.default().map((vnode: TresVNode) => createInstanceFromVNode(vnode))
+      return new threeObj(...internal.flat())
     } else {
     } else {
       // Creates a new THREE instance, if args is present, spread it on the constructor
       // Creates a new THREE instance, if args is present, spread it on the constructor
       return attrs.args ? new threeObj(...attrs.args) : new threeObj()
       return attrs.args ? new threeObj(...attrs.args) : new threeObj()
@@ -115,10 +122,12 @@ export function useInstanceCreator(prefix: string) {
         const cmp = defineComponent({
         const cmp = defineComponent({
           name,
           name,
           setup(props, { slots, attrs, ...ctx }) {
           setup(props, { slots, attrs, ...ctx }) {
-            const { scene } = useScene()
+            const { scene: fallback } = useScene()
+            const scene = inject<Ref<Scene>>('local-scene') || fallback
+            const catalogue = inject<Ref<TresCatalogue>>('catalogue')
             const { pushCamera } = useCamera()
             const { pushCamera } = useCamera()
 
 
-            const instance = createInstance(catalogue, threeObj, attrs, slots)
+            const instance = createInstance(threeObj, attrs, slots)
             processProps(attrs, instance)
             processProps(attrs, instance)
             // If the instance is a camera, push it to the camera stack
             // If the instance is a camera, push it to the camera stack
             if (instance instanceof PerspectiveCamera || instance instanceof OrthographicCamera) {
             if (instance instanceof PerspectiveCamera || instance instanceof OrthographicCamera) {
@@ -132,6 +141,8 @@ export function useInstanceCreator(prefix: string) {
 
 
             ctx.expose(instance)
             ctx.expose(instance)
             logMessage(name, {
             logMessage(name, {
+              sceneuuid: scene?.value.uuid,
+              catalogue: catalogue?.value.uuid,
               props,
               props,
               slots,
               slots,
               attrs,
               attrs,

+ 3 - 1
packages/tres/src/index.ts

@@ -19,7 +19,9 @@ const plugin: TresPlugin = {
     const prefix = options?.prefix || 'Tres'
     const prefix = options?.prefix || 'Tres'
     app.component(`${prefix}Canvas`, TresCanvas)
     app.component(`${prefix}Canvas`, TresCanvas)
     app.component(`${prefix}Scene`, Scene)
     app.component(`${prefix}Scene`, Scene)
-    const { catalogue } = useCatalogue(app, prefix)
+    const { catalogue, extend } = useCatalogue(app, prefix)
+    app.provide('catalogue', catalogue)
+    app.provide('extend', extend)
     const { createComponentInstances } = useInstanceCreator(prefix)
     const { createComponentInstances } = useInstanceCreator(prefix)
     const components = createComponentInstances(catalogue)
     const components = createComponentInstances(catalogue)
     /*  const components = createComponentInstances(
     /*  const components = createComponentInstances(