File indexing completed on 2024-06-16 04:12:34
0001 /* 0002 * SPDX-FileCopyrightText: 2009 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KIS_MEMENTO_ITEM_H_ 0008 #define KIS_MEMENTO_ITEM_H_ 0009 0010 #include <kis_shared.h> 0011 #include <kis_shared_ptr.h> 0012 #include "kis_tile.h" 0013 0014 0015 class KisMementoItem; 0016 typedef KisSharedPtr<KisMementoItem> KisMementoItemSP; 0017 0018 class KisMementoItem : public KisShared 0019 { 0020 public: 0021 enum enumType { 0022 CHANGED = 0x0, 0023 DELETED = 0x1 0024 }; 0025 0026 public: 0027 KisMementoItem() 0028 : m_tileData(0), m_committedFlag(false) { 0029 } 0030 0031 KisMementoItem(const KisMementoItem& rhs) 0032 : KisShared(), 0033 m_tileData(rhs.m_tileData), 0034 m_committedFlag(rhs.m_committedFlag), 0035 m_type(rhs.m_type), 0036 m_col(rhs.m_col), 0037 m_row(rhs.m_row), 0038 m_next(0), 0039 m_parent(0) { 0040 if (m_tileData) { 0041 if (m_committedFlag) 0042 m_tileData->acquire(); 0043 else 0044 m_tileData->ref(); 0045 } 0046 } 0047 0048 /** 0049 * Automatically called by Kis..HashTable. It means that 0050 * this mementoItem is a root item of parental hierarchy. 0051 * So m_parent should be NULL. Taking into account the tile 0052 * was not present before, the status of the item 0053 * should be 'DELETED'. 0054 * This memento item is considered as committed, so we acquire 0055 * the tile data right at the beginning. 0056 */ 0057 KisMementoItem(qint32 col, qint32 row, KisTileData* defaultTileData, KisMementoManager *mm) { 0058 Q_UNUSED(mm); 0059 m_tileData = defaultTileData; 0060 /* acquire the tileData deliberately and completely */ 0061 m_tileData->acquire(); 0062 m_col = col; 0063 m_row = row; 0064 m_type = DELETED; 0065 m_parent = 0; 0066 m_committedFlag = true; /* yes, we've committed it */ 0067 } 0068 0069 /** 0070 * FIXME: Not sure this function has any particular usecase. 0071 * Just leave it for compatibility with a hash table 0072 */ 0073 KisMementoItem(const KisMementoItem &rhs, KisMementoManager *mm) { 0074 Q_UNUSED(mm); 0075 m_tileData = rhs.m_tileData; 0076 /* Setting counter: m_refCount++ */ 0077 m_tileData->ref(); 0078 m_col = rhs.m_col; 0079 m_row = rhs.m_row; 0080 m_type = CHANGED; 0081 m_parent = 0; 0082 m_committedFlag = false; 0083 } 0084 0085 ~KisMementoItem() { 0086 releaseTileData(); 0087 } 0088 0089 void notifyDetachedFromDataManager() { 0090 // just to resemble KisTile... 0091 } 0092 0093 void notifyDeadWithoutDetaching() { 0094 // just to resemble KisTile... 0095 } 0096 0097 void notifyAttachedToDataManager(KisMementoManager *mm) { 0098 Q_UNUSED(mm); 0099 // just to resemble KisTile... 0100 } 0101 0102 0103 void reset() { 0104 releaseTileData(); 0105 m_tileData = 0; 0106 m_committedFlag = false; 0107 } 0108 0109 void deleteTile(KisTile* tile, KisTileData* defaultTileData) { 0110 m_tileData = defaultTileData; 0111 /* Setting counter: m_refCount++ */ 0112 m_tileData->ref(); 0113 0114 m_col = tile->col(); 0115 m_row = tile->row(); 0116 m_type = DELETED; 0117 } 0118 0119 void changeTile(KisTile* tile) { 0120 m_tileData = tile->tileData(); 0121 /* Setting counter: m_refCount++ */ 0122 m_tileData->ref(); 0123 m_col = tile->col(); 0124 m_row = tile->row(); 0125 m_type = CHANGED; 0126 } 0127 0128 void commit() { 0129 if (m_committedFlag) return; 0130 if (m_tileData) { 0131 /** 0132 * Setting counters to proper values: 0133 * m_refCount++, m_usersCount++; 0134 * m_refCount-- 0135 */ 0136 m_tileData->acquire(); 0137 m_tileData->deref(); 0138 0139 m_tileData->setMementoed(true); 0140 } 0141 m_committedFlag = true; 0142 } 0143 0144 inline KisTileSP tile(KisMementoManager *mm) { 0145 Q_ASSERT(m_tileData); 0146 return KisTileSP(new KisTile(m_col, m_row, m_tileData, mm)); 0147 } 0148 0149 inline enumType type() { 0150 return m_type; 0151 } 0152 0153 inline void setParent(KisMementoItemSP parent) { 0154 m_parent = parent; 0155 } 0156 inline KisMementoItemSP parent() { 0157 return m_parent; 0158 } 0159 0160 // Stuff for Kis..HashTable 0161 inline void setNext(KisMementoItemSP next) { 0162 m_next = next; 0163 } 0164 inline KisMementoItemSP next() const { 0165 return m_next; 0166 } 0167 inline qint32 col() const { 0168 return m_col; 0169 } 0170 inline qint32 row() const { 0171 return m_row; 0172 } 0173 inline KisTileData* tileData() const { 0174 return m_tileData; 0175 } 0176 0177 void debugPrintInfo() { 0178 QString s = QString("------\n" 0179 "Memento item:\t\t0x%1 (0x%2)\n" 0180 " status:\t(%3,%4) %5%6\n" 0181 " parent:\t0x%7 (0x%8)\n" 0182 " next:\t0x%9 (0x%10)\n") 0183 .arg((quintptr)this) 0184 .arg((quintptr)m_tileData) 0185 .arg(m_col) 0186 .arg(m_row) 0187 .arg((m_type == CHANGED) ? 'W' : 'D') 0188 .arg(m_committedFlag ? 'C' : '-') 0189 .arg((quintptr)m_parent.data()) 0190 .arg(m_parent ? (quintptr)m_parent->m_tileData : 0) 0191 .arg((quintptr)m_next.data()) 0192 .arg(m_next ? (quintptr)m_next->m_tileData : 0); 0193 dbgKrita << s; 0194 } 0195 0196 protected: 0197 void releaseTileData() { 0198 if (m_tileData) { 0199 if (m_committedFlag) { 0200 m_tileData->setMementoed(false); 0201 m_tileData->release(); 0202 } 0203 else { 0204 m_tileData->deref(); 0205 } 0206 } 0207 } 0208 0209 protected: 0210 KisTileData *m_tileData {0}; 0211 bool m_committedFlag {false}; 0212 enumType m_type {CHANGED}; 0213 0214 qint32 m_col {0}; 0215 qint32 m_row {0}; 0216 0217 KisMementoItemSP m_next; 0218 KisMementoItemSP m_parent; 0219 private: 0220 }; 0221 0222 0223 #endif /* KIS_MEMENTO_ITEM_H_ */ 0224