diff --git a/Makefile b/Makefile index 15f19fd..a9f6c13 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ COMMON = \ DEMO = \ demo.cc \ main.cc \ + syncedit.cc \ syncview.cc \ undo.cc \ # END DEMO diff --git a/sync.cc b/sync.cc index e0c23a2..d8831ae 100644 --- a/sync.cc +++ b/sync.cc @@ -164,17 +164,6 @@ void T_SyncTime::setDuration( /*= T_SyncCurves =============================================================*/ -void T_SyncCurves::clear( ) -{ - curves.clear( ); -} - -void T_SyncCurves::setCurve( - T_SyncCurve curve ) -{ - curves.set( std::move( curve ) ); -} - int32_t T_SyncCurves::indexOf( T_String const& name ) noexcept { @@ -597,6 +586,14 @@ void T_SyncManager::setCurve( updateCurveCaches( ); } +void T_SyncManager::removeCurve( + T_String const& curve ) noexcept +{ + if ( curves_.removeCurve( curve ) ) { + updateCurveCaches( ); + } +} + void T_SyncManager::curvesChanged_( ) { bool missing; diff --git a/sync.hh b/sync.hh index 0bf4b0e..0472e42 100644 --- a/sync.hh +++ b/sync.hh @@ -74,8 +74,12 @@ struct T_SyncCurves : curves( []( T_SyncCurve const& c ) -> T_String { return c.name; } ) { } - void clear( ); - void setCurve( T_SyncCurve curve ); + void clear( ) noexcept + { curves.clear( ); } + void setCurve( T_SyncCurve curve ) noexcept + { curves.set( std::move( curve ) ); } + bool removeCurve( T_String const& curve ) noexcept + { return curves.remove( curve ); } // Returns -1 on lookup failure int32_t indexOf( T_String const& name ) noexcept; @@ -342,6 +346,7 @@ struct T_SyncManager : public virtual A_MouseCtrl void checkCurveFile( ); void clearCurves( ); void setCurve( T_SyncCurve curve ); + void removeCurve( T_String const& curve ) noexcept; private: void curvesChanged_( ); diff --git a/syncedit.cc b/syncedit.cc new file mode 100644 index 0000000..787ff5f --- /dev/null +++ b/syncedit.cc @@ -0,0 +1,83 @@ +#include "externals.hh" +#include "syncedit.hh" +#include "globals.hh" + + +/*= T_UndoSyncChanges ==========================================================*/ + +void T_UndoSyncChanges::undo( ) const noexcept +{ + auto& sync{ Globals::Sync( ) }; + const auto n{ changes_.size( ) }; + for ( auto i = 0u ; i < n ; i ++ ) { + auto const& c( changes_[ i ] ); + if ( c.before ) { + sync.setCurve( *c.before ); + } else { + sync.removeCurve( c.inputId ); + } + } +} + +void T_UndoSyncChanges::redo( ) const noexcept +{ + auto& sync{ Globals::Sync( ) }; + const auto n{ changes_.size( ) }; + for ( auto i = 0u ; i < n ; i ++ ) { + auto const& c( changes_[ i ] ); + if ( c.after ) { + sync.setCurve( *c.after ); + } else { + sync.removeCurve( c.inputId ); + } + } +} + +/*------------------------------------------------------------------------------*/ + +T_UndoSyncChanges& T_UndoSyncChanges::curveCreation( + T_SyncCurve curve ) noexcept +{ +#ifndef NDEBUG + { + const auto n{ changes_.size( ) }; + for ( auto i = 0u ; i < n ; i ++ ) { + assert( changes_[ i ].inputId != curve.name ); + } + } +#endif + changes_.addNew( true , std::move( curve ) ); + return *this; +} + +T_UndoSyncChanges& T_UndoSyncChanges::curveDeletion( + T_SyncCurve curve ) noexcept +{ +#ifndef NDEBUG + { + const auto n{ changes_.size( ) }; + for ( auto i = 0u ; i < n ; i ++ ) { + assert( changes_[ i ].inputId != curve.name ); + } + } +#endif + changes_.addNew( std::move( curve ) ); + return *this; +} + +T_UndoSyncChanges& T_UndoSyncChanges::curveReplacement( + T_SyncCurve before , + T_SyncCurve after ) noexcept +{ + assert( before.name == after.name ); +#ifndef NDEBUG + { + const auto n{ changes_.size( ) }; + for ( auto i = 0u ; i < n ; i ++ ) { + assert( changes_[ i ].inputId != before.name ); + } + } +#endif + changes_.addNew( std::move( before ) , std::move( after ) ); + return *this; +} diff --git a/syncedit.hh b/syncedit.hh new file mode 100644 index 0000000..828eafa --- /dev/null +++ b/syncedit.hh @@ -0,0 +1,53 @@ +#pragma once +#include "sync.hh" +#include "undo.hh" + + +/*= GENERAL STRUCTURE FOR SYNC EDITOR UNDOS ====================================*/ + +class T_UndoSyncChanges : public A_UndoAction +{ + protected: + struct T_CurveChange_ + { + T_String inputId; + T_Optional< T_SyncCurve > before; + T_Optional< T_SyncCurve > after; + + explicit T_CurveChange_( T_SyncCurve before ) noexcept + : inputId{ before.name } , + before{ std::move( before ) } , + after{ } + {} + + T_CurveChange_( const bool , + T_SyncCurve after ) noexcept + : inputId{ after.name } , before{ } , + after{ std::move( after ) } + {} + + T_CurveChange_( T_SyncCurve before , + T_SyncCurve after ) noexcept + : inputId{ before.name } , + before{ std::move( before ) } , + after{ std::move( after ) } + {} + }; + T_AutoArray< T_CurveChange_ , 4 , 32 > changes_; + + public: + T_UndoSyncChanges( ) noexcept = default; + DEF_MOVE( T_UndoSyncChanges ); + NO_COPY( T_UndoSyncChanges ); + + void undo( ) const noexcept override; + void redo( ) const noexcept override; + + T_UndoSyncChanges& curveCreation( + T_SyncCurve curve ) noexcept; + T_UndoSyncChanges& curveDeletion( + T_SyncCurve curve ) noexcept; + T_UndoSyncChanges& curveReplacement( + T_SyncCurve before , + T_SyncCurve after ) noexcept; +};