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,19 +152,23 @@
|
||||||
(input dof-samples 16)
|
(input dof-samples 16)
|
||||||
|
|
||||||
# Input overrides
|
# Input overrides
|
||||||
{ NOT IMPLEMENTED
|
|
||||||
(ui-overrides
|
(ui-overrides
|
||||||
(section "Post-processing"
|
(section "Post-processing"
|
||||||
(section "Depth of Field"
|
(section "Depth of Field"
|
||||||
(float dof-sharp-distance (min 0) (max 1000) (step .1))
|
(float "Sharp distance" dof-sharp-distance
|
||||||
(float dof-sharp-range (min 0) (max 500) (step .1))
|
(min 0) (max 50000) (step .1))
|
||||||
(float dof-falloff (min 0) (max 500) (step .1))
|
(float "Sharp range" dof-sharp-range
|
||||||
(float dof-max-blur (min 1) (max 64) (step .1))
|
(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))
|
(int dof-samples (min 1) (max 64) (step .1))
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
(fn dof-set-uniforms (prog)
|
(fn dof-set-uniforms (prog)
|
||||||
|
|
78
opparser.cc
78
opparser.cc
|
@ -2,7 +2,9 @@
|
||||||
#include "opast.hh"
|
#include "opast.hh"
|
||||||
#include "ops.hh"
|
#include "ops.hh"
|
||||||
#include "opcomp.hh"
|
#include "opcomp.hh"
|
||||||
|
#include "syncoverrides.hh"
|
||||||
#include <ebcl/Algorithms.hh>
|
#include <ebcl/Algorithms.hh>
|
||||||
|
#include <ebcl/SRDParser.hh>
|
||||||
|
|
||||||
using namespace ebcl;
|
using namespace ebcl;
|
||||||
using namespace opast;
|
using namespace opast;
|
||||||
|
@ -24,6 +26,7 @@ struct T_ParserImpl_
|
||||||
LOCALS ,
|
LOCALS ,
|
||||||
MAINOUT ,
|
MAINOUT ,
|
||||||
ODBG ,
|
ODBG ,
|
||||||
|
OVERRIDES ,
|
||||||
PIPELINE ,
|
PIPELINE ,
|
||||||
PROFILE ,
|
PROFILE ,
|
||||||
PROGRAM ,
|
PROGRAM ,
|
||||||
|
@ -60,6 +63,7 @@ struct T_ParserImpl_
|
||||||
add( "sampler" , E_InstrType::SAMPLER );
|
add( "sampler" , E_InstrType::SAMPLER );
|
||||||
add( "set" , E_InstrType::SET );
|
add( "set" , E_InstrType::SET );
|
||||||
add( "texture" , E_InstrType::TEXTURE );
|
add( "texture" , E_InstrType::TEXTURE );
|
||||||
|
add( "ui-overrides" , E_InstrType::OVERRIDES );
|
||||||
add( "uniforms" , E_InstrType::UNIFORMS_FLT );
|
add( "uniforms" , E_InstrType::UNIFORMS_FLT );
|
||||||
add( "uniforms-i" , E_InstrType::UNIFORMS_INT );
|
add( "uniforms-i" , E_InstrType::UNIFORMS_INT );
|
||||||
add( "use-framebuffer" , E_InstrType::USE_FRAMEBUFFER );
|
add( "use-framebuffer" , E_InstrType::USE_FRAMEBUFFER );
|
||||||
|
@ -153,6 +157,8 @@ struct T_ParserImpl_
|
||||||
T_Array< T_SRDError >& errors;
|
T_Array< T_SRDError >& errors;
|
||||||
T_MultiArray< uint32_t > calls;
|
T_MultiArray< uint32_t > calls;
|
||||||
T_Array< T_InstrRestriction > callInfo;
|
T_Array< T_InstrRestriction > callInfo;
|
||||||
|
T_SRDParserConfig ovParserConfig;
|
||||||
|
T_SRDParser ovParser;
|
||||||
|
|
||||||
T_Visitor< A_Node > visitor{ opast::ASTVisitorBrowser };
|
T_Visitor< A_Node > visitor{ opast::ASTVisitorBrowser };
|
||||||
T_Visitor< uint32_t , uint32_t > callGraphVisitor{
|
T_Visitor< uint32_t , uint32_t > callGraphVisitor{
|
||||||
|
@ -231,6 +237,7 @@ struct T_ParserImpl_
|
||||||
M_DPARSER_( Input );
|
M_DPARSER_( Input );
|
||||||
M_DPARSER_( Locals );
|
M_DPARSER_( Locals );
|
||||||
M_DPARSER_( ODebug );
|
M_DPARSER_( ODebug );
|
||||||
|
M_DPARSER_( Overrides );
|
||||||
M_DPARSER_( Pipeline );
|
M_DPARSER_( Pipeline );
|
||||||
M_DPARSER_( Profile );
|
M_DPARSER_( Profile );
|
||||||
M_DPARSER_( Program );
|
M_DPARSER_( Program );
|
||||||
|
@ -295,7 +302,9 @@ struct T_ParserImpl_
|
||||||
inline T_ParserImpl_::T_ParserImpl_(
|
inline T_ParserImpl_::T_ParserImpl_(
|
||||||
T_Array< T_SRDError >* const errors ,
|
T_Array< T_SRDError >* const errors ,
|
||||||
T_OwnPtr< T_OpsParserOutput >* const output ) noexcept
|
T_OwnPtr< T_OpsParserOutput >* const output ) noexcept
|
||||||
: output( *output ) , errors( *errors )
|
: output( *output ) , errors( *errors ) ,
|
||||||
|
ovParserConfig( sov::GetParserConfig( ) ) ,
|
||||||
|
ovParser( ovParserConfig )
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void T_ParserImpl_::main(
|
void T_ParserImpl_::main(
|
||||||
|
@ -1008,6 +1017,7 @@ void T_ParserImpl_::parseInstructions(
|
||||||
M_CASE_( INPUT , Input );
|
M_CASE_( INPUT , Input );
|
||||||
M_CASE_( LOCALS , Locals );
|
M_CASE_( LOCALS , Locals );
|
||||||
M_CASE_( ODBG , ODebug );
|
M_CASE_( ODBG , ODebug );
|
||||||
|
M_CASE_( OVERRIDES , Overrides );
|
||||||
M_CASE_( PIPELINE , Pipeline );
|
M_CASE_( PIPELINE , Pipeline );
|
||||||
M_CASE_( PROFILE , Profile );
|
M_CASE_( PROFILE , Profile );
|
||||||
M_CASE_( PROGRAM , Program );
|
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 )
|
M_INSTR_( Pipeline )
|
||||||
{
|
{
|
||||||
if ( input.size( ) < 3 ) {
|
if ( input.size( ) < 3 ) {
|
||||||
|
|
207
syncoverrides.cc
207
syncoverrides.cc
|
@ -2,6 +2,8 @@
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "syncoverrides.hh"
|
#include "syncoverrides.hh"
|
||||||
|
|
||||||
|
#include <ebcl/SRDParser.hh>
|
||||||
|
|
||||||
using namespace sov;
|
using namespace sov;
|
||||||
|
|
||||||
#define M_SETOPT_( FIELD , VAR ) \
|
#define M_SETOPT_( FIELD , VAR ) \
|
||||||
|
@ -10,6 +12,211 @@ using namespace sov;
|
||||||
return true
|
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 ====================================================================*/
|
/*= A_Float ====================================================================*/
|
||||||
|
|
||||||
bool A_Float::setMin(
|
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
|
} // namespace
|
||||||
|
|
Loading…
Reference in a new issue