#pragma once #ifndef REAL_BUILD # include "externals.hh" #endif struct T_SyncData; namespace cops { struct T_Program; struct T_Context { T_Program const* program; float const* time; T_SyncData const* sync; T_KeyValueTable< T_String , float > vars; T_Array< float > opStack; T_Context& store( T_String const& name , const float value ); }; class X_OpFailure : public std::exception { public: X_OpFailure( ) = delete; DEF_COPY( X_OpFailure ); DEF_MOVE( X_OpFailure ); X_OpFailure( T_String const& source , uint32_t line , T_String&& error ) noexcept; T_String const& source( ) const noexcept { return source_; } uint32_t line( ) const noexcept { return line_; } T_String const& error( ) const noexcept { return error_; } char const* what( ) const noexcept override; private: T_String source_; uint32_t line_; T_String error_; T_String fullMessage_; }; /*--------------------------------------------------------------------*/ enum E_Op { OP_LOAD_CONSTANT , OP_LOAD_VARIABLE , OP_LOAD_INPUT , OP_STORE_VARIABLE , // OP_ADD , OP_MUL , OP_NEG , OP_INV , // OP_DUP , OP_XCHG , // OP_SET_UNIFORM , OP_USE_PIPELINE , OP_USE_TEXTURE , OP_USE_FRAMEBUFFER , OP_SET_VIEWPORT , // OP_CLEAR , OP_FULLSCREEN , // OP_CALL }; struct T_Op { explicit T_Op( const E_Op op ); virtual ~T_Op( ) = 0; E_Op op( ) const noexcept { return op_; } virtual void execute( T_Context& ctx ) const = 0; T_String source{}; uint32_t line{0}; protected: X_OpFailure error( ebcl::T_StringBuilder& message ) const noexcept; X_OpFailure error( T_String const& message ) const noexcept; private: E_Op op_; }; using P_Op = T_OwnPtr< T_Op >; using T_Operations = T_Array< P_Op >; template< typename T > inline T_Operations& operator <<( T_Operations& ops , T&& item ) { ops.add( NewOwned< T >( std::move( item ) ) ); return ops; } void Execute( T_Operations const& operations , T_Context& context ); /*--------------------------------------------------------------------*/ struct T_Function { T_String name; uint32_t arguments; T_Operations operations; T_Function( T_String const& name , const uint32_t arguments ) : name( name ) , arguments( arguments ) { } DEF_COPY( T_Function ); DEF_MOVE( T_Function ); }; struct T_Program { T_ObjectTable< T_String , T_Function > functions; T_Operations main; T_Program( ) : functions( []( T_Function const& f ) -> T_String { return f.name; } ) { } T_Operations& function( T_String const& name , const uint32_t args ); void execute( T_Context& context ) { context.program = this; Execute( main , context ); } }; /*====================================================================*/ struct OPLoadConstant : public T_Op { explicit OPLoadConstant( const float constant ); void execute( T_Context& ctx ) const override; float constant; }; struct OPLoadVariable : public T_Op { explicit OPLoadVariable( T_String const& variable ); void execute( T_Context& ctx ) const override; T_String variable; }; struct OPLoadInput : public T_Op { explicit OPLoadInput( T_String const& input ); void execute( T_Context& ctx ) const override; T_String input; }; struct OPStoreVariable : public T_Op { explicit OPStoreVariable( T_String const& variable ); void execute( T_Context& ctx ) const override; T_String variable; }; /*--------------------------------------------------------------------*/ struct OPAdd : public T_Op { OPAdd( ) : T_Op( OP_ADD ) {} void execute( T_Context& ctx ) const override; }; struct OPMul : public T_Op { OPMul( ) : T_Op( OP_MUL ) {} void execute( T_Context& ctx ) const override; }; struct OPNeg : public T_Op { OPNeg( ) : T_Op( OP_NEG ) {} void execute( T_Context& ctx ) const override; }; struct OPInv : public T_Op { OPInv( ) : T_Op( OP_INV ) {} void execute( T_Context& ctx ) const override; }; /*--------------------------------------------------------------------*/ struct OPDup : public T_Op { explicit OPDup( uint32_t stackIndex = 0 ); void execute( T_Context& ctx ) const override; uint32_t stackIndex; }; struct OPXchg : public T_Op { explicit OPXchg( uint32_t stackIndex = 1 ); void execute( T_Context& ctx ) const override; uint32_t stackIndex; }; /*--------------------------------------------------------------------*/ struct OPSetUniform : public T_Op { OPSetUniform( const uint32_t count , const bool integer ); void execute( T_Context& ctx ) const override; uint32_t count; bool integer; }; struct OPUsePipeline : public T_Op { explicit OPUsePipeline( const uint32_t index ); void execute( T_Context& ctx ) const override; uint32_t pipeline; }; struct OPUseTexture : public T_Op { OPUseTexture( const uint32_t binding , const uint32_t texture , const uint32_t sampler = 0 ); void execute( T_Context& ctx ) const override; uint32_t binding; uint32_t texture; uint32_t sampler; }; struct OPUseFramebuffer : public T_Op { explicit OPUseFramebuffer( const uint32_t framebuffer ); void execute( T_Context& ctx ) const override; uint32_t framebuffer; }; struct OPSetViewport : public T_Op { OPSetViewport( ) : T_Op( OP_SET_VIEWPORT ) { } void execute( T_Context& ctx ) const override; }; /*--------------------------------------------------------------------*/ struct OPClear : public T_Op { OPClear( ) : T_Op( OP_CLEAR ) { } void execute( T_Context& ctx ) const override; }; struct OPFullscreen : public T_Op { OPFullscreen( ) : T_Op( OP_FULLSCREEN ) { } void execute( T_Context& ctx ) const override; }; /*--------------------------------------------------------------------*/ struct OPCall : public T_Op { explicit OPCall( T_String const& function ); void execute( T_Context& ctx ) const override; T_String function; }; } // namespace cops