Parser + overrides - Partial parsing of ui-overrides sections

This commit is contained in:
Emmanuel BENOîT 2017-11-17 14:09:36 +01:00
parent 4ac51553bc
commit 3a59078323
4 changed files with 303 additions and 11 deletions

View file

@ -152,19 +152,23 @@
(input dof-samples 16)
# Input overrides
{ NOT IMPLEMENTED
(ui-overrides
(section "Post-processing"
(section "Depth of Field"
(float dof-sharp-distance (min 0) (max 1000) (step .1))
(float dof-sharp-range (min 0) (max 500) (step .1))
(float dof-falloff (min 0) (max 500) (step .1))
(float dof-max-blur (min 1) (max 64) (step .1))
(ui-overrides
(section "Post-processing"
(section "Depth of Field"
(float "Sharp distance" dof-sharp-distance
(min 0) (max 50000) (step .1))
(float "Sharp range" dof-sharp-range
(min 0) (max 50000) (step .1))
(float "Falloff" dof-falloff
(min 0) (max 50000) (step .1))
(float "Maximum blur" dof-max-blur
(min 1) (max 64) (slider))
{ NOT IMPLEMENTED
(int dof-samples (min 1) (max 64) (step .1))
)
}
)
)
}
)
)
(fn dof-set-uniforms (prog)

View file

@ -2,7 +2,9 @@
#include "opast.hh"
#include "ops.hh"
#include "opcomp.hh"
#include "syncoverrides.hh"
#include <ebcl/Algorithms.hh>
#include <ebcl/SRDParser.hh>
using namespace ebcl;
using namespace opast;
@ -24,6 +26,7 @@ struct T_ParserImpl_
LOCALS ,
MAINOUT ,
ODBG ,
OVERRIDES ,
PIPELINE ,
PROFILE ,
PROGRAM ,
@ -60,6 +63,7 @@ struct T_ParserImpl_
add( "sampler" , E_InstrType::SAMPLER );
add( "set" , E_InstrType::SET );
add( "texture" , E_InstrType::TEXTURE );
add( "ui-overrides" , E_InstrType::OVERRIDES );
add( "uniforms" , E_InstrType::UNIFORMS_FLT );
add( "uniforms-i" , E_InstrType::UNIFORMS_INT );
add( "use-framebuffer" , E_InstrType::USE_FRAMEBUFFER );
@ -153,6 +157,8 @@ struct T_ParserImpl_
T_Array< T_SRDError >& errors;
T_MultiArray< uint32_t > calls;
T_Array< T_InstrRestriction > callInfo;
T_SRDParserConfig ovParserConfig;
T_SRDParser ovParser;
T_Visitor< A_Node > visitor{ opast::ASTVisitorBrowser };
T_Visitor< uint32_t , uint32_t > callGraphVisitor{
@ -231,6 +237,7 @@ struct T_ParserImpl_
M_DPARSER_( Input );
M_DPARSER_( Locals );
M_DPARSER_( ODebug );
M_DPARSER_( Overrides );
M_DPARSER_( Pipeline );
M_DPARSER_( Profile );
M_DPARSER_( Program );
@ -295,7 +302,9 @@ struct T_ParserImpl_
inline T_ParserImpl_::T_ParserImpl_(
T_Array< T_SRDError >* const errors ,
T_OwnPtr< T_OpsParserOutput >* const output ) noexcept
: output( *output ) , errors( *errors )
: output( *output ) , errors( *errors ) ,
ovParserConfig( sov::GetParserConfig( ) ) ,
ovParser( ovParserConfig )
{ }
void T_ParserImpl_::main(
@ -1008,6 +1017,7 @@ void T_ParserImpl_::parseInstructions(
M_CASE_( INPUT , Input );
M_CASE_( LOCALS , Locals );
M_CASE_( ODBG , ODebug );
M_CASE_( OVERRIDES , Overrides );
M_CASE_( PIPELINE , Pipeline );
M_CASE_( PROFILE , Profile );
M_CASE_( PROGRAM , Program );
@ -1323,6 +1333,72 @@ M_INSTR_( ODebug )
/*----------------------------------------------------------------------------*/
M_INSTR_( Overrides )
{
if ( input.size( ) == 1 ) {
errors.addNew( "not enough arguments" , input[ 0 ].location( ) );
return;
}
struct T_StackEntry_ {
T_SRDList const* list;
uint32_t pos;
T_StackEntry_( T_SRDList const* list ,
const uint32_t pos ) noexcept
: list( list ) , pos( pos )
{}
};
T_AutoArray< T_StackEntry_ , 16 > stack;
T_StackEntry_ current{ &input , 1 };
T_SRDErrors ovParserErrors;
bool hadException{ false };
try {
ovParser.start( ovParserErrors );
while ( current.pos < current.list->size( ) || !stack.empty( ) ) {
if ( current.pos == current.list->size( ) ) {
current = stack.last( );
stack.removeLast( );
T_SRDToken ls{ T_SRDToken::ListEnd( ) };
ls.location( (*current.list)[ current.pos ].location( ) );
ovParser.push( ovParserErrors , std::move( ls ) );
current.pos ++;
continue;
}
auto const& src( (*current.list)[ current.pos ] );
if ( src.type( ) == E_SRDTokenType::LIST ) {
T_SRDToken ls{ T_SRDToken::ListStart( ) };
ls.location( src.location( ) );
ovParser.push( ovParserErrors , std::move( ls ) );
stack.add( current );
current = T_StackEntry_{ &src.list( ) , 0 };
} else {
ovParser.push( ovParserErrors , T_SRDToken{ src } );
current.pos ++;
}
}
ovParser.end( ovParserErrors );
} catch ( X_SRDErrors const& e ) {
hadException = true;
}
const auto n{ ovParserErrors.size( ) - ( hadException ? 1 : 0 ) };
if ( n != 0 ) {
for ( auto i = 0u ; i < n ; i ++ ) {
errors.add( ovParserErrors[ i ] );
}
if ( hadException ) {
errors.addNew( "too many errors in UI overrides list" ,
input[ 0 ].location( ) );
}
}
}
/*----------------------------------------------------------------------------*/
M_INSTR_( Pipeline )
{
if ( input.size( ) < 3 ) {

View file

@ -2,6 +2,8 @@
#include "globals.hh"
#include "syncoverrides.hh"
#include <ebcl/SRDParser.hh>
using namespace sov;
#define M_SETOPT_( FIELD , VAR ) \
@ -10,6 +12,211 @@ using namespace sov;
return true
/*= PARSER DEFINITIONS =========================================================*/
namespace {
using namespace ebcl;
using SP_Section = T_SharedPtr< T_SyncOverrideSection >;
bool EnterSection_( T_SRDParserData const& data )
{
*( data.targetData ) = NewShared< T_SyncOverrideSection >( (*data.input)[ 1 ].stringValue( ) );
return true;
}
bool ExitSection_( T_SRDParserData const& data )
{
auto& section( data.currentData->value< SP_Section >( ) );
auto& parent( data.targetData->value< SP_Section >( ) );
if ( section->overrides.empty( ) && section->subsections.empty( ) ) {
T_StringBuilder sb;
sb << "empty section '" << section->title << "'";
data.errors.add( std::move( sb ) , (*data.input)[ 0 ] );
} else {
parent->subsections.add( section.makeOwned( ) );
}
return true;
}
/*------------------------------------------------------------------------------*/
using SP_Float = T_SharedPtr< A_Float >;
bool EnterFloat1_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
SP_Float ptr{ NewShared< T_Float >(
input[ 1 ].stringValue( ) , input[ 2 ].stringValue( ) ) };
*( data.targetData ) = std::move( ptr );
return true;
}
bool EnterFloat2_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
SP_Float ptr{ NewShared< T_Float2 >(
input[ 1 ].stringValue( ) , input[ 2 ].stringValue( ) ,
input[ 3 ].stringValue( ) ) };
*( data.targetData ) = std::move( ptr );
return true;
}
bool EnterFloat3_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
SP_Float ptr{ NewShared< T_Float3 >(
input[ 1 ].stringValue( ) , input[ 2 ].stringValue( ) ,
input[ 3 ].stringValue( ) , input[ 4 ].stringValue( ) ) };
*( data.targetData ) = std::move( ptr );
return true;
}
bool EnterFloat4_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
SP_Float ptr{ NewShared< T_Float4 >(
input[ 1 ].stringValue( ) , input[ 2 ].stringValue( ) ,
input[ 3 ].stringValue( ) , input[ 4 ].stringValue( ) ,
input[ 5 ].stringValue( ) ) };
*( data.targetData ) = std::move( ptr );
return true;
}
bool AddFloat_( T_SRDParserData const& data )
{
auto& fl( data.currentData->value< SP_Float >( ) );
auto& parent( data.targetData->value< SP_Section >( ) );
if ( fl->min( ) > fl->max( ) ) {
data.errors.add( "invalid bounds" , (*data.input)[ 0 ] );
}
parent->overrides.add( fl.makeOwned( ) );
return true;
}
/*------------------------------------------------------------------------------*/
bool FloatSetSlider_( T_SRDParserData const& data )
{
data.currentData->value< SP_Float >( )->setSlider( );
return true;
}
bool FloatSetMin_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
if ( !data.currentData->value< SP_Float >( )->setMin( input[ 1 ].floatValue( ) ) ) {
data.errors.add( "duplicate minimal value" , (*data.input)[ 0 ] );
}
return true;
}
bool FloatSetMax_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
if ( !data.currentData->value< SP_Float >( )->setMax( input[ 1 ].floatValue( ) ) ) {
data.errors.add( "duplicate maximal value" , (*data.input)[ 0 ] );
}
return true;
}
bool FloatSetStep_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
const auto v( input[ 1 ].floatValue( ) );
if ( v <= 0 ) {
data.errors.add( "invalid step value" , (*data.input)[ 1 ] );
} else if ( !data.currentData->value< SP_Float >( )->setStep( v ) ) {
data.errors.add( "duplicate step value" , (*data.input)[ 0 ] );
}
return true;
}
bool FloatSetPower_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
const auto v( input[ 1 ].floatValue( ) );
if ( v <= 0 ) {
data.errors.add( "invalid power value" , (*data.input)[ 1 ] );
} else if ( !data.currentData->value< SP_Float >( )->setPower( v ) ) {
data.errors.add( "duplicate power value" , (*data.input)[ 0 ] );
}
return true;
}
bool FloatSetDecimals_( T_SRDParserData const& data )
{
auto const& input( *( data.input ) );
const auto v( input[ 1 ].longValue( ) );
if ( v < 0 || v > 10 ) {
data.errors.add( "invalid decimals value" , (*data.input)[ 1 ] );
} else if ( !data.currentData->value< SP_Float >( )->setDecimals( v ) ) {
data.errors.add( "duplicate decimals value" , (*data.input)[ 0 ] );
}
return true;
}
} // namespace
/*------------------------------------------------------------------------------*/
ebcl::T_SRDParserConfig sov::GetParserConfig( )
{
using namespace ebcl;
using namespace ebcl::SRD;
T_SRDParserDefs defs( "root" );
defs << OnStart( []( T_SRDParserData const& data ) -> bool {
*( data.currentData ) = NewShared< T_SyncOverrideSection >( "*" );
return true;
} );
defs.context( "root" )
<< ( Rule() << "section" << Text( ) << EnterContext( "section" )
<< OnEnter( EnterSection_ )
<< OnExit( ExitSection_ ) )
;
defs.context( "section" )
<< ( Rule() << "section" << Text( ) << EnterContext( "section" ) )
// Floating point controls
<< ( Rule() << "float" << Text( ) << Word( )
<< EnterContext( "float" )
<< OnEnter( EnterFloat1_ )
<< OnExit( AddFloat_ ) )
<< ( Rule() << "float2" << Text( )
<< ( SRD::Times( 2 ) << Word( ) )
<< EnterContext( "float" )
<< OnEnter( EnterFloat2_ )
<< OnExit( AddFloat_ ) )
<< ( Rule() << "float3" << Text( )
<< ( SRD::Times( 3 ) << Word( ) )
<< EnterContext( "float" )
<< OnEnter( EnterFloat3_ )
<< OnExit( AddFloat_ ) )
<< ( Rule() << "float4" << Text( )
<< ( SRD::Times( 4 ) << Word( ) )
<< EnterContext( "float" )
<< OnEnter( EnterFloat4_ )
<< OnExit( AddFloat_ ) )
;
// Floating point control parameters
defs.context( "float" )
<< ( Rule() << "slider" << FloatSetSlider_ )
<< ( Rule() << "min" << Numeric() << FloatSetMin_ )
<< ( Rule() << "max" << Numeric() << FloatSetMax_ )
<< ( Rule() << "step" << Numeric() << FloatSetStep_ )
<< ( Rule() << "power" << Numeric() << FloatSetPower_ )
<< ( Rule() << "decimals" << Integer() << FloatSetDecimals_ )
;
return T_SRDParserConfig{ defs };
}
/*= A_Float ====================================================================*/
bool A_Float::setMin(

View file

@ -88,5 +88,10 @@ class T_Float4 : public A_Float
};
/*= PARSER CONFIGURATION =======================================================*/
// Get a parser configuration that will be able to parse UI override definitions.
ebcl::T_SRDParserConfig GetParserConfig( );
} // namespace