import { Quaternion , Vector3 } from '@babylonjs/core/Maths/math.vector.js' ; import { Observable , Observer } from '@babylonjs/core/Misc/observable.js' ; import { Nullable } from '@babylonjs/core/types.js' ; import { CreatedInstance } from './CreatedInstance' ; import { PropChangeType , PropertyUpdate , PropsHandler } from './PropsHandler' ; export const applyUpdateToInstance = ( createdInstance , update ) : void => { const target = update . target !== undefined ? createdInstance . hostInstance [ update . target ] : createdInstance . hostInstance ; switch ( update . changeType ) { case PropChangeType . Primitive : case PropChangeType . FresnelParameters : case PropChangeType . LambdaExpression : case PropChangeType . Texture : if ( update . propertyName . indexOf ( '.' ) !== - 1 ) { const dotProps = update . propertyName . split ( '.' ) ; const lastProp = dotProps . pop ( ) ! ; const newTarget = dotProps . reduce ( ( target , prop ) => target [ prop ] , target ) ; newTarget [ lastProp ] = update . value ; } else { target [ update . propertyName ] = update . value ; } break ; case PropChangeType . Vector3 : if ( target [ update . propertyName ] ) { ; ( target [ update . propertyName ] as Vector3 ) . copyFrom ( update . value ) ; } else if ( update . value ) { target [ update . propertyName ] = update . value . clone ( ) ; } else { target [ update . propertyName ] = update . value ; } break ; case PropChangeType . Color3 : case PropChangeType . Color4 : if ( update . value ) { target [ update . propertyName ] = update . value . clone ( ) ; } else { target [ update . propertyName ] = update . value ; } break ; case PropChangeType . Control : target [ update . propertyName ] = update . value ; break ; case PropChangeType . NumericArray : target [ update . propertyName ] = update . value ; break ; case PropChangeType . Observable : if ( update . propertyName in createdInstance . observers ) { createdInstance . observers [ update . propertyName ] ! . callback = update . value ; } else { const observer = ( target [ update . propertyName ] as Observable < any > ) . add ( update . value ) ; createdInstance . observers [ update . propertyName ] = observer ; } break ; case PropChangeType . Method : if ( typeof target [ update . propertyName ] === 'function' ) { if ( Array . isArray ( update . value ) ) { target [ update . propertyName ] ( ... update . value ) ; } else if ( Object ( update . value ) !== update . value ) { target [ update . propertyName ] ( update . value ) ; } else { console . error ( "need to make sure this isn't something like a Vector3 before destructuring" ) ; target [ update . propertyName ] ( ... Object . values ( update . value ) ) ; } } else { console . error ( `Cannot call [not a function] ${ update . propertyName }(...) on:` , target ) ; } break ; case PropChangeType . Quaternion : if ( target [ update . propertyName ] ) { ; ( target [ update . propertyName ] as Quaternion ) . copyFrom ( update . value ) ; } else if ( update . value ) { target [ update . propertyName ] = ( update . value as Quaternion ) . clone ( ) ; } else { target [ update . propertyName ] = update . value ; } break ; default : console . error ( `Unhandled property update of type '${ update . changeType }'` ) ; break ; } } ; param instance param props export const applyInitialPropsToCreatedInstance = ( createdInstance , props ) => { if ( createdInstance . propsHandlers === undefined ) { return ; } const initPayload = [ ] ; createdInstance . propsHandlers . getPropsHandlers ( ) . forEach ( ( propHandler ) => { const handlerUpdates = propHandler . getPropertyUpdates ( { } , props ) ; if ( handlerUpdates !== null ) { initPayload . push ( ... handlerUpdates ) ; } } ) ; if ( initPayload . length > 0 ) { initPayload . forEach ( ( update ) => { applyUpdateToInstance ( createdInstance , update ) ; } ) ; } } ;