#pragma once #include "c-sync.hh" #include "c-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; }; /*= DURATION CHANGES =========================================================*/ class T_UndoDurationChanges final : public T_UndoSyncChanges { private: uint32_t unitsBefore_ , unitsAfter_; float uSizeBefore_ , uSizeAfter_; public: T_UndoDurationChanges( uint32_t units , uint32_t oldUnits , float unitSize , float oldUnitSize ) noexcept; T_UndoDurationChanges( ) noexcept = delete; DEF_MOVE( T_UndoDurationChanges ); NO_COPY( T_UndoDurationChanges ); void undo( ) const noexcept override; void redo( ) const noexcept override; }; /*= TRACK IDENTIFIER =========================================================*/ struct T_SyncTrackId { T_String id; bool isOverride; bool operator ==( T_SyncTrackId const& other ) const noexcept { return id == other.id && isOverride == other.isOverride; } bool operator !=( T_SyncTrackId const& other ) const noexcept { return id != other.id || isOverride != other.isOverride; } }; inline uint32_t ComputeHash( T_SyncTrackId const& id ) noexcept { return ComputeHash( id.id ) ^ ( id.isOverride ? 0xffffffff : 0 ); } /*= EDITION FUNCTIONS ========================================================*/ struct SyncEditor final { // Change the duration of the demo using the specified unit count and // size. If scaleCurves is true and the unit size has changed, the // curves' durations will be scaled so that the timings match as // closely as possible. static void SetDuration( uint32_t units , float uSize , bool scaleCurves ) noexcept; //---------------------------------------------------------------------- // Replaces a curve with a new record static void ReplaceCurve( T_SyncCurve replacement ) noexcept; // Delete a curve's (or an override's) record completely. static void DeleteCurve( T_SyncTrackId const& id ) noexcept; //---------------------------------------------------------------------- // Append a segment with the specified amount of units at the end of // the curve. If the curve does not exist it will be created. static void AppendSegment( T_SyncTrackId const& id , uint32_t nsDuration ) noexcept; // Delete a segment from a curve. static void DeleteSegment( T_SyncTrackId const& id , uint32_t segmentIndex ) noexcept; // Change the type of a segment in a curve. static void SetSegmentType( T_SyncCurve const& initial , uint32_t segmentIndex , T_SyncSegment::E_SegmentType newType ) noexcept; // Change the type of a segment for all inputs covered by an override. static void SetSegmentTypes( A_SyncOverride const& ovr , uint32_t segmentIndex , T_SyncSegment::E_SegmentType newType ) noexcept; //---------------------------------------------------------------------- // Insert a point in a segment. The pointIndex parameter indicates the // index of the new point; it must not be 0 or nbPoints( segment ) static void InsertPoint( T_SyncTrackId const& id , uint32_t segmentIndex , uint32_t pointIndex ) noexcept; // Delete a point from a segment. The point must not be the first or last // point in the segment. static void DeletePoint( T_SyncTrackId const& id , uint32_t segmentIndex , uint32_t pointIndex ) noexcept; //---------------------------------------------------------------------- // Make an override consistent by aligning all segment boundaries and // durations on the first longest curve. static void MakeOverrideConsistent( T_String const& id ) noexcept; };