diff --git a/Makefile b/Makefile index 3d10813..65c67c8 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,6 @@ COMMON = \ camera.cc \ \ filewatcher.cc \ - window.cc \ globals.cc \ profiling.cc \ shaders.cc \ @@ -47,6 +46,7 @@ COMMON = \ ui-sequencer.cc \ ui-sync.cc \ ui-utilities.cc \ + ui-app.cc \ # END COMMON DEMO = \ @@ -147,7 +147,7 @@ $(PCH): externals.hh #------------------------------------------------------------------------------- -$(OUTDIR)/window.o: window.cc $(OUTDIR)/font-awesome.inl +$(OUTDIR)/ui-app.o: ui-app.cc $(OUTDIR)/font-awesome.inl $(OUTDIR)/font-awesome.inl: 3rdparty/font-awesome/fonts/fontawesome-webfont.ttf $(OUTDIR)/font-to-c $(OUTDIR)/font-to-c -base85 3rdparty/font-awesome/fonts/fontawesome-webfont.ttf \ diff --git a/control.cc b/control.cc deleted file mode 100644 index f5916c3..0000000 --- a/control.cc +++ /dev/null @@ -1,423 +0,0 @@ -#include "externals.hh" -#include "ops.hh" -#include "globals.hh" -#include "sync.hh" - -using namespace cops; - - -/*= Command execution ========================================================*/ - -void cops::Execute( - T_Operations const& operations , - T_Context& context ) -{ - for ( auto const& op : operations ) { - op->execute( context ); - } -} - -T_Operations& T_Program::function( - T_String const& name , - const uint32_t args ) -{ - T_Function* op( functions.get( name ) ); - if ( !op ) { - functions.add( T_Function{ name , args } ); - op = functions.get( name ); - } - assert( op->arguments == args ); - return op->operations; -} - - -/*= X_OpFailure ==============================================================*/ - -X_OpFailure::X_OpFailure( - T_String const& source , - uint32_t line , - T_String&& error ) noexcept - : std::exception( ) , source_( source ) , line_( line ) , - error_( std::move( error ) ) -{ - ebcl::T_StringBuilder sb; - sb << "Program error (" << source << ", l. " << line << "): " << error - << '\0'; - fullMessage_ = std::move( sb ); -} - -char const* X_OpFailure::what( ) const noexcept -{ - return fullMessage_.data( ); -} - - -/*= T_Context ================================================================*/ - -T_Context& T_Context::store( - T_String const& name , - const float value ) -{ - vars.set( name , value ); - return *this; -} - - -/*= T_Op =====================================================================*/ - -T_Op::T_Op( const E_Op op ) - : op_( op ) -{ } - -T_Op::~T_Op( ) { } - - -X_OpFailure T_Op::error( - ebcl::T_StringBuilder& message ) const noexcept -{ - return X_OpFailure( source , line , std::move( message ) ); -} - -X_OpFailure T_Op::error( - T_String const& message ) const noexcept -{ - return X_OpFailure( source , line , T_String( message ) ); -} - - -/*= OPLoadConstant ===========================================================*/ - -OPLoadConstant::OPLoadConstant( - const float constant ) - : T_Op( OP_LOAD_CONSTANT ) , constant( constant ) -{ } - -void OPLoadConstant::execute( - T_Context& ctx ) const -{ - ctx.opStack.add( constant ); -} - - -/*= OPLoadVariable ===========================================================*/ - -OPLoadVariable::OPLoadVariable( - T_String const& variable ) - : T_Op( OP_LOAD_VARIABLE ) , variable( variable ) -{ } - -void OPLoadVariable::execute( - T_Context& ctx ) const -{ - auto const* v( ctx.vars.get( variable ) ); - if ( !v ) { - ebcl::T_StringBuilder sb; - sb << "variable '" << variable << "' not found" << '\0'; - throw error( sb ); - } - ctx.opStack.add( *v ); -} - - -/*= OPLoadInput ==============================================================*/ - -OPLoadInput::OPLoadInput( - T_String const& input ) - : T_Op( OP_LOAD_VARIABLE ) , input( input ) -{ } - -void OPLoadInput::execute( - T_Context& ctx ) const -{ - const auto i( Globals::Sync( ).inputPos( input ) ); - ctx.opStack.add( Globals::Sync( ).inputs( )[ i ] ); -} - - -/*= OPStoreVariable ==========================================================*/ - -OPStoreVariable::OPStoreVariable( - T_String const& variable ) - : T_Op( OP_LOAD_VARIABLE ) , variable( variable ) -{ } - -void OPStoreVariable::execute( - T_Context& ctx ) const -{ - if ( ctx.opStack.empty( ) ) { - throw error( "stack is empty" ); - } - - ctx.store( variable , ctx.opStack.last( ) ); - ctx.opStack.removeLast( ); -} - - -/*= Arithmetic operators =====================================================*/ - -void OPAdd::execute( - T_Context& ctx ) const -{ - if ( ctx.opStack.size( ) < 2 ) { - throw error( "missing operands in stack" ); - } - const float v( ctx.opStack.last( ) ); - ctx.opStack.removeLast( ); - ctx.opStack.last( ) += v; -} - -void OPMul::execute( - T_Context& ctx ) const -{ - if ( ctx.opStack.size( ) < 2 ) { - throw error( "missing operands in stack" ); - } - const float v( ctx.opStack.last( ) ); - ctx.opStack.removeLast( ); - ctx.opStack.last( ) *= v; -} - -void OPNeg::execute( - T_Context& ctx ) const -{ - if ( ctx.opStack.empty( ) ) { - throw error( "missing operand in stack" ); - } - ctx.opStack.last( ) = -ctx.opStack.last( ); -} - -void OPInv::execute( - T_Context& ctx ) const -{ - if ( ctx.opStack.empty( ) || ctx.opStack.last( ) == 0 ) { - throw error( "missing operand in stack" ); - } - ctx.opStack.last( ) = 1.0f / ctx.opStack.last( ); -} - - -/*= Stack operations =========================================================*/ - -OPDup::OPDup( const uint32_t stackIndex ) - : T_Op( OP_DUP ) , stackIndex( stackIndex ) -{ } - -void OPDup::execute( - T_Context& ctx ) const -{ - if ( ctx.opStack.size( ) <= stackIndex ) { - ebcl::T_StringBuilder sb; - sb << "stack does not have " << ( stackIndex + 1 ) - << " items (only " << ctx.opStack.size( ) << ")"; - throw error( sb ); - } - ctx.opStack.add( *( ctx.opStack.end( ) - stackIndex - 1 ) ); -} - -/*----------------------------------------------------------------------------*/ - -OPXchg::OPXchg( const uint32_t stackIndex ) - : T_Op( OP_XCHG ) , stackIndex( stackIndex ) -{ } - -void OPXchg::execute( - T_Context& ctx ) const -{ - if ( ctx.opStack.size( ) <= stackIndex ) { - ebcl::T_StringBuilder sb( "stack does not have " ); - sb << ( stackIndex + 1 ) << " items"; - throw error( sb ); - } - if ( stackIndex ) { - std::swap( *( ctx.opStack.end( ) - 1 ) , *( ctx.opStack.end( ) - stackIndex - 1 ) ); - } -} - - -/*= OPSetUniform =============================================================*/ - -// GENERAL FIXME -// program identifier should be an entry in a table -// or, you know, a program name - -OPSetUniform::OPSetUniform( - const uint32_t count , - const bool integer ) - : T_Op( OP_SET_UNIFORM ) , count( count ) , integer( integer ) -{ } - -void OPSetUniform::execute( - T_Context& ctx ) const -{ - if ( count == 0 || ctx.opStack.size( ) < count + 2 ) { - ebcl::T_StringBuilder sb( "stack does not have " ); - sb << ( count + 2 ) << " items"; - throw error( sb ); - } - - typedef void (*F_SetUniform_)( int , int , int , void* ); - void const* const funcs[] = { - &glProgramUniform1fv , &glProgramUniform2fv , &glProgramUniform3fv , &glProgramUniform4fv , - &glProgramUniform1iv , &glProgramUniform2iv , &glProgramUniform3iv , &glProgramUniform4iv , - }; - const F_SetUniform_ func{ *(F_SetUniform_*) funcs[ count + ( integer ? 4 : 0 ) - 1 ] }; - - const GLuint program( ctx.opStack.last( ) ); - ctx.opStack.removeLast( ); - const GLuint uniform( ctx.opStack.last( ) ); - ctx.opStack.removeLast( ); - - if ( integer ) { - int values[ count ]; - auto i = count; - while ( i != 0 ) { - values[ count - i ] = int( ctx.opStack.last( ) ); - ctx.opStack.removeLast( ); - i --; - } - func( program , uniform , 1 , values ); - } else { - float values[ count ]; - auto i = count; - while ( i != 0 ) { - values[ count - i ] = ctx.opStack.last( ); - ctx.opStack.removeLast( ); - i --; - } - func( program , uniform , 1 , values ); - } -} - - -/*= OPUsePipeline ============================================================*/ - -// GENERAL FIXME -// pipeline identifier should be an entry in a table -// or, you know, a program name - -OPUsePipeline::OPUsePipeline( - const uint32_t index ) - : T_Op( OP_USE_PIPELINE ) , pipeline( index ) -{ } - -void OPUsePipeline::execute( - T_Context& ) const -{ - glBindProgramPipeline( pipeline ); -} - - -/*= OPUseTexture =============================================================*/ - -// GENERAL FIXME -// texture & sampler identifiers should be entries in a table - -OPUseTexture::OPUseTexture( - const uint32_t binding , - const uint32_t texture , - const uint32_t sampler ) - : T_Op( OP_USE_TEXTURE ) , binding( binding ) , - texture( texture ) , sampler( sampler ) -{ } - -void OPUseTexture::execute( - T_Context& ) const -{ - glBindTextureUnit( binding , texture ); - glBindSampler( binding , sampler ); -} - - -/*= OPUseFramebuffer =========================================================*/ - -// GENERAL FIXME -// framebuffer identifier should be an entry in a table - -OPUseFramebuffer::OPUseFramebuffer( - const uint32_t framebuffer ) - : T_Op( OP_USE_FRAMEBUFFER ) , framebuffer( framebuffer ) -{ } - -void OPUseFramebuffer::execute( - T_Context& ) const -{ - glBindFramebuffer( GL_FRAMEBUFFER , framebuffer ); -} - - -/*= OPSetViewport ============================================================*/ - -void OPSetViewport::execute( - T_Context& ctx ) const -{ - if ( ctx.opStack.size( ) < 4 ) { - throw error( "stack does not have 4 items" ); - } - glViewport( - *( ctx.opStack.end( ) - 1 ) , - *( ctx.opStack.end( ) - 2 ) , - *( ctx.opStack.end( ) - 3 ) , - *( ctx.opStack.end( ) - 4 ) ); - ctx.opStack.resize( ctx.opStack.size( ) - 4 ); -} - - -/*= Draw commands ============================================================*/ - -void OPClear::execute( - T_Context& ctx ) const -{ - if ( ctx.opStack.size( ) < 4 ) { - throw error( "stack does not have 4 items" ); - } - glClearColor( - *( ctx.opStack.end( ) - 1 ) , - *( ctx.opStack.end( ) - 2 ) , - *( ctx.opStack.end( ) - 3 ) , - *( ctx.opStack.end( ) - 4 ) ); - ctx.opStack.resize( ctx.opStack.size( ) - 4 ); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); -} - -void OPFullscreen::execute( - T_Context& ) const -{ - glBindVertexArray( 0 ); - glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 ); -} - - -/*= Flow control =============================================================*/ - -OPCall::OPCall( - T_String const& function ) - : T_Op( OP_CALL ) , function( function ) -{ } - -void OPCall::execute( - T_Context& ctx ) const -{ - auto const* fp( ctx.program->functions.get( function ) ); - if ( !fp ) { - ebcl::T_StringBuilder sb( "function '" ); - sb << function << "' not found" << '\0'; - throw error( sb ); - } - - auto const& func( *fp ); - const auto ssz( ctx.opStack.size( ) ); - if ( ssz < func.arguments ) { - ebcl::T_StringBuilder sb( "function '" ); - sb << function << "' requires " << func.arguments << " argument" - << ( func.arguments > 1 ? "s" : "" ) << '\0'; - throw error( sb ); - } - - Execute( func.operations , ctx ); - if ( ctx.opStack.size( ) < ssz ) { - ebcl::T_StringBuilder sb( "function '" ); - sb << function << "' ate the stack" << '\0'; - throw error( sb ); - } - ctx.opStack.resize( ssz - func.arguments ); -} diff --git a/main.cc b/main.cc index 6daba33..c420b81 100644 --- a/main.cc +++ b/main.cc @@ -3,13 +3,13 @@ #include "demo.hh" #include "globals.hh" #include "profiling.hh" -#include "window.hh" #include "shaders.hh" #include "odbg.hh" #include "opemu.hh" #include "rendertarget.hh" #include "sync.hh" #include "ui.hh" +#include "ui-app.hh" #include "ui-sequencer.hh" #include "ui-sync.hh" #include "ui-utilities.hh" @@ -96,7 +96,7 @@ void T_Main::mainLoop( ) makeUI( ); render( ); p.end( "Full frame" ); - UI::Window( ).swap( ); + UI::Main( ).swap( ); p.endFrame( ); } } @@ -145,7 +145,7 @@ void T_Main::startIteration( ) } } - UI::Window( ).startFrame( capture , mouseInitial ); + UI::Main( ).startFrame( capture , mouseInitial ); ImGui::GetIO( ).MouseDrawCursor = true; } @@ -187,7 +187,7 @@ void T_Main::handleCapture( ) capture = false; CaptureMouseFromApp( false ); SDL_SetRelativeMouseMode( SDL_FALSE ); - UI::Window( ).warpMouse( mouseInitial ); + UI::Main( ).warpMouse( mouseInitial ); SetMouseCursor( ImGuiMouseCursor_Arrow ); } else if ( capture ) { SetMouseCursor( ImGuiMouseCursor_Move ); @@ -212,8 +212,8 @@ void T_Main::makeUI( ) bool eSequencer{ sequencer }; if ( BeginMainMenuBar( ) ) { if ( BeginMenu( "File" ) ) { - UI::Window( ).actionMenu( "Save curves" ); - UI::Window( ).actionMenu( "Reload curves" ); + UI::Main( ).actionMenu( "Save curves" ); + UI::Main( ).actionMenu( "Reload curves" ); Separator( ); if ( MenuItem( "Undo" , "C-z" , false , undo.canUndo( ) ) ) { undo.undo( ); @@ -275,7 +275,7 @@ void T_Main::render( ) glClear( GL_COLOR_BUFFER_BIT ); } - UI::Window( ).handleDialogs( ); + UI::Main( ).handleDialogs( ); glUseProgram( 0 ); glBindProgramPipeline( 0 ); UI::Textures( ).reset( ); diff --git a/window.cc b/ui-app.cc similarity index 87% rename from window.cc rename to ui-app.cc index 6822591..5b0d3f8 100644 --- a/window.cc +++ b/ui-app.cc @@ -1,11 +1,11 @@ #include "externals.hh" -#include "window.hh" +#include "ui-app.hh" #include "ui-imgui-sdl.hh" #include -/*= T_Window =================================================================*/ +/*= T_UIApp =================================================================*/ namespace { #include "font-awesome.inl" @@ -17,7 +17,7 @@ static const ImWchar IconsRanges_[] = { }; } // namespace -T_Window::T_Window( ) +T_UIApp::T_UIApp( ) { SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ); @@ -73,7 +73,7 @@ T_Window::T_Window( ) } } -T_Window::~T_Window( ) +T_UIApp::~T_UIApp( ) { ImGui_ImplSdl_Shutdown( ); SDL_GL_DeleteContext( gl ); @@ -81,13 +81,13 @@ T_Window::~T_Window( ) SDL_Quit( ); } -void T_Window::addAction( +void T_UIApp::addAction( T_UIAction action ) noexcept { actions_.set( std::move( action ) ); } -void T_Window::actionMenu( +void T_UIApp::actionMenu( T_String const& id ) const noexcept { auto const* const a{ actions_.get( id ) }; @@ -96,7 +96,7 @@ void T_Window::actionMenu( } } -void T_Window::actionButton( +void T_UIApp::actionButton( T_String const& id ) const noexcept { auto const* const a{ actions_.get( id ) }; @@ -105,25 +105,25 @@ void T_Window::actionButton( } } -void T_Window::startFrame( +void T_UIApp::startFrame( const bool capture , ImVec2 const& mouseInitial ) const { ImGui_ImplSdl_NewFrame( window , capture , mouseInitial ); } -void T_Window::warpMouse( +void T_UIApp::warpMouse( ImVec2 const& pos ) const { SDL_WarpMouseInWindow( window , pos.x , pos.y ); } -void T_Window::swap( ) const +void T_UIApp::swap( ) const { SDL_GL_SwapWindow( window ); } -void T_Window::handleDialogs( ) noexcept +void T_UIApp::handleDialogs( ) noexcept { const auto nDialogs{ modals_.size( ) }; for ( auto i = 0u ; i < nDialogs ; i ++ ) { diff --git a/window.hh b/ui-app.hh similarity index 97% rename from window.hh rename to ui-app.hh index 176da4e..2517000 100644 --- a/window.hh +++ b/ui-app.hh @@ -6,10 +6,10 @@ /*= WINDOW MANAGEMENT ========================================================*/ -struct T_Window +struct T_UIApp { - T_Window( ); - ~T_Window( ); + T_UIApp( ); + ~T_UIApp( ); //---------------------------------------------------------------------- diff --git a/ui-sequencer.cc b/ui-sequencer.cc index b49151d..1f4c90d 100644 --- a/ui-sequencer.cc +++ b/ui-sequencer.cc @@ -2,9 +2,9 @@ #include "ui-sequencer.hh" #include "sync.hh" #include "globals.hh" -#include "window.hh" #include "syncedit.hh" #include "ui.hh" +#include "ui-app.hh" #include "ui-utilities.hh" #define IMGUI_DEFINE_MATH_OPERATORS @@ -327,7 +327,7 @@ void T_SyncViewImpl_::displayToolbar( ) noexcept ToolbarSeparator( ); if ( ToolbarButton( ICON_FA_CLOCK_O , BtSize , "Change duration and time units." ) ) { - UI::Window( ).pushDialog( NewOwned< T_ChangeDurationDialog_ >( + UI::Main( ).pushDialog( NewOwned< T_ChangeDurationDialog_ >( sync.durationUnits( ) , sync.durationUnitSize( ) ) ); } @@ -500,7 +500,7 @@ void T_SyncViewImpl_::sequencerHeader( GetColorU32( ImVec4{ 1 , 1 , 1 , .5 } ) ); } - PushFont( UI::Window( ).smallFont( ) ); + PushFont( UI::Main( ).smallFont( ) ); PushStyleColor( ImGuiCol_Text , ColHeaderText ); auto pos{ startBarPos }; auto bar{ startBar }; diff --git a/ui-sync.cc b/ui-sync.cc index 5dd2dd7..0fc3712 100644 --- a/ui-sync.cc +++ b/ui-sync.cc @@ -2,19 +2,19 @@ #include "globals.hh" #include "ui.hh" #include "ui-actions.hh" +#include "ui-app.hh" #include "ui-overrides.hh" #include "ui-sync.hh" #include "ui-utilities.hh" -#include "window.hh" /*= T_UISync =================================================================*/ T_UISync::T_UISync( ) { - UI::Window( ).newAction( "Save curves" , []() { + UI::Main( ).newAction( "Save curves" , []() { if ( Globals::Sync( ).curvesFileChanged( ) ) { - UI::Window( ).msgbox( + UI::Main( ).msgbox( "Curves file changed" , "The file containing the curves has been modified " "on the disk. These changes will be overwritten. " @@ -32,8 +32,8 @@ T_UISync::T_UISync( ) } ).setIcon( ICON_FA_FLOPPY_O ) .setShortcut( T_KeyboardShortcut{ 's' , E_KeyboardModifier::CTRL } ); //----------------------------------------------------------------------------- - UI::Window( ).newAction( "Reload curves" , []() { - UI::Window( ).msgbox( + UI::Main( ).newAction( "Reload curves" , []() { + UI::Main( ).msgbox( "Reload curves?" , "Changes you made to the curves will be lost. Do you " "want to continue?" , diff --git a/ui.cc b/ui.cc index 72234aa..253e355 100644 --- a/ui.cc +++ b/ui.cc @@ -3,15 +3,15 @@ #include "shaders.hh" #include "texture.hh" #include "ui.hh" +#include "ui-app.hh" #include "ui-sync.hh" -#include "window.hh" namespace { struct UIData_ { - T_Window window; + T_UIApp window; T_TextureManager textures; T_ShaderManager shaders; T_OutputDebugger odbg; @@ -38,7 +38,7 @@ void UI::Shutdown( ) noexcept #define M_GET_( P ) ((UIData_*)(char*)&Instance_)->P -T_Window& UI::Window( ) noexcept +T_UIApp& UI::Main( ) noexcept { return M_GET_( window ); } T_TextureManager& UI::Textures( ) noexcept diff --git a/ui.hh b/ui.hh index 5589c93..62359b7 100644 --- a/ui.hh +++ b/ui.hh @@ -3,7 +3,7 @@ # include "externals.hh" #endif -struct T_Window; +struct T_UIApp; struct T_TextureManager; struct T_ShaderManager; struct T_OutputDebugger; @@ -16,7 +16,7 @@ struct UI : public ebcl::A_PrivateImplementation static void Init( ) noexcept; static void Shutdown( ) noexcept; - static T_Window& Window( ) noexcept; + static T_UIApp& Main( ) noexcept; static T_TextureManager& Textures( ) noexcept; static T_ShaderManager& Shaders( ) noexcept; static T_OutputDebugger& ODbg( ) noexcept;