@@ -27,17 +27,20 @@ sealed class AudioContainerWindow : EditorWindow
27
27
internal readonly AudioContainerWindowState State = new ( ) ;
28
28
29
29
/// <summary>
30
- /// Holds the added list elements in the list interaction callbacks
30
+ /// Holds the added list elements in the list interaction callbacks.
31
+ /// Only used locally in these methods, but it's a global member to avoid GC.
31
32
/// </summary>
32
33
readonly List < AudioContainerElement > m_AddedElements = new ( ) ;
33
34
35
+ readonly string k_EmptyGuidString = Guid . Empty . ToString ( "N" ) ;
36
+
34
37
VisualElement m_ContainerRootVisualElement ;
35
38
VisualElement m_Day0RootVisualElement ;
36
39
37
40
// Preview section
38
41
Label m_AssetNameLabel ;
39
- Button m_PlayButton ;
40
- VisualElement m_PlayButtonImage ;
42
+ Button m_PlayStopButton ;
43
+ VisualElement m_PlayStopButtonImage ;
41
44
Button m_SkipButton ;
42
45
VisualElement m_SkipButtonImage ;
43
46
@@ -94,7 +97,7 @@ sealed class AudioContainerWindow : EditorWindow
94
97
bool m_IsInitializing ;
95
98
bool m_Day0ElementsInitialized ;
96
99
bool m_ContainerElementsInitialized ;
97
- private bool m_ClipFieldProgressBarsAreCleared = true ;
100
+ bool m_ClipFieldProgressBarsAreCleared = true ;
98
101
99
102
/// <summary>
100
103
/// Holds the previous state of the list elements for undo/delete housekeeping
@@ -117,8 +120,6 @@ void OnEnable()
117
120
{
118
121
Instance = this ;
119
122
120
- Undo . undoRedoPerformed += OnUndoRedoPerformed ;
121
-
122
123
State . TargetChanged += OnTargetChanged ;
123
124
State . TransportStateChanged += OnTransportStateChanged ;
124
125
State . EditorPauseStateChanged += EditorPauseStateChanged ;
@@ -143,13 +144,14 @@ void OnDisable()
143
144
UnsubscribeFromClipListCallbacksAndEvents ( ) ;
144
145
UnsubscribeFromAutomaticTriggerCallbacksAndEvents ( ) ;
145
146
146
- Undo . undoRedoPerformed -= OnUndoRedoPerformed ;
147
+ EditorApplication . update -= OneTimeEditorApplicationUpdate ;
147
148
148
149
State . TargetChanged -= OnTargetChanged ;
149
150
State . TransportStateChanged -= OnTransportStateChanged ;
150
151
State . EditorPauseStateChanged -= EditorPauseStateChanged ;
151
152
152
153
State . OnDestroy ( ) ;
154
+
153
155
m_CachedElements . Clear ( ) ;
154
156
m_AddedElements . Clear ( ) ;
155
157
}
@@ -333,8 +335,8 @@ static void InsertUnitFieldForFloatField(VisualElement field, string unit)
333
335
void InitializePreviewElements ( )
334
336
{
335
337
m_AssetNameLabel = UIToolkitUtilities . GetChildByName < Label > ( m_ContainerRootVisualElement , "asset-name-label" ) ;
336
- m_PlayButton = UIToolkitUtilities . GetChildByName < Button > ( m_ContainerRootVisualElement , "play-button" ) ;
337
- m_PlayButtonImage = UIToolkitUtilities . GetChildByName < VisualElement > ( m_ContainerRootVisualElement , "play-button-image" ) ;
338
+ m_PlayStopButton = UIToolkitUtilities . GetChildByName < Button > ( m_ContainerRootVisualElement , "play-button" ) ;
339
+ m_PlayStopButtonImage = UIToolkitUtilities . GetChildByName < VisualElement > ( m_ContainerRootVisualElement , "play-button-image" ) ;
338
340
m_SkipButton = UIToolkitUtilities . GetChildByName < Button > ( m_ContainerRootVisualElement , "skip-button" ) ;
339
341
m_SkipButtonImage = UIToolkitUtilities . GetChildByName < VisualElement > ( m_ContainerRootVisualElement , "skip-button-image" ) ;
340
342
@@ -344,17 +346,17 @@ void InitializePreviewElements()
344
346
345
347
void SubscribeToPreviewCallbacksAndEvents ( )
346
348
{
347
- m_PlayButton . clicked += OnPlayStopButtonClicked ;
349
+ m_PlayStopButton . clicked += OnPlayStopButtonClicked ;
348
350
m_SkipButton . clicked += OnSkipButtonClicked ;
349
351
}
350
352
351
353
void UnsubscribeFromPreviewCallbacksAndEvents ( )
352
354
{
353
- if ( m_PlayButton != null )
354
- m_PlayButton . clicked -= OnPlayStopButtonClicked ;
355
+ if ( m_PlayStopButton != null )
356
+ m_PlayStopButton . clicked -= OnPlayStopButtonClicked ;
355
357
356
- if ( m_PlayButton != null )
357
- m_PlayButton . clicked -= OnSkipButtonClicked ;
358
+ if ( m_SkipButton != null )
359
+ m_SkipButton . clicked -= OnSkipButtonClicked ;
358
360
}
359
361
360
362
void BindAndTrackPreviewProperties ( )
@@ -386,15 +388,15 @@ void UpdateTransportButtonStates()
386
388
{
387
389
var editorIsPaused = EditorApplication . isPaused ;
388
390
389
- m_PlayButton ? . SetEnabled ( State . IsReadyToPlay ( ) && ! editorIsPaused ) ;
391
+ m_PlayStopButton ? . SetEnabled ( State . IsReadyToPlay ( ) && ! editorIsPaused ) ;
390
392
m_SkipButton ? . SetEnabled ( State . IsPlayingOrPaused ( ) && State . AudioContainer . triggerMode == AudioRandomContainerTriggerMode . Automatic && ! editorIsPaused ) ;
391
393
392
394
var image =
393
395
State . IsPlayingOrPaused ( )
394
396
? UIToolkitUtilities . LoadIcon ( "Stop" )
395
397
: UIToolkitUtilities . LoadIcon ( "Play" ) ;
396
398
397
- m_PlayButtonImage . style . backgroundImage = new StyleBackground ( image ) ;
399
+ m_PlayStopButtonImage . style . backgroundImage = new StyleBackground ( image ) ;
398
400
}
399
401
400
402
void OnTransportStateChanged ( object sender , EventArgs e )
@@ -435,7 +437,6 @@ void InitializeVolumeElements()
435
437
volumeRandomizationMaxField . label = "" ;
436
438
volumeRandomizationMaxField . formatString = "0.#" ;
437
439
InsertUnitFieldForFloatField ( volumeRandomizationMaxField , "dB" ) ;
438
-
439
440
}
440
441
441
442
void SubscribeToVolumeCallbacksAndEvents ( )
@@ -794,18 +795,16 @@ void OnListItemsAdded(IEnumerable<int> indices)
794
795
795
796
m_AddedElements . Clear ( ) ;
796
797
797
- var undoName = "Add AudioContainerElement " ;
798
+ var undoName = $ "Add { nameof ( AudioRandomContainer ) } element ";
798
799
799
800
if ( indicesArray . Length > 1 )
800
801
{
801
802
undoName = $ "{ undoName } s";
802
803
}
803
804
804
805
Undo . SetCurrentGroupName ( undoName ) ;
805
- SetTitle ( ) ;
806
+
806
807
m_AddedElements . Clear ( ) ;
807
- // Force a list rebuild when the list size has changed or it will not render correctly
808
- EditorApplication . update += DoDelayedListRebuild ;
809
808
}
810
809
811
810
void OnListItemsRemoved ( IEnumerable < int > indices )
@@ -826,27 +825,25 @@ void OnListItemsRemoved(IEnumerable<int> indices)
826
825
827
826
State . AudioContainer . NotifyObservers ( AudioRandomContainer . ChangeEventType . List ) ;
828
827
829
- var undoName = "Remove AudioContainerElement " ;
828
+ var undoName = $ "Remove { nameof ( AudioRandomContainer ) } element ";
830
829
831
830
if ( indicesArray . Length > 1 )
832
831
{
833
832
undoName = $ "{ undoName } s";
834
833
}
835
834
836
835
Undo . SetCurrentGroupName ( undoName ) ;
837
- SetTitle ( ) ;
838
- // Force a list rebuild when the list size has changed or it will not render correctly
839
- EditorApplication . update += DoDelayedListRebuild ;
840
836
}
841
837
842
838
void OnItemListIndexChanged ( int oldIndex , int newIndex )
843
839
{
840
+ Undo . SetCurrentGroupName ( $ "Reorder { nameof ( AudioRandomContainer ) } list") ;
844
841
State . AudioContainer . NotifyObservers ( AudioRandomContainer . ChangeEventType . List ) ;
845
842
}
846
843
847
844
void OnAudioClipDrag ( List < AudioClip > audioClips )
848
845
{
849
- var undoName = "Add AudioContainerElement " ;
846
+ var undoName = $ "Add { nameof ( AudioRandomContainer ) } element ";
850
847
851
848
if ( audioClips . Count > 1 )
852
849
undoName = $ "{ undoName } s";
@@ -875,17 +872,36 @@ void OnAudioClipDrag(List<AudioClip> audioClips)
875
872
Undo . RegisterCreatedObjectUndo ( element , "Create AudioContainerElement" ) ;
876
873
877
874
m_AddedElements . Clear ( ) ;
878
-
879
- SetTitle ( ) ;
880
875
Undo . SetCurrentGroupName ( undoName ) ;
881
- // Force a list rebuild when the list size has changed or it will not render correctly
882
- EditorApplication . update += DoDelayedListRebuild ;
883
876
}
884
877
885
878
void OnAudioClipListChanged ( SerializedProperty property )
886
879
{
887
- UpdateTransportButtonStates ( ) ;
880
+ // Do manual fixup of orphaned subassets after a possible undo of item removal
881
+ // because the undo system does not play nice with RegisterCreatedObjectUndo.
882
+ if ( m_CachedElements . Count < State . AudioContainer . elements . Length )
883
+ {
884
+ var elements = State . AudioContainer . elements ;
885
+
886
+ foreach ( var elm in elements )
887
+ {
888
+ AssetDatabase . TryGetGUIDAndLocalFileIdentifier ( elm , out var guid , out var localId ) ;
889
+
890
+ // An empty asset GUID means the subasset has lost the reference
891
+ // to the main asset after an undo of item removal, so re-add it manually.
892
+ if ( guid . Equals ( k_EmptyGuidString ) )
893
+ AssetDatabase . AddObjectToAsset ( elm , State . AudioContainer ) ;
894
+ }
895
+ }
896
+
897
+ // Update the cached list of elements
888
898
m_CachedElements = State . AudioContainer . elements . ToList ( ) ;
899
+
900
+ // Force a list rebuild when the list has changed or it will not always render correctly
901
+ m_ClipsListView . Rebuild ( ) ;
902
+
903
+ UpdateTransportButtonStates ( ) ;
904
+ SetTitle ( ) ;
889
905
}
890
906
891
907
void UpdateClipFieldProgressBars ( )
@@ -939,12 +955,6 @@ void ClearClipFieldProgressBars()
939
955
m_ClipFieldProgressBarsAreCleared = true ;
940
956
}
941
957
942
- void DoDelayedListRebuild ( )
943
- {
944
- m_ClipsListView . Rebuild ( ) ;
945
- EditorApplication . update -= DoDelayedListRebuild ;
946
- }
947
-
948
958
#endregion
949
959
950
960
#region TriggerAndPlaybackMode
@@ -1185,24 +1195,6 @@ void OnCountRandomizationButtonClicked()
1185
1195
1186
1196
#region GlobalEditorCallbackHandlers
1187
1197
1188
- void OnUndoRedoPerformed ( )
1189
- {
1190
- if ( m_ContainerRootVisualElement == null
1191
- || m_ContainerRootVisualElement . style . display == DisplayStyle . None
1192
- || State . AudioContainer == null )
1193
- return ;
1194
-
1195
- if ( m_CachedElements . Count != State . AudioContainer . elements . Length )
1196
- {
1197
- // Force a list rebuild when the list size has increased or it will not render correctly
1198
- // if (m_CachedElements.Count < State.AudioContainer.elements.Length)
1199
- m_ClipsListView . Rebuild ( ) ;
1200
-
1201
- SetTitle ( ) ;
1202
- m_CachedElements = State . AudioContainer . elements . ToList ( ) ;
1203
- }
1204
- }
1205
-
1206
1198
void OnWillSaveAssets ( IEnumerable < string > paths )
1207
1199
{
1208
1200
if ( State . AudioContainer == null )
0 commit comments