Parser + overrides - Partial parsing of ui-overrides sections
This commit is contained in:
parent
4ac51553bc
commit
3a59078323
4 changed files with 303 additions and 11 deletions
20
demo.srd
20
demo.srd
|
@ -152,20 +152,24 @@
|
|||
(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))
|
||||
(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)
|
||||
(uniforms prog 2
|
||||
|
|
78
opparser.cc
78
opparser.cc
|
@ -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 ) {
|
||||
|
|
207
syncoverrides.cc
207
syncoverrides.cc
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue