demotool/demo.cc

180 lines
4.1 KiB
C++

#include "externals.hh"
#include "demo.hh"
#include "sync.hh"
#include "rendertarget.hh"
#include "globals.hh"
#include <ebcl/Files.hh>
#include <ebcl/SRDText.hh>
T_Demo::T_Demo( const uint32_t width ,
const uint32_t height )
: width( width ) , height( height )
{ }
bool T_Demo::initialise( )
{
if ( !program ) {
loadProgram( );
}
return true;
}
void T_Demo::render( )
{
if ( program && !context ) {
runInit( );
}
auto& sync( Globals::Sync( ) );
if ( playing ) {
const float time = SDL_GetTicks( ) * 1e-3;
if ( playingPrevious ) {
sync.timeDelta( time - lastFrame );
playing = !sync.finished( );
}
lastFrame = time;
}
playingPrevious = playing;
if ( context && !context->aborted ) {
try {
context->run( ops::T_OpContext::R_RENDER , sync.time( ) , width , height );
} catch ( ops::X_OpFailure const& fail ) {
printf( "FAILED TO RUN FRAME!\n\t%s\n" , fail.what( ) );
context->aborted = true;
}
}
}
void T_Demo::handleDND(
ImVec2 const& move ,
const bool hasCtrl ,
const bool hasShift ,
const bool lmb // Left mouse button
)
{
}
void T_Demo::handleWheel(
const float wheel ,
const bool hasCtrl ,
const bool hasShift
)
{
}
namespace {
/*============================================================================*/
void PrintStreamError(
char const* const prefix ,
T_String const& name ,
ebcl::X_StreamError const& error )
{
T_StringBuilder sb;
sb << prefix << " '" << name << "': " << error.what( );
if ( error.code( ) == ebcl::E_StreamError::SYSTEM_ERROR ) {
sb << " (error code " << error.systemError( ) << ")";
}
sb << '\n' << '\0';
fprintf( stderr , "%s" , sb.data( ) );
}
void WriteSRDError(
T_StringBuilder& sb ,
ebcl::T_SRDError const& error )
{
sb << error.location( ) << " - " << error.error( ) << "\n";
}
/*============================================================================*/
} // namespace
bool T_Demo::loadProgram( )
{
using namespace ebcl;
const T_String inputName( T_String::Pooled( "demo.srd" ) );
T_File input( inputName , E_FileMode::READ_ONLY );
try {
input.open( );
} catch ( X_StreamError const& e ) {
PrintStreamError( "Could not open" , inputName , e );
return false;
}
// Load SRD data
T_SRDMemoryTarget srdOut;
srdOut.clearComments( true ).clearFlushToken( true );
try {
T_SRDTextReader srdReader{ srdOut };
T_FileInputStream fis{ input };
srdReader.read( inputName , fis );
} catch ( X_StreamError const& e ) {
PrintStreamError( "Could not open" , inputName , e );
return false;
} catch ( X_SRDErrors const& e ) {
T_StringBuilder sb;
const auto nErrors( e.errors.size( ) );
for ( auto i = 0u ; i < nErrors ; i ++ ) {
WriteSRDError( sb , e.errors[ i ] );
}
sb << "No parsing happened due to format errors\n" << '\0';
fprintf( stderr , "%s" , sb.data( ) );
return false;
}
// Parse the fuck
opast::T_Parser parser;
if ( parser.parse( srdOut.list( ) ) ) {
printf( "Parser successful. Compiling...\n" );
ops::T_Compiler compiler;
program = compiler.compile( *parser.result( ) );
return true;
}
T_StringBuilder sb;
sb << "- PARSE ERRORS -------------------------\n";
const auto nErrors( parser.errors( ).size( ) );
for ( auto i = 0u ; i < nErrors ; i ++ ) {
WriteSRDError( sb , parser.errors( )[ i ] );
}
sb << "----------------------------------------\n";
sb << '\0';
fprintf( stderr , "%s" , sb.data( ) );
return false;
}
void T_Demo::runInit( )
{
context = NewOwned< ops::T_OpContext >( *program );
try {
context->run( ops::T_OpContext::R_INIT , 0 , width , height );
} catch ( ops::X_OpFailure const& fail ) {
printf( "FAILED TO RUN INIT!\n\t%s\n" , fail.what( ) );
context->aborted = true;
return;
}
Globals::Sync( ).clearInputs( );
const auto n( context->initialInputs.size( ) );
assert( n == program->inputs.size( ) );
for ( auto i = 0u ; i < n ; i ++ ) {
Globals::Sync( ).addInput( program->inputs[ i ] ,
context->initialInputs[ i ] );
#ifdef INVASIVE_TRACES
printf( "#%d %s pos %d\n" , i , program->inputs[ i ].toOSString( ).data( ) ,
Globals::Sync( ).inputPos( program->inputs[ i ] ) );
#endif //INVASIVE_TRACES
}
Globals::Sync( ).updateCurveCaches( );
}