Added COMMIT::GetStatus() and minor refactor

Moved duplicated code to a new function and added
an assert to warn against possible memory leak.
This commit is contained in:
Maciej Suminski 2017-07-19 10:45:14 +02:00
parent 5f4599fb56
commit 984ac70106
2 changed files with 62 additions and 24 deletions

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* Copyright 2016-2017 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@ -52,7 +52,7 @@ COMMIT& COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType )
{
case CHT_ADD:
assert( m_changedItems.find( aItem ) == m_changedItems.end() );
makeEntry( aItem, CHT_ADD | flag );
makeEntry( aItem, CHT_ADD | flag );
return *this;
case CHT_REMOVE:
@ -62,13 +62,7 @@ COMMIT& COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType )
case CHT_MODIFY:
{
EDA_ITEM* parent = parentObject( aItem );
if( m_changedItems.find( parent ) != m_changedItems.end() )
return *this; // item has been already modified once
makeEntry( parent, CHT_MODIFY | flag, parent->Clone() );
return *this;
return createModified( parent, parent->Clone(), flag );
}
default:
@ -79,19 +73,6 @@ COMMIT& COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType )
}
COMMIT& COMMIT::Modified( EDA_ITEM* aItem, EDA_ITEM* aCopy )
{
EDA_ITEM* parent = parentObject( aItem );
if( m_changedItems.find( parent ) != m_changedItems.end() )
return *this; // item has been already modified once
makeEntry( parent, CHT_MODIFY, aCopy );
return *this;
}
COMMIT& COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType )
{
for( EDA_ITEM* item : container )
@ -133,6 +114,15 @@ COMMIT& COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag )
return *this;
}
int COMMIT::GetStatus( EDA_ITEM* aItem )
{
COMMIT_LINE* entry = findEntry( parentObject( aItem ) );
return entry ? entry->m_type : 0;
}
template <class Container, class F>
void eraseIf( Container& c, F&& f )
{
@ -142,6 +132,28 @@ void eraseIf( Container& c, F&& f )
c.end() );
}
COMMIT& COMMIT::createModified( EDA_ITEM* aItem, EDA_ITEM* aCopy, int aExtraFlags )
{
EDA_ITEM* parent = parentObject( aItem );
auto entryIt = m_changedItems.find( parent );
if( entryIt != m_changedItems.end() )
{
#ifdef DEBUG
const COMMIT_LINE* entry = findEntry( parent );
wxASSERT_MSG( entry->m_copy == aCopy, "Staging a different copy, possible memleak" );
#endif
return *this; // item has been already modified once
}
makeEntry( parent, CHT_MODIFY | aExtraFlags, aCopy );
return *this;
}
void COMMIT::makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy )
{
// Expect an item copy if it is going to be modified
@ -165,6 +177,18 @@ void COMMIT::makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy )
}
COMMIT::COMMIT_LINE* COMMIT::findEntry( EDA_ITEM* aItem )
{
for( COMMIT_LINE& change : m_changes )
{
if( change.m_item == aItem )
return &change;
}
return nullptr;
}
CHANGE_TYPE COMMIT::convert( UNDO_REDO_T aType ) const
{
switch( aType )

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* Copyright 2016-2017 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@ -107,7 +107,10 @@ public:
///> Creates an undo entry for an item that has been already modified. Requires a copy done
///> before the modification.
COMMIT& Modified( EDA_ITEM* aItem, EDA_ITEM* aCopy );
COMMIT& Modified( EDA_ITEM* aItem, EDA_ITEM* aCopy )
{
return createModified( aItem, aCopy );
}
template<class Range>
COMMIT& StageItems( const Range& aRange, CHANGE_TYPE aChangeType )
@ -137,6 +140,9 @@ public:
return m_changes.empty();
}
///> Returns status of an item.
int GetStatus( EDA_ITEM* aItem );
protected:
struct COMMIT_LINE
{
@ -157,8 +163,16 @@ protected:
m_changes.clear();
}
COMMIT& createModified( EDA_ITEM* aItem, EDA_ITEM* aCopy, int aExtraFlags = 0 );
virtual void makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy = NULL );
/**
* Searches for an entry describing change for a particular item
* @return null if there is no related entry.
*/
COMMIT_LINE* findEntry( EDA_ITEM* aItem );
virtual EDA_ITEM* parentObject( EDA_ITEM* aItem ) const = 0;
CHANGE_TYPE convert( UNDO_REDO_T aType ) const;