Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Valid history for each opened scene #3557

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion source/MRMesh/MRCombinedHistoryAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void CombinedHistoryAction::action( HistoryAction::Type type )

bool CombinedHistoryAction::filter( HistoryStackFilter filteringCondition )
{
return filterHistoryActionsVector( actions_, filteringCondition ).first;
return filterHistoryActionsVector( actions_, filteringCondition );
}

size_t CombinedHistoryAction::heapBytes() const
Expand Down
11 changes: 5 additions & 6 deletions source/MRMesh/MRHistoryAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@
namespace MR
{

std::pair<bool, int> filterHistoryActionsVector( HistoryActionsVector& historyVector,
HistoryStackFilter filteringCondition, size_t firstRedoIndex /*= 0*/, bool deepFiltering /*= true */ )
bool filterHistoryActionsVector( HistoryActionsVector& historyVector,
HistoryStackFilter filteringCondition, bool deepFiltering /*= true */, std::function<void( size_t id )> onFilterCb )
{
bool needSignal = false;
int redoDecrease = 0;
for ( int i = ( int )historyVector.size() - 1; i >= 0; --i )
{
if ( filteringCondition( historyVector[i] ) )
{
if ( i < firstRedoIndex ) ++redoDecrease;
if ( onFilterCb ) onFilterCb( i );
historyVector.erase( historyVector.begin() + i );
needSignal = true;
}
Expand All @@ -26,13 +25,13 @@ std::pair<bool, int> filterHistoryActionsVector( HistoryActionsVector& historyVe
needSignal = combinedAction->filter( filteringCondition ) || needSignal;
if ( combinedAction->empty() )
{
if ( i < firstRedoIndex ) ++redoDecrease;
if ( onFilterCb ) onFilterCb( i );
historyVector.erase( historyVector.begin() + i );
needSignal = true;
}
}
}
return { needSignal, redoDecrease };
return needSignal;
}

} //namespace MR
6 changes: 3 additions & 3 deletions source/MRMesh/MRHistoryAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ using HistoryActionsVector = std::vector<std::shared_ptr<HistoryAction>>;

/**
* \brief Remove actions from history actions vector that match the condition
* \param firstRedoIndex - set redo index for calculate how many actions removed before it
* \param deepFiltering - filter actions into combined actions
* \param onFilter - callback that is called when element is filtered from the stack with id of filtered element as argument
* \return pair (anything removed, how many removed before firstRedoIndex)
*/
MRMESH_API std::pair<bool, int> filterHistoryActionsVector( HistoryActionsVector& historyVector,
HistoryStackFilter filteringCondition, size_t firstRedoIndex = 0, bool deepFiltering = true );
MRMESH_API bool filterHistoryActionsVector( HistoryActionsVector& historyVector,
HistoryStackFilter filteringCondition, bool deepFiltering = true, std::function<void( size_t id )> onFilterCb = {} );

} //namespace MR
29 changes: 26 additions & 3 deletions source/MRViewer/MRHistoryStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#include "MRViewer.h"
#include "MRMesh/MRCombinedHistoryAction.h"
#include "MRPch/MRSpdlog.h"
#include "MRMesh/MRStringConvert.h"
#include "MRMesh/MRSceneRoot.h"
#include <cassert>
#include <filesystem>

namespace MR
{
Expand Down Expand Up @@ -44,12 +47,26 @@ void HistoryStore::appendAction( const std::shared_ptr<HistoryAction>& action )
{
stack_.erase( stack_.begin(), stack_.begin() + numActionsToDelete );
firstRedoIndex_ -= numActionsToDelete;
savedSceneIndex_ -= numActionsToDelete;
for ( auto& [_, savedSceneId] : savedSceneIndex_ )
savedSceneId -= numActionsToDelete;
}

changedSignal( *this, ChangeType::AppendAction );
}

bool HistoryStore::isSceneModified() const
{
auto it = savedSceneIndex_.find( utf8string( SceneRoot::getScenePath() ) );
if ( it == savedSceneIndex_.end() )
return firstRedoIndex_ != 0;
return firstRedoIndex_ != it->second;
}

void HistoryStore::setSavedState()
{
savedSceneIndex_[utf8string( SceneRoot::getScenePath() )] = firstRedoIndex_;
}

void HistoryStore::clear()
{
if ( stack_.empty() )
Expand All @@ -62,8 +79,14 @@ void HistoryStore::clear()

void HistoryStore::filterStack( HistoryStackFilter filteringCondition, bool deepFiltering /*= true*/ )
{
const auto [needSignal, redoDecrease] = filterHistoryActionsVector( stack_, filteringCondition, firstRedoIndex_, deepFiltering );
firstRedoIndex_ -= redoDecrease;
auto cpyFirstRedoId = firstRedoIndex_;
auto cpySceneSavedIdMap = savedSceneIndex_;
bool needSignal = filterHistoryActionsVector( stack_, filteringCondition, deepFiltering, [&] ( size_t id )
{
if ( id < cpyFirstRedoId ) --firstRedoIndex_;
for ( const auto& [name, sceneSavedId] : cpySceneSavedIdMap )
if ( id < sceneSavedId ) --savedSceneIndex_[name];
} );
if ( needSignal )
changedSignal( *this, ChangeType::Filter );
}
Expand Down
7 changes: 4 additions & 3 deletions source/MRViewer/MRHistoryStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "MRMesh/MRHistoryAction.h"
#include "MRMesh/MRSignal.h"
#include <memory>
#include <unordered_map>

namespace MR
{
Expand All @@ -30,9 +31,9 @@ class HistoryStore
void setScopeBlockPtr( HistoryActionsVector* scopedBlock ) { scopedBlock_ = scopedBlock; }

/// Returns true if the current scene state does not match the saved state
bool isSceneModified() const { return firstRedoIndex_ != savedSceneIndex_; }
MRVIEWER_API bool isSceneModified() const;// { return firstRedoIndex_ != savedSceneIndex_; }
/// Consider the current scene state as saved
void setSavedState() { savedSceneIndex_ = firstRedoIndex_; }
MRVIEWER_API void setSavedState();// { savedSceneIndex_ = firstRedoIndex_; }

/// Clears this HistoryStore
MRVIEWER_API void clear();
Expand Down Expand Up @@ -79,7 +80,7 @@ class HistoryStore
size_t firstRedoIndex_{ 0 };
/// this index points to the position in stack_ corresponding to saved scene state;
/// if firstRedoIndex_ == savedSceneIndex_ then the scene is considered as not modified
size_t savedSceneIndex_{ 0 };
std::unordered_map<std::string, size_t> savedSceneIndex_;
/// memory limit (bytes) to this HistoryStore if stack_ exceed it, old actions are removed
size_t storageLimit_{ size_t( ~0 ) };
};
Expand Down
Loading