From d61df0597965e708581d1b32eafa2f14866bf9b4 Mon Sep 17 00:00:00 2001 From: Alvaro Saburido Date: Tue, 12 Dec 2023 16:50:19 +0100 Subject: [PATCH] feat: enable devtools (#465) * feat: devtools hook on window object * chore: release v3.6.0-next.0 --- CHANGELOG.md | 8 + docs/package.json | 6 +- package.json | 2 +- playground/package.json | 1 + playground/vite.config.ts | 2 + pnpm-lock.yaml | 380 +++++++++++++++++- .../useTresContextProvider/index.ts | 98 ++++- src/env.d.ts | 7 + src/utils/perf.ts | 34 ++ 9 files changed, 526 insertions(+), 12 deletions(-) create mode 100644 src/utils/perf.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index c0506ea17..f2ecfcb50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ +## [3.6.0-next.0](https://github.com/Tresjs/tres/compare/3.5.1...3.6.0-next.0) (2023-12-06) + + +### Features + +* devtools hook on window object ([df96c1f](https://github.com/Tresjs/tres/commit/df96c1f31aafe1b73cd344fde39420c1ae443d47)) + + ## [3.5.2](https://github.com/Tresjs/tres/compare/3.5.1...3.5.2) (2023-12-12) diff --git a/docs/package.json b/docs/package.json index ebe5d7bd1..097a757d5 100644 --- a/docs/package.json +++ b/docs/package.json @@ -8,11 +8,11 @@ "build": "vitepress build", "preview": "vitepress preview" }, - "dependencies": { - "@tresjs/core": "workspace:^3.1.1" - }, "devDependencies": { "unocss": "^0.58.0", "vite-svg-loader": "^5.1.0" + }, + "dependencies": { + "@tresjs/core": "workspace:3.6.0-next.0" } } diff --git a/package.json b/package.json index b055df6df..0542d0037 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@tresjs/core", "type": "module", - "version": "3.5.2", + "version": "3.6.0-next.0", "packageManager": "pnpm@8.10.2", "description": "Declarative ThreeJS using Vue Components", "author": "Alvaro Saburido (https://github.com/alvarosabu/)", diff --git a/playground/package.json b/playground/package.json index fd3abc902..2d29c1920 100644 --- a/playground/package.json +++ b/playground/package.json @@ -15,6 +15,7 @@ "devDependencies": { "@tresjs/leches": "0.15.0-next.3", "@tweakpane/plugin-essentials": "^0.2.0", + "vite-plugin-vue-devtools": "1.0.0-rc.6", "unplugin-auto-import": "^0.17.2", "vite-plugin-glsl": "^1.2.1", "vite-plugin-qrcode": "^0.2.3", diff --git a/playground/vite.config.ts b/playground/vite.config.ts index 0fd985568..17076bef5 100644 --- a/playground/vite.config.ts +++ b/playground/vite.config.ts @@ -7,11 +7,13 @@ import glsl from 'vite-plugin-glsl' import UnoCSS from 'unocss/vite' import { templateCompilerOptions } from '@tresjs/core' import { qrcode } from 'vite-plugin-qrcode' +import VueDevTools from 'vite-plugin-vue-devtools' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ glsl(), + VueDevTools(), vue({ script: { propsDestructure: true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3ec450022..205fc5712 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,7 +23,7 @@ importers: version: 1.9.0 '@tresjs/cientos': specifier: 3.6.0 - version: 3.6.0(@tresjs/core@)(three@0.159.0)(tweakpane@4.0.1)(vue@3.3.11) + version: 3.6.0(@tresjs/core@3.5.1)(three@0.159.0)(tweakpane@4.0.1)(vue@3.3.11) '@tresjs/eslint-config-vue': specifier: ^0.2.1 version: 0.2.1(@typescript-eslint/eslint-plugin@6.14.0)(eslint@8.55.0)(typescript@5.3.3) @@ -130,7 +130,7 @@ importers: docs: dependencies: '@tresjs/core': - specifier: workspace:^3.1.1 + specifier: workspace:3.6.0-next.0 version: link:.. devDependencies: unocss: @@ -144,7 +144,7 @@ importers: dependencies: '@tresjs/cientos': specifier: 3.6.0 - version: 3.6.0(@tresjs/core@)(three@0.159.0)(tweakpane@4.0.1)(vue@3.3.11) + version: 3.6.0(@tresjs/core@3.5.1)(three@0.159.0)(tweakpane@4.0.1)(vue@3.3.11) vue-router: specifier: ^4.2.5 version: 4.2.5(vue@3.3.11) @@ -164,6 +164,9 @@ importers: vite-plugin-qrcode: specifier: ^0.2.3 version: 0.2.3(vite@5.0.8) + vite-plugin-vue-devtools: + specifier: 1.0.0-rc.6 + version: 1.0.0-rc.6(pug@3.0.2)(vite@5.0.8) vue-tsc: specifier: ^1.8.25 version: 1.8.25(typescript@5.3.3) @@ -641,6 +644,50 @@ packages: dependencies: '@babel/types': 7.23.6 + /@babel/plugin-proposal-decorators@7.23.6(@babel/core@7.23.6): + resolution: {integrity: sha512-D7Ccq9LfkBFnow3azZGJvZYgcfeqAw3I1e5LoTpj6UKIFQilh8yqXsIGcRIqbBdsPWIz+Ze7ZZfggSj62Qp+Fg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.6 + '@babel/helper-create-class-features-plugin': 7.23.6(@babel/core@7.23.6) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.6) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.23.6) + dev: true + + /@babel/plugin-syntax-decorators@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.6): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.6): resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} engines: {node: '>=6.9.0'} @@ -1765,7 +1812,7 @@ packages: resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} dev: true - /@tresjs/cientos@3.6.0(@tresjs/core@)(three@0.159.0)(tweakpane@4.0.1)(vue@3.3.11): + /@tresjs/cientos@3.6.0(@tresjs/core@3.5.1)(three@0.159.0)(tweakpane@4.0.1)(vue@3.3.11): resolution: {integrity: sha512-VM6LamAFlcKufbrtbYN71ncuAw2JPVfKUC6Ey9+scq05qvHdQM8fU0WoppNZEtmIL7m2aUqroOZRnr9LXyZPCg==} peerDependencies: '@tresjs/core': '>=3.2' @@ -1773,7 +1820,7 @@ packages: tweakpane: '>=3.0.0' vue: '>=3.3' dependencies: - '@tresjs/core': 'link:' + '@tresjs/core': 3.5.1(three@0.159.0)(vue@3.3.11) '@vueuse/core': 10.7.0(vue@3.3.11) camera-controls: 2.7.3(three@0.159.0) stats-gl: 1.0.7 @@ -1800,7 +1847,6 @@ packages: vue: 3.3.11(typescript@5.3.3) transitivePeerDependencies: - '@vue/composition-api' - dev: true /@tresjs/eslint-config-base@0.2.1(@typescript-eslint/eslint-plugin@6.14.0)(@typescript-eslint/parser@6.14.0)(eslint@8.55.0): resolution: {integrity: sha512-9fkwDaNu4nLKujeERi5d1S7+ZdZpxBE+g/jUbM4ywhn/+5P7Qv8dXlo1vB05LteX5cTBnZxHQTFrJGK+sMcFdg==} @@ -2388,6 +2434,19 @@ packages: - rollup dev: true + /@vite-plugin-vue-devtools/core@1.0.0-rc.6(vite@5.0.8): + resolution: {integrity: sha512-9A7BEvW6tPgLJK+bRyjWCMcXs/mWAdyrcSH1hNr+b7d5lEWoyBrm9d8s0UGEXLnRoJAfHhrAx525wMUGZI1QNA==} + peerDependencies: + vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 + dependencies: + '@babel/parser': 7.23.6 + birpc: 0.2.14 + estree-walker: 2.0.2 + magic-string: 0.30.5 + vite: 5.0.8 + vite-hot-client: 0.2.3(vite@5.0.8) + dev: true + /@vitejs/plugin-vue@4.5.2(vite@5.0.8)(vue@3.3.11): resolution: {integrity: sha512-UGR3DlzLi/SaVBPX0cnSyE37vqxU3O6chn8l0HJNzQzDia6/Au2A4xKv+iIJW8w2daf80G7TYHhi1pAUjdZ0bQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -2485,6 +2544,29 @@ packages: path-browserify: 1.0.1 dev: true + /@vue/babel-helper-vue-transform-on@1.1.5: + resolution: {integrity: sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==} + dev: true + + /@vue/babel-plugin-jsx@1.1.5(@babel/core@7.23.6): + resolution: {integrity: sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.6 + '@babel/helper-module-imports': 7.22.15 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.6) + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.6 + '@babel/types': 7.23.6 + '@vue/babel-helper-vue-transform-on': 1.1.5 + camelcase: 6.3.0 + html-tags: 3.3.1 + svg-tags: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /@vue/compiler-core@3.3.11: resolution: {integrity: sha512-h97/TGWBilnLuRaj58sxNrsUU66fwdRKLOLQ9N/5iNDfp+DZhYH9Obhe0bXxhedl8fjAgpRANpiZfbgWyruQ0w==} dependencies: @@ -2728,6 +2810,21 @@ packages: - '@vue/composition-api' - vue + /@webfansplz/vuedoc-parser@0.0.4(pug@3.0.2): + resolution: {integrity: sha512-OnJxUtZOvKHonA9wmW1F0E+UkjP4RZdNRZyUWF1Nrh0TAm4uzX4a99EgHH33Rc2dJgkhMdtaZ9P+ekVJ42Y0kg==} + engines: {node: '>=16.6'} + peerDependencies: + pug: ^3.0.2 + dependencies: + '@babel/parser': 7.23.6 + '@babel/traverse': 7.23.6 + pug: 3.0.2 + resolve: 1.22.8 + vue-template-compiler: 2.7.15 + transitivePeerDependencies: + - supports-color + dev: true + /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -2754,6 +2851,12 @@ packages: engines: {node: '>=0.4.0'} dev: true + /acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + /acorn@8.10.0: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} @@ -2954,6 +3057,14 @@ packages: is-shared-array-buffer: 1.0.2 dev: true + /asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + dev: true + + /assert-never@1.2.1: + resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==} + dev: true + /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true @@ -2980,6 +3091,13 @@ packages: engines: {node: '>= 0.4'} dev: true + /babel-walk@3.0.0-canary-5: + resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==} + engines: {node: '>= 10.0.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true @@ -3007,6 +3125,10 @@ packages: engines: {node: '>=8'} dev: true + /birpc@0.2.14: + resolution: {integrity: sha512-37FHE8rqsYM5JEKCnXFyHpBCzvgHEExwVVTq+nUmloInU7l8ezD1TpOhKpS8oe1DTYFqEK27rFZVKG43oTqXRA==} + dev: true + /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} dependencies: @@ -3170,6 +3292,11 @@ packages: engines: {node: '>=6'} dev: true + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + /camelcase@7.0.1: resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} engines: {node: '>=14.16'} @@ -3241,6 +3368,12 @@ packages: resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} dev: true + /character-parser@2.2.0: + resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} + dependencies: + is-regex: 1.1.4 + dev: true + /character-reference-invalid@1.1.4: resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} dev: true @@ -3443,6 +3576,13 @@ packages: engines: {node: ^14.18.0 || >=16.10.0} dev: true + /constantinople@4.0.1: + resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + dev: true + /conventional-changelog-angular@7.0.0: resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} engines: {node: '>=16'} @@ -3868,6 +4008,10 @@ packages: esutils: 2.0.3 dev: true + /doctypes@1.1.0: + resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} + dev: true + /dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} dependencies: @@ -5207,6 +5351,11 @@ packages: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true + /html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + dev: true + /html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} dev: true @@ -5480,6 +5629,13 @@ packages: hasBin: true dev: true + /is-expression@4.0.0: + resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} + dependencies: + acorn: 7.4.1 + object-assign: 4.1.1 + dev: true + /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -5578,6 +5734,10 @@ packages: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} dev: true + /is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + dev: true + /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -5751,6 +5911,10 @@ packages: nopt: 7.2.0 dev: true + /js-stringify@1.0.2: + resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} + dev: true + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true @@ -5886,6 +6050,13 @@ packages: engines: {'0': node >= 0.2.0} dev: true + /jstransformer@1.0.0: + resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} + dependencies: + is-promise: 2.2.2 + promise: 7.3.1 + dev: true + /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: @@ -6374,6 +6545,11 @@ packages: resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} dev: true + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + /object-hash@3.0.0: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} @@ -6820,6 +6996,12 @@ packages: iterate-value: 1.0.2 dev: true + /promise@7.3.1: + resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + dependencies: + asap: 2.0.6 + dev: true + /property-information@6.4.0: resolution: {integrity: sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==} dev: true @@ -6856,6 +7038,97 @@ packages: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} dev: true + /pug-attrs@3.0.0: + resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} + dependencies: + constantinople: 4.0.1 + js-stringify: 1.0.2 + pug-runtime: 3.0.1 + dev: true + + /pug-code-gen@3.0.2: + resolution: {integrity: sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==} + dependencies: + constantinople: 4.0.1 + doctypes: 1.1.0 + js-stringify: 1.0.2 + pug-attrs: 3.0.0 + pug-error: 2.0.0 + pug-runtime: 3.0.1 + void-elements: 3.1.0 + with: 7.0.2 + dev: true + + /pug-error@2.0.0: + resolution: {integrity: sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==} + dev: true + + /pug-filters@4.0.0: + resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==} + dependencies: + constantinople: 4.0.1 + jstransformer: 1.0.0 + pug-error: 2.0.0 + pug-walk: 2.0.0 + resolve: 1.22.8 + dev: true + + /pug-lexer@5.0.1: + resolution: {integrity: sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==} + dependencies: + character-parser: 2.2.0 + is-expression: 4.0.0 + pug-error: 2.0.0 + dev: true + + /pug-linker@4.0.0: + resolution: {integrity: sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==} + dependencies: + pug-error: 2.0.0 + pug-walk: 2.0.0 + dev: true + + /pug-load@3.0.0: + resolution: {integrity: sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==} + dependencies: + object-assign: 4.1.1 + pug-walk: 2.0.0 + dev: true + + /pug-parser@6.0.0: + resolution: {integrity: sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==} + dependencies: + pug-error: 2.0.0 + token-stream: 1.0.0 + dev: true + + /pug-runtime@3.0.1: + resolution: {integrity: sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==} + dev: true + + /pug-strip-comments@2.0.0: + resolution: {integrity: sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==} + dependencies: + pug-error: 2.0.0 + dev: true + + /pug-walk@2.0.0: + resolution: {integrity: sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==} + dev: true + + /pug@3.0.2: + resolution: {integrity: sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==} + dependencies: + pug-code-gen: 3.0.2 + pug-filters: 4.0.0 + pug-lexer: 5.0.1 + pug-linker: 4.0.0 + pug-load: 3.0.0 + pug-parser: 6.0.0 + pug-runtime: 3.0.1 + pug-strip-comments: 2.0.0 + dev: true + /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -7604,6 +7877,10 @@ packages: engines: {node: '>= 0.4'} dev: true + /svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + dev: true + /svgo@3.0.4: resolution: {integrity: sha512-T+Xul3JwuJ6VGXKo/p2ndqx1ibxNKnLTvRc1ZTWKCfyKS/GgNjRZcYsK84fxTsy/izr91g/Rwx6fGnVgaFSI5g==} engines: {node: '>=14.0.0'} @@ -7725,6 +8002,10 @@ packages: is-number: 7.0.0 dev: true + /token-stream@1.0.0: + resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==} + dev: true + /totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} @@ -8236,6 +8517,14 @@ packages: vfile-message: 4.0.2 dev: true + /vite-hot-client@0.2.3(vite@5.0.8): + resolution: {integrity: sha512-rOGAV7rUlUHX89fP2p2v0A2WWvV3QMX2UYq0fRqsWSvFvev4atHWqjwGoKaZT1VTKyLGk533ecu3eyd0o59CAg==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 + dependencies: + vite: 5.0.8 + dev: true + /vite-node@1.0.4: resolution: {integrity: sha512-9xQQtHdsz5Qn8hqbV7UKqkm8YkJhzT/zr41Dmt5N7AlD8hJXw/Z7y0QiD5I8lnTthV9Rvcvi0QW7PI0Fq83ZPg==} engines: {node: ^18.0.0 || >=20.0.0} @@ -8305,6 +8594,30 @@ packages: - rollup dev: true + /vite-plugin-inspect@0.7.42(vite@5.0.8): + resolution: {integrity: sha512-JCyX86wr3siQc+p9Kd0t8VkFHAJag0RaQVIpdFGSv5FEaePEVB6+V/RGtz2dQkkGSXQzRWrPs4cU3dRKg32bXw==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + dependencies: + '@antfu/utils': 0.7.7 + '@rollup/pluginutils': 5.1.0 + debug: 4.3.4 + error-stack-parser-es: 0.1.1 + fs-extra: 11.2.0 + open: 9.1.0 + picocolors: 1.0.0 + sirv: 2.0.3 + vite: 5.0.8 + transitivePeerDependencies: + - rollup + - supports-color + dev: true + /vite-plugin-inspect@0.8.1(vite@5.0.8): resolution: {integrity: sha512-oPBPVGp6tBd5KdY/qY6lrbLXqrbHRG0hZLvEaJfiZ/GQfDB+szRuLHblQh1oi1Hhh8GeLit/50l4xfs2SA+TCA==} engines: {node: '>=14'} @@ -8350,6 +8663,46 @@ packages: - supports-color dev: true + /vite-plugin-vue-devtools@1.0.0-rc.6(pug@3.0.2)(vite@5.0.8): + resolution: {integrity: sha512-mtWRTz1VwBEZcb6rosgiDvXHZunxPxgBaPsORbJECZGkjZFRig7NIEwiRXgSgpx+DAiEzBoX+FLsNnGgVq+VuA==} + engines: {node: '>=v14.21.3'} + peerDependencies: + vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 + dependencies: + '@vite-plugin-vue-devtools/core': 1.0.0-rc.6(vite@5.0.8) + '@webfansplz/vuedoc-parser': 0.0.4(pug@3.0.2) + birpc: 0.2.14 + execa: 8.0.1 + sirv: 2.0.3 + vite: 5.0.8 + vite-plugin-inspect: 0.7.42(vite@5.0.8) + vite-plugin-vue-inspector: 4.0.2(vite@5.0.8) + transitivePeerDependencies: + - '@nuxt/kit' + - pug + - rollup + - supports-color + dev: true + + /vite-plugin-vue-inspector@4.0.2(vite@5.0.8): + resolution: {integrity: sha512-KPvLEuafPG13T7JJuQbSm5PwSxKFnVS965+MP1we2xGw9BPkkc/+LPix5MMWenpKWqtjr0ws8THrR+KuoDC8hg==} + peerDependencies: + vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 + dependencies: + '@babel/core': 7.23.6 + '@babel/plugin-proposal-decorators': 7.23.6(@babel/core@7.23.6) + '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.6) + '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.23.6) + '@vue/babel-plugin-jsx': 1.1.5(@babel/core@7.23.6) + '@vue/compiler-dom': 3.3.11 + kolorist: 1.8.0 + magic-string: 0.30.5 + vite: 5.0.8 + transitivePeerDependencies: + - supports-color + dev: true + /vite-svg-loader@5.1.0(vue@3.3.11): resolution: {integrity: sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==} peerDependencies: @@ -8508,6 +8861,11 @@ packages: - terser dev: true + /void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + dev: true + /vue-component-type-helpers@1.8.25: resolution: {integrity: sha512-NCA6sekiJIMnMs4DdORxATXD+/NRkQpS32UC+I1KQJUasx+Z7MZUb3Y+MsKsFmX+PgyTYSteb73JW77AibaCCw==} dev: true @@ -8699,6 +9057,16 @@ packages: execa: 5.1.1 dev: true + /with@7.0.2: + resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} + engines: {node: '>= 10.0.0'} + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + assert-never: 1.2.1 + babel-walk: 3.0.0-canary-5 + dev: true + /wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} dev: true diff --git a/src/composables/useTresContextProvider/index.ts b/src/composables/useTresContextProvider/index.ts index 4f0905237..378814eb2 100644 --- a/src/composables/useTresContextProvider/index.ts +++ b/src/composables/useTresContextProvider/index.ts @@ -1,8 +1,9 @@ -import { toValue, useElementSize, useWindowSize } from '@vueuse/core' -import { inject, provide, readonly, shallowRef, computed, ref } from 'vue' +import { toValue, useElementSize, useFps, useMemory, useRafFn, useWindowSize } from '@vueuse/core' +import { inject, provide, readonly, shallowRef, computed, ref, onUnmounted } from 'vue' import type { Camera, EventDispatcher, Scene, WebGLRenderer } from 'three' import { Raycaster } from 'three' import type { ComputedRef, DeepReadonly, MaybeRef, MaybeRefOrGetter, Ref, ShallowRef } from 'vue' +import { calculateMemoryUsage } from '../../utils/perf' import { useCamera } from '../useCamera' import type { UseRendererOptions } from '../useRenderer' import { useRenderer } from '../useRenderer' @@ -17,6 +18,18 @@ export interface TresContext { controls: Ref<(EventDispatcher & { enabled: boolean }) | null> renderer: ShallowRef raycaster: ShallowRef + perf: { + maxFrames: number + fps: { + value: number + accumulator: number[] + } + memory: { + currentMem: number + allocatedMem: number + accumulator: number[] + } + } registerCamera: (camera: Camera) => void setCameraActive: (cameraOrUuid: Camera | string) => void deregisterCamera: (camera: Camera) => void @@ -78,6 +91,18 @@ export function useTresContextProvider({ renderer, raycaster: shallowRef(new Raycaster()), controls: ref(null), + perf: { + maxFrames: 160, + fps: { + value: 0, + accumulator: [], + }, + memory: { + currentMem: 0, + allocatedMem: 0, + accumulator: [], + }, + }, extend, registerCamera, setCameraActive, @@ -85,6 +110,75 @@ export function useTresContextProvider({ } provide('useTres', toProvide) + + // Performance + const updateInterval = 100 // Update interval in milliseconds + const fps = useFps({ every: updateInterval }) + const { isSupported, memory } = useMemory({ interval: updateInterval }) + const maxFrames = 160 + let lastUpdateTime = performance.now() + + const updatePerformanceData = ({ timestamp }: { timestamp: number }) => { + + // Update WebGL Memory Usage (Placeholder for actual logic) + // perf.memory.value = calculateMemoryUsage(gl) + if (toProvide.scene.value) { + toProvide.perf.memory.allocatedMem = calculateMemoryUsage(toProvide.scene.value as unknown as TresObject) + } + + // Update memory usage + if (timestamp - lastUpdateTime >= updateInterval) { + lastUpdateTime = timestamp + + // Update FPS + toProvide.perf.fps.accumulator.push(fps.value as never) + + if (toProvide.perf.fps.accumulator.length > maxFrames) { + toProvide.perf.fps.accumulator.shift() + } + + toProvide.perf.fps.value = fps.value + + // Update memory + if (isSupported.value && memory.value) { + toProvide.perf.memory.accumulator.push(memory.value.usedJSHeapSize / 1024 / 1024 as never) + + if (toProvide.perf.memory.accumulator.length > maxFrames) { + toProvide.perf.memory.accumulator.shift() + } + + toProvide.perf.memory.currentMem + = toProvide.perf.memory.accumulator.reduce((a, b) => a + b, 0) / toProvide.perf.memory.accumulator.length + + } + } + } + + // Devtools + let accumulatedTime = 0 + const interval = 1 // Interval in milliseconds, e.g., 1000 ms = 1 second + + const { pause, resume } = useRafFn(({ delta }) => { + if (!window.__TRES__DEVTOOLS__) return + + updatePerformanceData({ timestamp: performance.now() }) + + // Accumulate the delta time + accumulatedTime += delta + + // Check if the accumulated time is greater than or equal to the interval + if (accumulatedTime >= interval) { + window.__TRES__DEVTOOLS__.cb(toProvide) + + // Reset the accumulated time + accumulatedTime = 0 + } + }, { immediate: true }) + + onUnmounted(() => { + pause() + }) + return toProvide } diff --git a/src/env.d.ts b/src/env.d.ts index 972479b18..0a0a81bf3 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -7,5 +7,12 @@ declare module '*.vue' { export default component } +interface Window { + __TRES__DEVTOOLS__?: { + cb: Function; + // You can add other properties of __TRES__DEVTOOLS__ here if needed + }; +} + declare module '*.glsl' {} declare module '*.json' {} diff --git a/src/utils/perf.ts b/src/utils/perf.ts new file mode 100644 index 000000000..5e0120cd8 --- /dev/null +++ b/src/utils/perf.ts @@ -0,0 +1,34 @@ +import type { Scene } from 'three' +import type { TresObject } from './../types' + +export function calculateMemoryUsage(object: TresObject | Scene) { + let totalMemory = 0 + + object.traverse((node: TresObject) => { + if (node.isMesh && node.geometry) { + const geometry = node.geometry + const verticesMemory = geometry.attributes.position.count * 3 * Float32Array.BYTES_PER_ELEMENT + const facesMemory = geometry.index ? geometry.index.count * Uint32Array.BYTES_PER_ELEMENT : 0 + const normalsMemory + = geometry.attributes.normal ? geometry.attributes.normal.count * 3 * Float32Array.BYTES_PER_ELEMENT : 0 + const uvsMemory = geometry.attributes.uv ? geometry.attributes.uv.count * 2 * Float32Array.BYTES_PER_ELEMENT : 0 + + const geometryMemory = verticesMemory + facesMemory + normalsMemory + uvsMemory + totalMemory += geometryMemory + } + }) + + return totalMemory +} + +export function bytesToKB(bytes: number): string { + return (bytes / 1024).toFixed(2) +} + +export function bytesToMB(bytes: number): string { + return (bytes / 1024 / 1024).toFixed(2) +} + +export function bytesToGB(bytes: number): string { + return (bytes / 1024 / 1024 / 1024).toFixed(2) +} \ No newline at end of file