diff --git a/ui-overrides.cc b/ui-overrides.cc index 66f8527..2f587af 100644 --- a/ui-overrides.cc +++ b/ui-overrides.cc @@ -25,36 +25,31 @@ char const* BuildLabel_( } // namespace +A_SyncData::~A_SyncData( ) { } + + /*= FLOAT OVERRIDES ==========================================================*/ M_DECL_SOVUI( Float ) { using namespace ImGui; auto& ov{ dynamic_cast< T_Float& >( ovp ) }; - float v[ 1 ] = { - Common::Sync( ).inputs( )[ ov.inputPositions( )[ 0 ] ] - }; - char const* const label( BuildLabel_( counter , sb ) ); const bool changed( ov.slider( ) - ? SliderFloat( label , v , ov.min( ) , ov.max( ) , + ? SliderFloat( label , &data[ 0 ] , ov.min( ) , ov.max( ) , ov.decimals( ) , ov.power( ) ) - : DragFloat( label , v , ov.step( ) , ov.min( ) , + : DragFloat( label , &data[ 0 ] , ov.step( ) , ov.min( ) , ov.max( ) , ov.decimals( ) , ov.power( ) ) ); - if ( changed ) { - Common::Sync( ).inputs( )[ ov.inputPositions( )[ 0 ] ] = v[ 0 ]; - } + return changed; } M_DECL_SOVUI( Float2 ) { using namespace ImGui; auto& ov{ dynamic_cast< T_Float2& >( ovp ) }; - auto& sinp( Common::Sync( ).inputs( ) ); - auto const& ovip{ ov.inputPositions( ) }; float v[ 2 ]; for ( auto i = 0 ; i < 2 ; i ++ ) { - v[ i ] = sinp[ ovip[ i ] ]; + v[ i ] = data[ i ]; } char const* const label( BuildLabel_( counter , sb ) ); @@ -65,20 +60,19 @@ M_DECL_SOVUI( Float2 ) ov.max( ) , ov.decimals( ) , ov.power( ) ) ); if ( changed ) { for ( auto i = 0 ; i < 2 ; i ++ ) { - sinp[ ovip[ i ] ] = v[ i ]; + data[ i ] = v[ i ]; } } + return changed; } M_DECL_SOVUI( Float3 ) { using namespace ImGui; auto& ov{ dynamic_cast< T_Float3& >( ovp ) }; - auto& sinp( Common::Sync( ).inputs( ) ); - auto const& ovip{ ov.inputPositions( ) }; float v[ 3 ]; for ( auto i = 0 ; i < 3 ; i ++ ) { - v[ i ] = sinp[ ovip[ i ] ]; + v[ i ] = data[ i ]; } char const* const label( BuildLabel_( counter , sb ) ); @@ -89,20 +83,19 @@ M_DECL_SOVUI( Float3 ) ov.max( ) , ov.decimals( ) , ov.power( ) ) ); if ( changed ) { for ( auto i = 0 ; i < 3 ; i ++ ) { - sinp[ ovip[ i ] ] = v[ i ]; + data[ i ] = v[ i ]; } } + return changed; } M_DECL_SOVUI( Float4 ) { using namespace ImGui; auto& ov{ dynamic_cast< T_Float4& >( ovp ) }; - auto& sinp( Common::Sync( ).inputs( ) ); - auto const& ovip{ ov.inputPositions( ) }; float v[ 4 ]; for ( auto i = 0 ; i < 4 ; i ++ ) { - v[ i ] = sinp[ ovip[ i ] ]; + v[ i ] = data[ i ]; } char const* const label( BuildLabel_( counter , sb ) ); @@ -113,9 +106,10 @@ M_DECL_SOVUI( Float4 ) ov.max( ) , ov.decimals( ) , ov.power( ) ) ); if ( changed ) { for ( auto i = 0 ; i < 4 ; i ++ ) { - sinp[ ovip[ i ] ] = v[ i ]; + data[ i ] = v[ i ]; } } + return changed; } @@ -125,30 +119,25 @@ M_DECL_SOVUI( Integer ) { using namespace ImGui; auto& ov{ dynamic_cast< T_Integer& >( ovp ) }; - auto& sinp( Common::Sync( ).inputs( ) ); - auto const& ovip{ ov.inputPositions( ) }; - int32_t v[ 1 ] = { - int32_t( sinp[ ovip[ 0 ] ] ) - }; + int32_t v = int32_t( data[ 0 ] ); char const* const label( BuildLabel_( counter , sb ) ); const bool changed( ov.slider( ) - ? SliderInt( label , v , ov.min( ) , ov.max( ) ) - : DragInt( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) ); + ? SliderInt( label , &v , ov.min( ) , ov.max( ) ) + : DragInt( label , &v , ov.step( ) , ov.min( ) , ov.max( ) ) ); if ( changed ) { - sinp[ ovip[ 0 ] ] = v[ 0 ]; + data[ 0 ] = v; } + return changed; } M_DECL_SOVUI( Integer2 ) { using namespace ImGui; auto& ov{ dynamic_cast< T_Integer2& >( ovp ) }; - auto& sinp( Common::Sync( ).inputs( ) ); - auto const& ovip{ ov.inputPositions( ) }; int32_t v[ 2 ]; for ( auto i = 0 ; i < 2 ; i ++ ) { - v[ i ] = sinp[ ovip[ i ] ]; + v[ i ] = data[ i ]; } char const* const label( BuildLabel_( counter , sb ) ); @@ -157,20 +146,19 @@ M_DECL_SOVUI( Integer2 ) : DragInt2( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) ); if ( changed ) { for ( auto i = 0 ; i < 2 ; i ++ ) { - sinp[ ovip[ i ] ] = v[ i ]; + data[ i ] = v[ i ]; } } + return changed; } M_DECL_SOVUI( Integer3 ) { using namespace ImGui; auto& ov{ dynamic_cast< T_Integer3& >( ovp ) }; - auto& sinp( Common::Sync( ).inputs( ) ); - auto const& ovip{ ov.inputPositions( ) }; int32_t v[ 3 ]; for ( auto i = 0 ; i < 3 ; i ++ ) { - v[ i ] = sinp[ ovip[ i ] ]; + v[ i ] = data[ i ]; } char const* const label( BuildLabel_( counter , sb ) ); @@ -179,20 +167,19 @@ M_DECL_SOVUI( Integer3 ) : DragInt3( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) ); if ( changed ) { for ( auto i = 0 ; i < 3 ; i ++ ) { - sinp[ ovip[ i ] ] = v[ i ]; + data[ i ] = v[ i ]; } } + return changed; } M_DECL_SOVUI( Integer4 ) { using namespace ImGui; auto& ov{ dynamic_cast< T_Integer4& >( ovp ) }; - auto& sinp( Common::Sync( ).inputs( ) ); - auto const& ovip{ ov.inputPositions( ) }; int32_t v[ 4 ]; for ( auto i = 0 ; i < 4 ; i ++ ) { - v[ i ] = sinp[ ovip[ i ] ]; + v[ i ] = data[ i ]; } char const* const label( BuildLabel_( counter , sb ) ); @@ -201,9 +188,10 @@ M_DECL_SOVUI( Integer4 ) : DragInt4( label , v , ov.step( ) , ov.min( ) , ov.max( ) ) ); if ( changed ) { for ( auto i = 0 ; i < 4 ; i ++ ) { - sinp[ ovip[ i ] ] = v[ i ]; + data[ i ] = v[ i ]; } } + return changed; } @@ -213,11 +201,9 @@ M_DECL_SOVUI( ColorGrading ) { using namespace ImGui; auto& ov{ dynamic_cast< T_ColorGrading& >( ovp ) }; - auto& sinp{ Common::Sync( ).inputs( ) }; - auto const& ovip{ ov.inputPositions( ) }; float v[ 3 ]; for ( auto i = 0 ; i < 3 ; i ++ ) { - v[ i ] = sinp[ ovip[ i ] ]; + v[ i ] = data[ i ]; } char const* const label{ BuildLabel_( counter , sb ) }; @@ -228,9 +214,10 @@ M_DECL_SOVUI( ColorGrading ) if ( changed ) { for ( auto i = 0 ; i < 3 ; i ++ ) { - sinp[ ovip[ i ] ] = v[ i ]; + data[ i ] = v[ i ]; } } + return changed; } @@ -240,24 +227,19 @@ namespace { glm::vec3 VectorFromInputs_( T_CamOverride::T_VectorConfig const& vc , - T_AutoArray< uint32_t , 8 > const& ovip ) noexcept + A_SyncData const& data ) noexcept { - auto& sinp( Common::Sync( ).inputs( ) ); - return glm::vec3{ - sinp[ ovip[ vc.x ] ] , - sinp[ ovip[ vc.y ] ] , - sinp[ ovip[ vc.z ] ] }; + return glm::vec3{ data[ vc.x ] , data[ vc.y ] , data[ vc.z ] }; } void InputsFromVector_( T_CamOverride::T_VectorConfig const& vc , - T_AutoArray< uint32_t , 8 > const& ovip , + A_SyncData& data , glm::vec3 const& v ) noexcept { - auto& sinp( Common::Sync( ).inputs( ) ); - sinp[ ovip[ vc.x ] ] = v.x; - sinp[ ovip[ vc.y ] ] = v.y; - sinp[ ovip[ vc.z ] ] = v.z; + data[ vc.x ] = v.x; + data[ vc.y ] = v.y; + data[ vc.z ] = v.z; } /*------------------------------------------------------------------------------*/ @@ -266,10 +248,12 @@ struct T_MouseCam_ : public virtual A_MouseCtrl { T_CameraMouseControl camera; T_CamOverride& ov; + T_OwnPtr< A_SyncData > data; T_MouseCam_( T_Camera& cam , - T_CamOverride& ov ) noexcept - : camera( cam ) , ov( ov ) + T_CamOverride& ov , + A_SyncData const& data ) noexcept + : camera( cam ) , ov( ov ) , data( data.clone( ) ) { } void handleDragAndDrop( @@ -290,7 +274,6 @@ void T_MouseCam_::handleDragAndDrop( T_KbdMods modifiers , T_MouseButtons buttons ) noexcept { - auto& sync( Common::Sync( ) ); if ( !ov.enabled( ) ) { UI::Sync( ).clearMouseDelegate( ); return; @@ -298,16 +281,14 @@ void T_MouseCam_::handleDragAndDrop( camera.handleDragAndDrop( move , modifiers , buttons ); - auto& sinp( sync.inputs( ) ); - auto const& ovip{ ov.inputPositions( ) }; auto& cam{ camera.camera }; - InputsFromVector_( ov.target( ) , ovip , cam.lookAt( ) ); + InputsFromVector_( ov.target( ) , *data , cam.lookAt( ) ); if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) { - InputsFromVector_( ov.angles( ) , ovip , cam.angles( ) ); - sinp[ ovip[ ov.distance( ) ] ] = cam.distance( ); + InputsFromVector_( ov.angles( ) , *data , cam.angles( ) ); + (*data)[ ov.distance( ) ] = cam.distance( ); } else { - InputsFromVector_( ov.position( ) , ovip , cam.position( ) ); - InputsFromVector_( ov.up( ) , ovip , cam.upVector( ) ); + InputsFromVector_( ov.position( ) , *data , cam.position( ) ); + InputsFromVector_( ov.up( ) , *data , cam.upVector( ) ); } } @@ -316,7 +297,6 @@ void T_MouseCam_::handleWheel( T_KbdMods modifiers , T_MouseButtons buttons ) noexcept { - auto& sync( Common::Sync( ) ); if ( !ov.enabled( ) ) { UI::Sync( ).clearMouseDelegate( ); return; @@ -324,24 +304,22 @@ void T_MouseCam_::handleWheel( camera.handleWheel( wheel , modifiers , buttons ); - auto& sinp( sync.inputs( ) ); auto& cam{ camera.camera }; - auto const& ovip{ ov.inputPositions( ) }; if ( modifiers & E_KbdMod::SHIFT ) { auto const& fc( ov.fovConfig( ) ); if ( fc.mode == T_CamOverride::FM_FOV ) { - sinp[ ovip[ fc.inputIndex ] ] = cam.fieldOfView( ); + (*data)[ fc.inputIndex ] = cam.fieldOfView( ); } else { - sinp[ ovip[ fc.inputIndex ] ] = cam.nearPlane( ); + (*data)[ fc.inputIndex ] = cam.nearPlane( ); } } else { - InputsFromVector_( ov.target( ) , ovip , cam.lookAt( ) ); + InputsFromVector_( ov.target( ) , *data , cam.lookAt( ) ); if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) { - InputsFromVector_( ov.angles( ) , ovip , cam.angles( ) ); - sinp[ ovip[ ov.distance( ) ] ] = cam.distance( ); + InputsFromVector_( ov.angles( ) , *data , cam.angles( ) ); + (*data)[ ov.distance( ) ] = cam.distance( ); } else { - InputsFromVector_( ov.position( ) , ovip , cam.position( ) ); - InputsFromVector_( ov.up( ) , ovip , cam.upVector( ) ); + InputsFromVector_( ov.position( ) , *data , cam.position( ) ); + InputsFromVector_( ov.up( ) , *data , cam.upVector( ) ); } } } @@ -351,33 +329,30 @@ void T_MouseCam_::handleWheel( M_DECL_SOVUI( Camera ) { auto& ov{ dynamic_cast< T_CamOverride& >( ovp ) }; - auto& sync{ Common::Sync( ) }; - auto& sinp{ sync.inputs( ) }; auto& camera{ ov.camData( ) }; - auto const& ovip{ ov.inputPositions( ) }; auto const& fc{ ov.fovConfig( ) }; if ( !ov.enabled( ) || !ov.prevEnabled( ) ) { // Set field of view / near plane if ( fc.mode == T_CamOverride::FM_FOV ) { - camera.fieldOfView( sinp[ ovip[ fc.inputIndex ] ] ); + camera.fieldOfView( data[ fc.inputIndex ] ); } else { - camera.nearPlane( sinp[ ovip[ fc.inputIndex ] ] ); + camera.nearPlane( data[ fc.inputIndex ] ); } // Set camera parameters const glm::vec3 lookAt{ VectorFromInputs_( - ov.target( ) , ovip ) }; + ov.target( ) , data ) }; if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) { const glm::vec3 angles{ VectorFromInputs_( - ov.angles( ) , ovip ) }; - const float distance{ sinp[ ovip[ ov.distance( ) ] ] }; + ov.angles( ) , data ) }; + const float distance{ data[ ov.distance( ) ] }; camera.camera( lookAt , angles , distance ); } else { const glm::vec3 position{ VectorFromInputs_( - ov.position( ) , ovip ) }; + ov.position( ) , data ) }; const glm::vec3 up{ VectorFromInputs_( - ov.up( ) , ovip ) }; + ov.up( ) , data ) }; camera.camera( lookAt , position , up ); } } @@ -399,7 +374,7 @@ M_DECL_SOVUI( Camera ) if ( handlerChanged ) { if ( mouseHandler ) { sui.delegateMouse( ov.id( ) , - NewOwned< T_MouseCam_ >( camera , ov ) ); + NewOwned< T_MouseCam_ >( camera , ov , data ) ); } else { sui.clearMouseDelegate( ); } @@ -408,21 +383,22 @@ M_DECL_SOVUI( Camera ) // Update values if ( changes & E_CameraChange::FOV ) { if ( fc.mode == T_CamOverride::FM_FOV ) { - sinp[ ovip[ fc.inputIndex ] ] = camera.fieldOfView( ); + data[ fc.inputIndex ] = camera.fieldOfView( ); } else { - sinp[ ovip[ fc.inputIndex ] ] = camera.nearPlane( ); + data[ fc.inputIndex ] = camera.nearPlane( ); } } if ( changes & E_CameraChange::MATRIX ) { - InputsFromVector_( ov.target( ) , ovip , camera.lookAt( ) ); + InputsFromVector_( ov.target( ) , data , camera.lookAt( ) ); if ( ov.mode( ) == T_CamOverride::CM_ANGLES ) { - InputsFromVector_( ov.angles( ) , ovip , camera.angles( ) ); - sinp[ ovip[ ov.distance( ) ] ] = camera.distance( ); + InputsFromVector_( ov.angles( ) , data , camera.angles( ) ); + data[ ov.distance( ) ] = camera.distance( ); } else { - InputsFromVector_( ov.position( ) , ovip , camera.position( ) ); - InputsFromVector_( ov.up( ) , ovip , camera.upVector( ) ); + InputsFromVector_( ov.position( ) , data , camera.position( ) ); + InputsFromVector_( ov.up( ) , data , camera.upVector( ) ); } } + return changes; } diff --git a/ui-overrides.hh b/ui-overrides.hh index 362081c..1d0edbc 100644 --- a/ui-overrides.hh +++ b/ui-overrides.hh @@ -2,12 +2,24 @@ #include "c-syncoverrides.hh" #define M_DECL_SOVUI(NAME) \ - void UI##NAME( A_SyncOverride& ovp , \ + bool UI##NAME( A_SyncOverride& ovp , \ + A_SyncData& data , \ uint32_t& counter , \ T_StringBuilder& sb ) noexcept namespace sov { + class A_SyncData + { + public: + virtual ~A_SyncData( ) = 0; + + virtual float operator[]( uint32_t index ) const noexcept = 0; + virtual float& operator[]( uint32_t index ) noexcept = 0; + + virtual T_OwnPtr< A_SyncData > clone( ) const noexcept = 0; + }; + M_DECL_SOVUI( Float ); M_DECL_SOVUI( Float2 ); M_DECL_SOVUI( Float3 ); diff --git a/ui-sync.cc b/ui-sync.cc index 3a41747..113035a 100644 --- a/ui-sync.cc +++ b/ui-sync.cc @@ -8,6 +8,57 @@ #include "ui-utilities.hh" +/*= T_SyncInputData_ =========================================================*/ +namespace { + +class T_SyncInputData_ : public sov::A_SyncData +{ + private: + T_AutoArray< float* , 16 > ptr_; + + public: + void setFromOverride( A_SyncOverride const& sov ) noexcept; + + float operator[]( uint32_t index ) const noexcept override; + float& operator[]( uint32_t index ) noexcept override; + + T_OwnPtr< sov::A_SyncData > clone( ) const noexcept override; +}; + + +void T_SyncInputData_::setFromOverride( + A_SyncOverride const& sov ) noexcept +{ + auto const& iPos{ sov.inputPositions() }; + const auto np{ iPos.size( ) }; + ptr_.ensureCapacity( np ); + ptr_.clear( ); + + auto& inputs{ Common::Sync( ).inputs( ) }; + for ( auto i = 0u ; i < np ; i ++ ) { + ptr_.add( &inputs[ iPos[ i ] ] ); + } +} + +float T_SyncInputData_::operator[]( + const uint32_t index ) const noexcept +{ + return *ptr_[ index ]; +} + +float& T_SyncInputData_::operator[]( + const uint32_t index ) noexcept +{ + return *ptr_[ index ]; +} + +T_OwnPtr< sov::A_SyncData > T_SyncInputData_::clone( ) const noexcept +{ + return NewOwned< T_SyncInputData_ >( *this ); +} + + +} // namespace /*= T_UISync =================================================================*/ T_UISync::T_UISync( ) @@ -96,6 +147,7 @@ bool HandleOverrideSection_( void HandleOverride_( A_SyncOverride& ov , + T_SyncInputData_& data , uint32_t& counter , T_StringBuilder& sb ) noexcept { @@ -112,7 +164,8 @@ void HandleOverride_( } Indent( ); PushItemWidth( -1 ); - (UI::Sync( ).uiFor( ov ))( ov , counter , sb ); + data.setFromOverride( ov ); + (UI::Sync( ).uiFor( ov ))( ov , data , counter , sb ); PopItemWidth( ); Unindent( ); if ( !enabled ) { @@ -126,7 +179,8 @@ T_UISync::F_Override T_UISync::uiFor( A_SyncOverride& target ) const noexcept { auto const* const rv{ sovuis_.get( target.type( ) ) }; - return rv ? *rv : []( A_SyncOverride& , uint32_t& , T_StringBuilder& ) { + return rv ? *rv : []( A_SyncOverride& , sov::A_SyncData& , + uint32_t& , T_StringBuilder& ) { ImGui::Text( "(missing UI)" ); }; } @@ -144,9 +198,10 @@ void T_UISync::makeOverridesWindow( ) Begin( "Input overrides" , &ovWindow_ , ImGuiWindowFlags_NoCollapse ); + T_AutoArray< bool , 32 > stack; + T_SyncInputData_ data; T_StringBuilder temp; uint32_t counter{ 0 }; - T_AutoArray< bool , 32 > stack; bool found{ false }; using T_Ove_ = T_SyncOverrideVisitor::T_Element; Common::Sync( ).visitOverrides( [&]( T_Ove_ element , bool exit ) { @@ -161,7 +216,7 @@ void T_UISync::makeOverridesWindow( ) } if ( exit ) { HandleOverride_( *element.value< A_SyncOverride* >( ) , - counter , temp ); + data , counter , temp ); found = true; } return true; diff --git a/ui-sync.hh b/ui-sync.hh index cc377b6..da1dff2 100644 --- a/ui-sync.hh +++ b/ui-sync.hh @@ -3,6 +3,8 @@ #include "ui-mousectrl.hh" +namespace sov { class A_SyncData; } + class T_UISync : public A_MouseCtrl { public: @@ -16,7 +18,8 @@ class T_UISync : public A_MouseCtrl void makeOverridesWindow( ); using F_Override = std::function< - void( A_SyncOverride& , uint32_t& , T_StringBuilder& ) >; + void( A_SyncOverride& , sov::A_SyncData& , uint32_t& , + T_StringBuilder& ) >; F_Override uiFor( A_SyncOverride& target ) const noexcept;