|
Krita Source Code Documentation
|
#include <kis_memento_manager.h>
Public Member Functions | |
| void | commit () |
| KisMementoSP | currentMemento () |
| void | debugPrintInfo () |
| KisTileSP | getCommittedTile (qint32 col, qint32 row, bool &existingTile) |
| KisMementoSP | getMemento () |
| bool | hasCurrentMemento () |
| KisMementoManager () | |
| KisMementoManager (const KisMementoManager &rhs) | |
| void | purgeHistory (KisMementoSP oldestMemento) |
| void | registerTileChange (KisTile *tile) |
| void | registerTileDeleted (KisTile *tile) |
| void | rollback (KisTileHashTable *ht, KisMementoSP memento) |
| void | rollforward (KisTileHashTable *ht, KisMementoSP memento) |
| void | setDefaultTileData (KisTileData *defaultTileData) |
| ~KisMementoManager () | |
Protected Member Functions | |
| qint32 | findRevisionByMemento (KisMementoSP memento) const |
| void | resetRevisionHistory (KisMementoItemList list) |
Definition at line 45 of file kis_memento_manager.h.
| KisMementoManager::KisMementoManager | ( | ) |
Tile change/delete registration is enabled for all devices by default. It can't be delayed.
Definition at line 64 of file kis_memento_manager.cc.
| KisMementoManager::KisMementoManager | ( | const KisMementoManager & | rhs | ) |
Definition at line 75 of file kis_memento_manager.cc.
References m_registrationBlocked.
| KisMementoManager::~KisMementoManager | ( | ) |
Definition at line 88 of file kis_memento_manager.cc.
References DEBUG_LOG_SIMPLE_ACTION.
| void KisMementoManager::commit | ( | ) |
Commits changes, made in INDEX: appends m_index into m_revisions list and owes all modified tileDatas.
We still need to continue commit, because a named transaction may be reverted by the user
Definition at line 166 of file kis_memento_manager.cc.
References KisMementoItem::col(), KisMementoItem::commit(), KisSharedPtr< T >::data(), DEBUG_DUMP_MESSAGE, KisTileHashTableTraits< T >::deleteTile(), KisTileHashTableTraits< T >::getTileLazy(), KisTileDataStore::instance(), KisTileHashTableTraits< T >::isEmpty(), KisHistoryItem::itemList, KisTileDataStore::kickPooler(), KIS_ASSERT, m_currentMemento, m_headsHashTable, m_index, m_revisions, KisHistoryItem::memento, KisTileHashTableIteratorTraits< T, LockerType >::moveCurrentToHashTable(), namedTransactionInProgress, newTile(), KisMementoItem::row(), KisMementoItem::setParent(), and KisTileHashTableIteratorTraits< T, LockerType >::tile().
| KisMementoSP KisMementoManager::currentMemento | ( | ) |
Definition at line 257 of file kis_memento_manager.cc.
References m_currentMemento.
| void KisMementoManager::debugPrintInfo | ( | ) |
Definition at line 407 of file kis_memento_manager.cc.
References KisMementoItem::debugPrintInfo(), KisTileHashTableTraits< T >::debugPrintInfo(), KisHistoryItem::itemList, m_cancelledRevisions, m_headsHashTable, m_index, m_revisions, KisTileHashTableIteratorTraits< T, LockerType >::next(), and KisTileHashTableIteratorTraits< T, LockerType >::tile().
|
protected |
Definition at line 373 of file kis_memento_manager.cc.
References m_revisions.
| KisTileSP KisMementoManager::getCommittedTile | ( | qint32 | col, |
| qint32 | row, | ||
| bool & | existingTile ) |
Get old tile, whose memento is in the HEAD revision. existingTile returns if the tile is actually an existing non-default tile or it was created on the fly from the default tile data
Our getOldTile mechanism is supposed to return current tile, if the history is disabled. So we return zero if no named transaction is in progress.
Definition at line 215 of file kis_memento_manager.cc.
References KisTileHashTableTraits< T >::getReadOnlyTileLazy(), m_headsHashTable, namedTransactionInProgress, and KisMementoItem::tile().
| KisMementoSP KisMementoManager::getMemento | ( | ) |
We do not allow nested transactions
The following assert is useful for testing if some code creates a transaction on a device with "inconsistent history". We cannot keep this sanity check enabled all the time, because in some places (e.g. projection in KisAsyncMerger) such usecase is considered legit. But in places with "consistent history", e.g. in layer's paint device, such usage will cause undo corruption.
Definition at line 229 of file kis_memento_manager.cc.
References commit(), DEBUG_LOG_SIMPLE_ACTION, KIS_SAFE_ASSERT_RECOVER_NOOP, m_cancelledRevisions, m_currentMemento, and namedTransactionInProgress.
|
inline |
Definition at line 98 of file kis_memento_manager.h.
| void KisMementoManager::purgeHistory | ( | KisMementoSP | oldestMemento | ) |
Removes all the history that precedes the revision pointed by oldestMemento. That is after calling to purgeHistory(someMemento) you won't be able to do rollback(someMemento) anymore.
Definition at line 353 of file kis_memento_manager.cc.
References commit(), DEBUG_DUMP_MESSAGE, findRevisionByMemento(), KIS_ASSERT, m_currentMemento, m_revisions, and resetRevisionHistory().
Most tricky part. This function is called by a tile, when it gets new tile-data through COW. The Memento Manager wraps this tile-data into KisMementoItem class and waits until commit() order given. By this time KisMementoItem doesn't take part in COW mechanism. It only holds tileData->m_refCount counter to ensure tile isn't deleted from memory. When commit() comes, KisMementoItem grabs tileData->m_usersCount and since that moment it is a rightful co-owner of the tileData and COW participant. It means that tileData won't be ever changed since then. Every write request to the original tile will lead to duplicating tileData and registering it here again...
NOTE: We don't assume that the registerTileChange/Delete can be called once a commit only. Reverse can happen when we do sequential clears of the device. In such a case the tiles will be removed and added several times during a commit.
TODO: There is an 'uncomfortable' state for the tile possible 1) Imagine we have a clear device 2) Then we painted something in a tile 3) It registered itself using registerTileChange() 4) Then we called clear() and getMemento() [==commit()] 5) The tile will be registered as deleted and successfully committed to a revision. That means the states of the memento manager at stages 1 and 5 do not coincide. This will not lead to any memory leaks or bugs seen, it just not good from a theoretical perspective.
Definition at line 113 of file kis_memento_manager.cc.
References KisTileHashTableTraits< T >::addTile(), KisMementoItem::changeTile(), KisMementoItem::col(), KisTile::col(), DEBUG_LOG_TILE_ACTION, KisTileHashTableTraits< T >::getExistingTile(), m_currentMemento, m_currentMementoExtentLock, m_index, namedTransactionInProgress, registrationBlocked, KisMementoItem::reset(), KisMementoItem::row(), KisTile::row(), and KisMemento::updateExtent().
Called when a tile deleted. Creates empty KisMementoItem showing that there was a tile one day
Definition at line 136 of file kis_memento_manager.cc.
References KisTileHashTableTraits< T >::addTile(), KisMementoItem::col(), KisTile::col(), DEBUG_LOG_TILE_ACTION, KisMementoItem::deleteTile(), KisTileData::deref(), KisTileHashTableTraits< T >::getExistingTile(), m_currentMemento, m_currentMementoExtentLock, m_headsHashTable, m_index, namedTransactionInProgress, KisTileHashTableTraits< T >::refAndFetchDefaultTileData(), registrationBlocked, KisMementoItem::reset(), KisMementoItem::row(), KisTile::row(), and KisMemento::updateExtent().
|
protected |
Definition at line 385 of file kis_memento_manager.cc.
References KisMementoItem::parent(), and KisMementoItem::setParent().
| void KisMementoManager::rollback | ( | KisTileHashTable * | ht, |
| KisMementoSP | memento ) |
Undo and Redo stuff respectively.
When calling them, INDEX list should be empty, so to say, "working copy should be clean".
NOTE: tricky hack alert. We have just deleted some tiles from the original hash table. And they accurately reported to us about their death. Should have reported... But we have prevented their registration with explicitly blocking the process. So all the dead tiles are going to /dev/null :)
PS: It could cause some race condition... But we insist on serialization of rollback()/rollforward() requests. There is not much sense in calling rollback() concurrently.
Definition at line 265 of file kis_memento_manager.cc.
References KisTileHashTableTraits< T >::addTile(), blockRegistration, KisMementoItem::CHANGED, KisMementoItem::col(), commit(), DEBUG_DUMP_MESSAGE, KisTileHashTableTraits< T >::deleteTile(), forEachReversed, KisTileDataStore::instance(), KisHistoryItem::itemList, KisTileDataStore::kickPooler(), KIS_ASSERT, KIS_SAFE_ASSERT_RECOVER_NOOP, m_cancelledRevisions, m_currentMemento, m_headsHashTable, m_revisions, KisHistoryItem::memento, namedTransactionInProgress, KisMementoItem::parent(), KisMementoItem::row(), KisMementoItem::tile(), KisMementoItem::type(), and unblockRegistration.
| void KisMementoManager::rollforward | ( | KisTileHashTable * | ht, |
| KisMementoSP | memento ) |
Definition at line 322 of file kis_memento_manager.cc.
References KisTileHashTableTraits< T >::addTile(), blockRegistration, KisMementoItem::CHANGED, KisMementoItem::col(), commit(), DEBUG_DUMP_MESSAGE, KisTileHashTableTraits< T >::deleteTile(), KisTileHashTableTraits< T >::isEmpty(), KisHistoryItem::itemList, KIS_SAFE_ASSERT_RECOVER_NOOP, KIS_SAFE_ASSERT_RECOVER_RETURN, m_cancelledRevisions, m_currentMemento, m_index, KisHistoryItem::memento, KisMementoItem::parent(), KisMementoItem::row(), KisMementoItem::tile(), KisMementoItem::type(), and unblockRegistration.
| void KisMementoManager::setDefaultTileData | ( | KisTileData * | defaultTileData | ) |
Definition at line 401 of file kis_memento_manager.cc.
References m_headsHashTable, m_index, and KisTileHashTableTraits< T >::setDefaultTileData().
|
protected |
List of revisions temporarily undone while rollback()
Definition at line 138 of file kis_memento_manager.h.
|
protected |
Stores extent of current INDEX. It is the "name" of current named transaction
Definition at line 150 of file kis_memento_manager.h.
|
protected |
Definition at line 151 of file kis_memento_manager.h.
|
protected |
A hash table, that stores the most recently updated versions of tiles. Say, HEAD revision :)
Definition at line 144 of file kis_memento_manager.h.
|
protected |
INDEX of tiles to be committed with next commit() We use a hash table to be able to check that we have the only memento item for a tile per commit efficiently
Definition at line 128 of file kis_memento_manager.h.
|
protected |
The flag that blocks registration of changes on tiles. This is a temporary state of the memento manager, that is used for traveling in history
Definition at line 161 of file kis_memento_manager.h.
|
protected |
Main list that stores every commit ever done
Definition at line 133 of file kis_memento_manager.h.