import { Color3 } from "babylonjs/Maths/math.color" ; import { IPerfMetadata } from "babylonjs/Misc/interfaces/iPerfViewer" ; import { PerformanceViewerCollector } from "babylonjs/Misc/PerformanceViewer/performanceViewerCollector" ; import * as React from "react" ; import { useEffect , useState } from "react" ; import { ColorPickerLineComponent } from "../../../../sharedUiComponents/lines/colorPickerComponent" ; import { faSquare , faCheckSquare } from "@fortawesome/free-solid-svg-icons" ; import { CheckBoxLineComponent } from "../../../../sharedUiComponents/lines/checkBoxLineComponent" ; import { Observable } from "babylonjs/Misc/observable" ; import { IPerfMinMax , IVisibleRangeChangedObservableProps } from "../../../graph/graphSupportingTypes" ; import { Engine } from "babylonjs/Engines/engine" ; interface IPerformanceViewerSidebarComponentProps { collector : PerformanceViewerCollector ; onVisibleRangeChangedObservable ? : Observable < IVisibleRangeChangedObservableProps > ; } export const PerformanceViewerSidebarComponent = ( props ) => { const { collector , onVisibleRangeChangedObservable } = props ; const [ metadataMap , setMetadataMap ] = useState < Map < string , IPerfMetadata > > ( ) ; const [ metadataCategoryId , setMetadataCategoryId ] = useState < Map < string , string [ ] > > ( ) ; const [ metadataCategoryChecked , setMetadataCategoryChecked ] = useState < Map < string , number > > ( ) ; const [ metadataCategories , setMetadataCategories ] = useState < string [ ] > ( ) ; const [ valueMap , setValueMap ] = useState < Map < string , IPerfMinMax > > ( ) ; useEffect ( ( ) => { if ( ! onVisibleRangeChangedObservable ) { return ; } const observer = ( props ) => { setValueMap ( props . valueMap ) ; } ; onVisibleRangeChangedObservable . add ( observer ) ; return ( ) => { onVisibleRangeChangedObservable . removeCallback ( observer ) ; } ; } , [ onVisibleRangeChangedObservable ] ) ; useEffect ( ( ) => { const onUpdateMetadata = ( metadata ) => { const newCategoryIdMap = new Map < string , string [ ] > ( ) ; const newCategoryCheckedMap = new Map < string , number > ( ) ; metadata . forEach ( ( value , id ) => { const currentCategory = value . category ?? "" ; let currentIds = newCategoryIdMap . get ( currentCategory ) ?? [ ] ; let currentChecked = newCategoryCheckedMap . get ( currentCategory ) ?? 0 ; currentIds . push ( id ) ; newCategoryIdMap . set ( currentCategory , currentIds ) ; if ( ! value . hidden ) { currentChecked += 1 ; } newCategoryCheckedMap . set ( currentCategory , currentChecked ) ; } ) ; const orderedCategories = Array . from ( newCategoryIdMap . keys ( ) ) ; orderedCategories . sort ( ) ; setMetadataCategoryId ( newCategoryIdMap ) ; setMetadataCategoryChecked ( newCategoryCheckedMap ) ; setMetadataMap ( metadata ) ; setMetadataCategories ( orderedCategories ) ; } ; collector . metadataObservable . add ( onUpdateMetadata ) ; return ( ) => { collector . metadataObservable . removeCallback ( onUpdateMetadata ) ; } ; } , [ ] ) ; const onCheckChange = ( id ) => ( selected ) => { collector . updateMetadata ( id , "hidden" , ! selected ) ; } ; const onCheckAllChange = ( category ) => ( selected ) => { const categoryIds = metadataCategoryId ?. get ( category ) ; categoryIds ?. forEach ( ( id ) => { collector . updateMetadata ( id , "hidden" , ! selected ) ; } ) ; } ; const onColorChange = ( id ) => ( color ) => { collector . updateMetadata ( id , "color" , color ) ; } ; return ( < div id = "performance-viewer-sidebar" > { metadataCategories && metadataCategories . map ( ( category ) => ( < div key = { `category-${ category || 'version' }` } > { category ? < div className = "category-header header sidebar-item" key = { `header-${ category }` } > < span className = "category" > { category } < /span> < CheckBoxLineComponent isSelected = { ( ) => metadataCategoryChecked ?. get ( category ) === metadataCategoryId ?. get ( category ) ?. length } onSelect = { onCheckAllChange ( category ) } faIcons = { { enabled : faCheckSquare , disabled : faSquare } } /> < /div> : < div className = "version-header sidebar-item" key = { "header-version" } > < span className = "category" > Version : < /span> < span className = "value" > { Engine . Version } < /span> < /div>} { metadataCategoryId ?. get ( category ) ?. map ( ( id ) => { const metadata = metadataMap ?. get ( id ) ; const range = valueMap ?. get ( id ) ; return metadata && < div key = { `perf-sidebar-item-${ id }` } className = "sidebar-item measure" > { } < div className = "category" > < CheckBoxLineComponent isSelected = { ( ) => ! metadata . hidden } onSelect = { onCheckChange ( id ) } faIcons = { { enabled : faCheckSquare , disabled : faSquare } } /> < ColorPickerLineComponent value = { Color3 . FromHexString ( metadata . color ?? "#000" ) } onColorChanged = { onColorChange ( id ) } shouldPopRight / > < span className = "sidebar-item-label" > { id } < /span> < /div> { } { range && < div className = "value" > { ( ( range . min + range . max ) / 2 ) . toFixed ( 2 ) } < /div>} < /div>; } ) } < /div>))} < /div>); } ;