import { MODULE_INJECTORS_VS , MODULE_INJECTORS_FS } from '../../modules/module-injectors' ; import { assert } from '../utils/assert' ; const MODULE_INJECTORS = { vs : MODULE_INJECTORS_VS , fs : MODULE_INJECTORS_FS } ; const REGEX_START_OF_MAIN = /void\s+main\s*\([^)]*\)\s*\{\n?/ ; const REGEX_END_OF_MAIN = /}\n?[^{}]*$/ ; const fragments = [ ] ; export const DECLARATION_INJECT_MARKER = '__LUMA_INJECT_DECLARATIONS__' ; param source param type param inject param injectStandardStubs returns export default function injectShader ( source , type , inject , injectStandardStubs = false ) { const isVertex = type === 'vs' ; for ( const key in inject ) { const fragmentData = inject [ key ] ; fragmentData . sort ( ( a , b ) => a . order - b . order ) ; fragments . length = fragmentData . length ; for ( let i = 0 , len = fragmentData . length ; i < len ; ++ i ) { fragments [ i ] = fragmentData [ i ] . injection ; } const fragmentString = `${ fragments . join ( '\n' ) }\n` ; switch ( key ) { case 'vs:#decl' : if ( isVertex ) { source = source . replace ( DECLARATION_INJECT_MARKER , fragmentString ) ; } break ; case 'vs:#main-start' : if ( isVertex ) { source = source . replace ( REGEX_START_OF_MAIN , ( match ) => match + fragmentString ) ; } break ; case 'vs:#main-end' : if ( isVertex ) { source = source . replace ( REGEX_END_OF_MAIN , ( match ) => fragmentString + match ) ; } break ; case 'fs:#decl' : if ( ! isVertex ) { source = source . replace ( DECLARATION_INJECT_MARKER , fragmentString ) ; } break ; case 'fs:#main-start' : if ( ! isVertex ) { source = source . replace ( REGEX_START_OF_MAIN , ( match ) => match + fragmentString ) ; } break ; case 'fs:#main-end' : if ( ! isVertex ) { source = source . replace ( REGEX_END_OF_MAIN , ( match ) => fragmentString + match ) ; } break ; default : source = source . replace ( key , ( match ) => match + fragmentString ) ; } } source = source . replace ( DECLARATION_INJECT_MARKER , '' ) ; if ( injectStandardStubs ) { source = source . replace ( /\}\s*$/ , ( match ) => match + MODULE_INJECTORS [ type ] ) ; } return source ; } export function combineInjects ( injects ) { const result = { } ; assert ( Array . isArray ( injects ) && injects . length > 1 ) ; injects . forEach ( ( inject ) => { for ( const key in inject ) { result [ key ] = result [ key ] ? `${ result [ key ] }\n${ inject [ key ] }` : inject [ key ] ; } } ) ; return result ; }