From df96c1f31aafe1b73cd344fde39420c1ae443d47 Mon Sep 17 00:00:00 2001 From: alvarosabu Date: Wed, 6 Dec 2023 12:22:37 +0100 Subject: [PATCH] feat: devtools hook on window object --- playground/package.json | 1 + playground/vite.config.ts | 2 + pnpm-lock.yaml | 386 ++++++++++++++++++ .../useTresContextProvider/index.ts | 97 ++++- src/env.d.ts | 7 + src/utils/perf.ts | 34 ++ 6 files changed, 525 insertions(+), 2 deletions(-) create mode 100644 src/utils/perf.ts diff --git a/playground/package.json b/playground/package.json index 232bf66c2..4e3633cf4 100644 --- a/playground/package.json +++ b/playground/package.json @@ -18,6 +18,7 @@ "unplugin-auto-import": "^0.17.1", "vite-plugin-glsl": "^1.2.0", "vite-plugin-qrcode": "^0.2.2", + "vite-plugin-vue-devtools": "1.0.0-rc.6", "vue-tsc": "^1.8.22" } } 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 0271befd1..d7c34e9e8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -164,6 +164,9 @@ importers: vite-plugin-qrcode: specifier: ^0.2.2 version: 0.2.2(vite@4.5.0) + vite-plugin-vue-devtools: + specifier: 1.0.0-rc.6 + version: 1.0.0-rc.6(pug@3.0.2)(vite@4.5.0) vue-tsc: specifier: ^1.8.22 version: 1.8.22(typescript@5.3.2) @@ -432,6 +435,24 @@ packages: semver: 6.3.1 dev: true + /@babel/helper-create-class-features-plugin@7.23.5(@babel/core@7.23.3): + resolution: {integrity: sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.3 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.3) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 + dev: true + /@babel/helper-environment-visitor@7.22.20: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} @@ -603,6 +624,49 @@ packages: dependencies: '@babel/types': 7.23.4 + /@babel/plugin-proposal-decorators@7.23.5(@babel/core@7.23.3): + resolution: {integrity: sha512-6IsY8jOeWibsengGlWIezp7cuZEFzNlAghFpzh9wiZwhQ42/hRcPnY/QV9HJoKTlujupinSlnQPiEy/u2C1ZfQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.3 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.23.3) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.3) + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.23.3) + dev: true + + /@babel/plugin-syntax-decorators@7.23.3(@babel/core@7.23.3): + 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.3 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.3 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.3): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.3 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.3): resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} engines: {node: '>=6.9.0'} @@ -2322,6 +2386,19 @@ packages: - rollup dev: true + /@vite-plugin-vue-devtools/core@1.0.0-rc.6(vite@4.5.0): + 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.4 + birpc: 0.2.14 + estree-walker: 2.0.2 + magic-string: 0.30.5 + vite: 4.5.0 + vite-hot-client: 0.2.3(vite@4.5.0) + dev: true + /@vitejs/plugin-vue@4.5.0(vite@5.0.2)(vue@3.3.9): resolution: {integrity: sha512-a2WSpP8X8HTEww/U00bU4mX1QpLINNuz/2KMNpLsdu3BzOpak3AGI1CJYBTXcc4SPhaD0eNRUp7IyQK405L5dQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -2419,6 +2496,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.3): + resolution: {integrity: sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.3 + '@babel/helper-module-imports': 7.22.15 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.3) + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.4 + '@babel/types': 7.23.4 + '@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.7: resolution: {integrity: sha512-pACdY6YnTNVLXsB86YD8OF9ihwpolzhhtdLVHhBL6do/ykr6kKXNYABRtNMGrsQXpEXXyAdwvWWkuTbs4MFtPQ==} dependencies: @@ -2653,6 +2753,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.4 + '@babel/traverse': 7.23.4 + 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 @@ -2679,6 +2794,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'} @@ -2879,6 +3000,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 @@ -2905,6 +3034,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.4 + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true @@ -2932,6 +3068,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: @@ -3095,6 +3235,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'} @@ -3166,6 +3311,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 @@ -3368,6 +3519,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.4 + '@babel/types': 7.23.4 + dev: true + /conventional-changelog-angular@7.0.0: resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} engines: {node: '>=16'} @@ -3793,6 +3951,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: @@ -5132,6 +5294,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 @@ -5405,6 +5572,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'} @@ -5503,6 +5677,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'} @@ -5676,6 +5854,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 @@ -5811,6 +5993,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: @@ -6299,6 +6488,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'} @@ -6738,6 +6932,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 @@ -6774,6 +6974,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'} @@ -7533,6 +7824,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'} @@ -7654,6 +7949,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'} @@ -8161,6 +8460,14 @@ packages: vfile-message: 4.0.2 dev: true + /vite-hot-client@0.2.3(vite@4.5.0): + resolution: {integrity: sha512-rOGAV7rUlUHX89fP2p2v0A2WWvV3QMX2UYq0fRqsWSvFvev4atHWqjwGoKaZT1VTKyLGk533ecu3eyd0o59CAg==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 + dependencies: + vite: 4.5.0 + dev: true + /vite-node@0.34.6(@types/node@20.8.10): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} engines: {node: '>=v14.18.0'} @@ -8223,6 +8530,30 @@ packages: - rollup dev: true + /vite-plugin-inspect@0.7.42(vite@4.5.0): + 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.6 + '@rollup/pluginutils': 5.0.5 + debug: 4.3.4 + error-stack-parser-es: 0.1.1 + fs-extra: 11.1.1 + open: 9.1.0 + picocolors: 1.0.0 + sirv: 2.0.3 + vite: 4.5.0 + transitivePeerDependencies: + - rollup + - supports-color + dev: true + /vite-plugin-inspect@0.8.0(vite@5.0.2): resolution: {integrity: sha512-6Ijifcb/dWYSZoTlkYaJmLfnsi3tR19qB706CV7D4mG6PBgBx4e5cGmICaxAFwlF9yJv6MeMwmNlXa4exA9DQw==} engines: {node: '>=14'} @@ -8268,6 +8599,46 @@ packages: - supports-color dev: true + /vite-plugin-vue-devtools@1.0.0-rc.6(pug@3.0.2)(vite@4.5.0): + 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@4.5.0) + '@webfansplz/vuedoc-parser': 0.0.4(pug@3.0.2) + birpc: 0.2.14 + execa: 8.0.1 + sirv: 2.0.3 + vite: 4.5.0 + vite-plugin-inspect: 0.7.42(vite@4.5.0) + vite-plugin-vue-inspector: 4.0.1(vite@4.5.0) + transitivePeerDependencies: + - '@nuxt/kit' + - pug + - rollup + - supports-color + dev: true + + /vite-plugin-vue-inspector@4.0.1(vite@4.5.0): + resolution: {integrity: sha512-Jk7YUpYFK1Slm64ct6jL9vfVNnDXsK1N3axCbfpyXmRH0pNbd9yZ58haZKyjZ/Mi47D17dB6KnxPqOLO2SR1FQ==} + peerDependencies: + vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 + dependencies: + '@babel/core': 7.23.3 + '@babel/plugin-proposal-decorators': 7.23.5(@babel/core@7.23.3) + '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.23.3) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.3) + '@babel/plugin-transform-typescript': 7.23.4(@babel/core@7.23.3) + '@vue/babel-plugin-jsx': 1.1.5(@babel/core@7.23.3) + '@vue/compiler-dom': 3.3.9 + kolorist: 1.8.0 + magic-string: 0.30.5 + vite: 4.5.0 + transitivePeerDependencies: + - supports-color + dev: true + /vite-svg-loader@5.1.0(vue@3.3.9): resolution: {integrity: sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==} peerDependencies: @@ -8471,6 +8842,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.22: resolution: {integrity: sha512-LK3wJHs3vJxHG292C8cnsRusgyC5SEZDCzDCD01mdE/AoREFMl2tzLRuzwyuEsOIz13tqgBcnvysN3Lxsa14Fw==} dev: true @@ -8662,6 +9038,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.4 + '@babel/types': 7.23.4 + 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 79b0379fe..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, @@ -86,6 +111,74 @@ 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