Skip to content

Commit fedcf05

Browse files
committed
epoch to clear
1 parent 0ea45c8 commit fedcf05

3 files changed

Lines changed: 25 additions & 0 deletions

File tree

lib/usdUfe/undo/UsdUndoStateDelegate.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ class SpecCopier : public SdfAbstractDataSpecVisitor
6565

6666
namespace USDUFE_NS_DEF {
6767

68+
uint32_t UsdUndoStateDelegate::_invertEpoch { 0 };
69+
70+
void UsdUndoStateDelegate::beginInvert() { ++_invertEpoch; }
71+
6872
UsdUndoStateDelegate::UsdUndoStateDelegate()
6973
: _dirty(false)
7074
, _setMessageAlreadyShowed(false)
@@ -106,6 +110,15 @@ void UsdUndoStateDelegate::invertSetField(
106110
TF_DEBUG(USDUFE_UNDOSTATEDELEGATE)
107111
.Msg("Inverting set Field '%s' for Spec '%s'\n", fieldName.GetText(), path.GetText());
108112

113+
// Clear the tracking set when a new undo/redo replay starts. beginReplay()
114+
// increments _replayEpoch at the top of each doInvert() call. Without this,
115+
// entries from a previous undo would persist into a subsequent redo and
116+
// incorrectly filter children that invertDeleteSpec is about to recreate.
117+
if (_invertEpoch != _lastSeenEpoch) {
118+
_specsDeletedByInvertCreate.clear();
119+
_lastSeenEpoch = _invertEpoch;
120+
}
121+
109122
// When restoring a PrimChildren or PropertyChildren field, the inverse value may
110123
// reference children whose specs no longer exist. There are two reasons this happens:
111124
//

lib/usdUfe/undo/UsdUndoStateDelegate.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ class USDUFE_PUBLIC UsdUndoStateDelegate : public SdfLayerStateDelegateBase
4949

5050
static UsdUndoStateDelegateRefPtr New();
5151

52+
/// Called at the start of each undo/redo replay. Increments an epoch counter, useful
53+
/// to manage any per-undo/redo state.
54+
static void beginInvert();
55+
5256
private:
5357
void invertSetField(const SdfPath& path, const TfToken& fieldName, const VtValue& inverse);
5458
void invertCreateSpec(const SdfPath& path, bool inert);
@@ -131,7 +135,11 @@ class USDUFE_PUBLIC UsdUndoStateDelegate : public SdfLayerStateDelegateBase
131135
bool _setMessageAlreadyShowed;
132136

133137
// Tracks specs deleted by invertCreateSpec during an undo/redo replay.
138+
// See invertSetField and invertCreateSpec for detailed documentation.
134139
std::unordered_set<SdfPath, SdfPath::Hash> _specsDeletedByInvertCreate;
140+
141+
uint32_t _lastSeenEpoch { 0 };
142+
static uint32_t _invertEpoch;
135143
};
136144

137145
} // namespace USDUFE_NS_DEF

lib/usdUfe/undo/UsdUndoableItem.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "UsdUndoableItem.h"
1818

1919
#include <usdUfe/undo/UsdUndoBlock.h>
20+
#include <usdUfe/undo/UsdUndoStateDelegate.h>
2021

2122
#include <pxr/usd/sdf/changeBlock.h>
2223

@@ -33,6 +34,9 @@ void UsdUndoableItem::doInvert()
3334
"stack.");
3435
}
3536

37+
// Signal so that any per-invert tracking state can be updated.
38+
UsdUndoStateDelegate::beginInvert();
39+
3640
UsdUndoBlock undoBlock(this);
3741

3842
// call invert functions in reverse order

0 commit comments

Comments
 (0)