Mostly finished de-std::ifying the shaders manager

This commit is contained in:
Emmanuel BENOîT 2017-11-05 13:47:26 +01:00
parent f5630fa6e6
commit 2ce821c4c0
3 changed files with 69 additions and 47 deletions

2
ebcl

@ -1 +1 @@
Subproject commit c35f4c6644ddc06f08d5ab15e1d08c087cd8397a Subproject commit 1b1be9e6b2149867c5de67a3dc62ed997f803334

View file

@ -585,35 +585,50 @@ T_ShaderPipeline T_ShaderManager::pipeline(
void T_ShaderManager::update( ) void T_ShaderManager::update( )
{ {
T_Array< T_String > temp;
T_StringBuilder sb;
inputs_.clear( ); inputs_.clear( );
// Check for missing files // Check for missing files
for ( auto it = missing_.begin( ) ; it != missing_.end( ) ; ++ it ) { for ( auto it = missing_.keys( ).cbegin( ) ; it.valid( ) ; ++it ) {
const bool exists( ([] ( std::string const& name ) -> bool { const bool exists( ([&sb] ( T_String const& name ) -> bool {
struct stat buffer; struct stat buffer;
return ( stat( name.c_str( ) , &buffer ) == 0 ); sb.clear( );
})( "shaders/" + (*it).first ) ); sb << "shaders/" << name << '\0';
return ( stat( sb.data( ) , &buffer ) == 0 );
})( *it ) );
if ( !exists ) { if ( !exists ) {
continue; continue;
} }
updates_.insert( (*it).second.begin( ) , (*it).second.end( ) ); auto& set( missing_.values( )[ it.pos( ) ] );
missing_.erase( (*it).first ); for ( auto& s : set ) {
if ( !updates_.contains( s ) ) {
updates_.add( std::move( s ) );
}
}
temp.add( *it );
}
// Remove all marked entries
for ( auto const& s : temp ) {
missing_.remove( s );
} }
// Reset programs that need to be updated // Reset programs that need to be updated
T_Array< T_String > pipelines; temp.clear( );
for ( auto const& name : updates_ ) { for ( auto it = updates_.begin( ) ; it.valid( ) ; ) {
auto const* p( programIndex_.get( name.c_str( ) ) ); auto const* p( programIndex_.get( *it ) );
if ( p ) { if ( p ) {
auto& pr( programs_[ *p ] ); auto& pr( programs_[ *p ] );
for ( auto const& ref : pr.references ) { for ( auto const& ref : pr.references ) {
if ( !pipelines.contains( ref ) ) { if ( !temp.contains( ref ) ) {
pipelines.add( ref ); temp.add( ref );
} }
} }
resetProgram( pr ); resetProgram( pr );
++it;
} else { } else {
updates_.erase( name ); updates_.removeSwap( it.pos( ) );
} }
} }
if ( updates_.empty( ) ) { if ( updates_.empty( ) ) {
@ -621,7 +636,7 @@ void T_ShaderManager::update( )
} }
// Reset pipelines affected by the programs above // Reset pipelines affected by the programs above
for ( auto const& pName : pipelines ) { for ( auto const& pName : temp ) {
auto& pipeline( *pipelines_.get( pName ) ); auto& pipeline( *pipelines_.get( pName ) );
if ( pipeline.id != 0 ) { if ( pipeline.id != 0 ) {
glDeleteProgramPipelines( 1 , &pipeline.id ); glDeleteProgramPipelines( 1 , &pipeline.id );
@ -630,20 +645,20 @@ void T_ShaderManager::update( )
} }
// Try to load all updated programs // Try to load all updated programs
sb.clear( );
for ( auto const& name : updates_ ) { for ( auto const& name : updates_ ) {
auto& pr( programs_[ *programIndex_.get( name.c_str( ) ) ] ); auto& pr( programs_[ *programIndex_.get( name ) ] );
initProgram( pr ); initProgram( pr );
T_StringBuilder sb;
for ( auto const& e : pr.code.errors ) { for ( auto const& e : pr.code.errors ) {
sb << e.source << ':' << e.line << ": " sb << e.source << ':' << e.line << ": "
<< e.error << '\n'; << e.error << '\n';
} }
sb << '\0';
printf( "%s" , sb.data( ) );
} }
sb << '\0';
printf( "%s" , sb.data( ) );
// Try to initialise all affected pipelines // Try to initialise all affected pipelines
for ( auto const& pName : pipelines ) { for ( auto const& pName : temp ) {
initPipeline( *pipelines_.get( pName ) ); initPipeline( *pipelines_.get( pName ) );
} }
@ -667,7 +682,7 @@ uint32_t T_ShaderManager::newProgramRecord( )
void T_ShaderManager::loadProgram( void T_ShaderManager::loadProgram(
T_String const& pipeline , T_String const& pipeline ,
std::string const& name ) T_String const& name )
{ {
if ( useExistingProgram( pipeline , name ) ) { if ( useExistingProgram( pipeline , name ) ) {
return; return;
@ -675,8 +690,8 @@ void T_ShaderManager::loadProgram(
const uint32_t index( newProgramRecord( ) ); const uint32_t index( newProgramRecord( ) );
auto& program( programs_[ index ] ); auto& program( programs_[ index ] );
programIndex_.add( T_String{ name.c_str( ) } , index ); programIndex_.add( name , index );
program.name = name.c_str( ); program.name = name;
program.references.add( pipeline ); program.references.add( pipeline );
program.id = 0; program.id = 0;
initProgram( program ); initProgram( program );
@ -692,9 +707,9 @@ void T_ShaderManager::loadProgram(
bool T_ShaderManager::useExistingProgram( bool T_ShaderManager::useExistingProgram(
T_String const& pipeline , T_String const& pipeline ,
std::string const& name ) T_String const& name )
{ {
auto const* pos( programIndex_.get( name.c_str( ) ) ); auto const* pos( programIndex_.get( name ) );
if ( !pos ) { if ( !pos ) {
return false; return false;
} }
@ -762,7 +777,7 @@ void T_ShaderManager::dereferenceProgram(
return; return;
} }
resetProgram( program ); resetProgram( program );
programIndex_.remove( program.name.c_str( ) ); programIndex_.remove( program.name );
} }
@ -820,14 +835,14 @@ void T_ShaderManager::initProgram(
// Build the code // Build the code
auto name( program.name ); auto name( program.name );
printf( "init program %s\n" , program.name.c_str( ) ); printf( "init program %s\n" , program.name.toOSString( ).data( ) );
auto& code( program.code ); auto& code( program.code );
T_CodeBuilder_ cb( [this]( T_String const& n ) { return getInput( n ); } , T_CodeBuilder_ cb( [this]( T_String const& n ) { return getInput( n ); } ,
name.c_str( ) , code ); name , code );
const bool built( const bool built(
T_CodeBuilder_{ T_CodeBuilder_{
[this]( T_String const& n ) { return getInput( n ); } , [this]( T_String const& n ) { return getInput( n ); } ,
program.name.c_str( ) , code program.name , code
}.buildCode( ) ); }.buildCode( ) );
// Initialise file watcher + missing files // Initialise file watcher + missing files
@ -844,7 +859,10 @@ void T_ShaderManager::initProgram(
sb << "shaders/" << fn; sb << "shaders/" << fn;
w.watch( std::move( sb ) ); w.watch( std::move( sb ) );
} else { } else {
missing_[ std::string{ (char*) fn.toOSString( ).data( ) } ].insert( name ); auto& mset( missing_.getOrCreate( fn ) );
if ( !mset.contains( name ) ) {
mset.add( name );
}
} }
} }
@ -860,8 +878,7 @@ void T_ShaderManager::initProgram(
ProgramTypes_[ int( code.type ) ] , ProgramTypes_[ int( code.type ) ] ,
1 , &list[ 0 ] ); 1 , &list[ 0 ] );
if ( sid == 0 ) { if ( sid == 0 ) {
code.errors.addNew( name.c_str( ) , 0 , code.errors.addNew( name , 0 , "failed to create GL program" );
"failed to create GL program" );
return; return;
} }
@ -922,9 +939,11 @@ void T_ShaderManager::parseGLSLError(
} }
void T_ShaderManager::programUpdated( void T_ShaderManager::programUpdated(
std::string const& name ) T_String const& name )
{ {
updates_.insert( name ); if ( !updates_.contains( name ) ) {
updates_.add( name );
}
} }
void T_ShaderManager::resetProgram( void T_ShaderManager::resetProgram(
@ -944,14 +963,17 @@ void T_ShaderManager::resetProgram(
for ( auto i = 0u ; i < nf ; i ++ ) { for ( auto i = 0u ; i < nf ; i ++ ) {
T_String const& k{ files.keys( )[ i ] }; T_String const& k{ files.keys( )[ i ] };
bool v{ files[ i ] }; bool v{ files[ i ] };
std::string temp{ (char*) k.toOSString( ).data( ) }; auto* const ptr( missing_.get( k ) );
if ( v || missing_.find( temp ) == missing_.end( ) ) { if ( v || !ptr ) {
continue; continue;
} }
auto& set( missing_[ temp ] ); auto& set( *ptr );
set.erase( program.name ); const auto index( set.indexOf( program.name ) );
if ( set.empty( ) ) { if ( index != -1 ) {
missing_.erase( temp ); set.removeSwap( index );
if ( set.empty( ) ) {
missing_.remove( k );
}
} }
} }
} }
@ -1001,11 +1023,11 @@ void T_ShaderManager::makeUI( )
const bool open( nErrors const bool open( nErrors
? ImGui::TreeNodeEx( &program , ImGuiTreeNodeFlags_OpenOnArrow ? ImGui::TreeNodeEx( &program , ImGuiTreeNodeFlags_OpenOnArrow
| ImGuiTreeNodeFlags_OpenOnDoubleClick , "%s" , | ImGuiTreeNodeFlags_OpenOnDoubleClick , "%s" ,
program.name.c_str( ) ) program.name.toOSString( ).data( ) )
: false ); : false );
if ( !nErrors ) { if ( !nErrors ) {
ImGui::Text( "%s" , program.name.c_str( ) ); ImGui::Text( "%s" , program.name.toOSString( ).data( ) );
} }
ImGui::SameLine( 400 ); ImGui::SameLine( 400 );

View file

@ -182,7 +182,7 @@ struct T_ShaderManager
struct T_Program_ struct T_Program_
{ {
std::string name; T_String name;
T_Array< T_String > references; T_Array< T_String > references;
T_ShaderCode code; T_ShaderCode code;
GLuint id; GLuint id;
@ -198,17 +198,17 @@ struct T_ShaderManager
T_KeyValueTable< T_String , P_ShaderInput > inputs_; T_KeyValueTable< T_String , P_ShaderInput > inputs_;
std::map< std::string , std::set< std::string > > missing_; T_KeyValueTable< T_String , T_Array< T_String > > missing_;
std::set< std::string > updates_; T_Array< T_String > updates_;
uint32_t newProgramRecord( ); uint32_t newProgramRecord( );
void loadProgram( void loadProgram(
T_String const& pipeline , T_String const& pipeline ,
std::string const& name ); T_String const& name );
bool useExistingProgram( bool useExistingProgram(
T_String const& pipeline , T_String const& pipeline ,
std::string const& name ); T_String const& name );
T_ShaderInput const* getInput( T_ShaderInput const* getInput(
T_String const& name ); T_String const& name );
@ -225,6 +225,6 @@ struct T_ShaderManager
T_ShaderCode& code , T_ShaderCode& code ,
char const* errorLine ); char const* errorLine );
void programUpdated( std::string const& name ); void programUpdated( T_String const& name );
void resetProgram( T_Program_& program ); void resetProgram( T_Program_& program );
}; };