@@ -102,6 +102,9 @@ public T FindWindow<T>() where T : MonoView
102102 /// </summary>
103103 public MonoView Push ( MonoView prefab )
104104 {
105+ if ( ! Application . isPlaying )
106+ return null ;
107+
105108 if ( prefab == null )
106109 {
107110 Debug . LogError ( "[WindowStack] Provided prefab is null." , this ) ;
@@ -226,6 +229,9 @@ public T Push<T>() where T : MonoView
226229 /// </summary>
227230 public void Pop ( )
228231 {
232+ if ( ! Application . isPlaying )
233+ return ;
234+
229235 if ( _stack . Count == 0 )
230236 {
231237 Debug . LogError ( "[WindowStack] No windows to pop." , this ) ;
@@ -238,9 +244,12 @@ public void Pop()
238244 {
239245 var newTopIdx = _stack . Count - 1 ;
240246 var newTop = _stack [ newTopIdx ] ;
241- newTop . transform . SetAsLastSibling ( ) ;
242- newTop . MoveToForeground ( ) ;
243- newTop . UpdateOrder ( newTopIdx + _orderOffset ) ;
247+ if ( newTop )
248+ {
249+ newTop . transform . SetAsLastSibling ( ) ;
250+ newTop . MoveToForeground ( ) ;
251+ newTop . UpdateOrder ( newTopIdx + _orderOffset ) ;
252+ }
244253 }
245254 UpdateVisibility ( ) ;
246255 }
@@ -250,8 +259,13 @@ public void Pop()
250259 /// </summary>
251260 public void Clear ( )
252261 {
253- while ( _stack . Count > 0 )
254- Pop ( ) ;
262+ for ( int i = _stack . Count - 1 ; i >= 0 ; i -- )
263+ {
264+ var view = _stack [ i ] ;
265+ view . OnPopped ( ) ;
266+ view . parentStack = null ;
267+ }
268+ _stack . Clear ( ) ;
255269 }
256270
257271 /// <summary>
@@ -260,6 +274,9 @@ public void Clear()
260274 /// <param name="instance"></param>
261275 public void Pop ( MonoView instance )
262276 {
277+ if ( ! Application . isPlaying )
278+ return ;
279+
263280 int idx = _stack . IndexOf ( instance ) ;
264281
265282 if ( idx == - 1 )
@@ -277,6 +294,7 @@ public void Pop(MonoView instance)
277294
278295 _stack . RemoveAt ( idx ) ;
279296 instance . OnPopped ( ) ;
297+ instance . parentStack = null ;
280298
281299 var transition = instance . ExitTransition ( ) ;
282300 if ( transition != null )
@@ -300,6 +318,9 @@ public void Pop(MonoView instance)
300318 /// </summary>
301319 public MonoView Replace ( MonoView prefab )
302320 {
321+ if ( ! Application . isPlaying )
322+ return null ;
323+
303324 if ( prefab == null )
304325 {
305326 Debug . LogError ( "[WindowStack] Provided prefab is null." , this ) ;
@@ -328,6 +349,108 @@ public T Replace<T>() where T : MonoView
328349 return ( T ) Replace ( prefab ) ;
329350 }
330351
352+ /// <summary>
353+ /// Replaces the specified instance in the stack with a new window instantiated from the provided prefab.
354+ /// The old instance plays its exit transition while the new one plays its enter transition.
355+ /// The new window takes the same position in the stack as the old one.
356+ /// </summary>
357+ public MonoView Replace ( MonoView instance , MonoView prefab )
358+ {
359+ if ( ! Application . isPlaying )
360+ return null ;
361+
362+ if ( prefab == null )
363+ {
364+ Debug . LogError ( "[WindowStack] Provided prefab is null." , this ) ;
365+ return null ;
366+ }
367+
368+ int idx = _stack . IndexOf ( instance ) ;
369+
370+ if ( idx == - 1 )
371+ {
372+ Debug . LogError ( "[WindowStack] The provided window instance is not in the stack." , this ) ;
373+ return null ;
374+ }
375+
376+ // If it's the top window, use the regular Replace method
377+ if ( idx == _stack . Count - 1 )
378+ return Replace ( prefab ) ;
379+
380+ // Remove the instance at its position
381+ _stack . RemoveAt ( idx ) ;
382+ instance . OnPopped ( ) ;
383+ instance . parentStack = null ;
384+
385+ var exitTransition = instance . ExitTransition ( ) ;
386+ if ( exitTransition != null )
387+ {
388+ instance . canvasGroup . blocksRaycasts = false ;
389+ StartCoroutine ( RunExitTransition ( instance , exitTransition ) ) ;
390+ }
391+ else
392+ {
393+ instance . DestroyMe ( ) ;
394+ }
395+
396+ // Insert new instance at the same position
397+ return InsertIntoStack ( prefab , idx ) ;
398+ }
399+
400+ /// <summary>
401+ /// Replaces the specified instance in the stack with a new window of the specified type.
402+ /// The old instance plays its exit transition while the new one plays its enter transition.
403+ /// The new window takes the same position in the stack as the old one.
404+ /// </summary>
405+ public T Replace < T > ( MonoView instance ) where T : MonoView
406+ {
407+ if ( ! TryGet < T > ( out var prefab ) )
408+ {
409+ Debug . LogError ( $ "[WindowStack] No window prefab of type `{ typeof ( T ) } ` found in WindowPrefabs.", this ) ;
410+ return null ;
411+ }
412+
413+ return ( T ) Replace ( instance , prefab ) ;
414+ }
415+
416+ /// <summary>
417+ /// Replaces the specified instance in the stack with a new window instantiated from the provided prefab.
418+ /// If the instance is no longer part of the stack, pushes the new window instead.
419+ /// </summary>
420+ public MonoView ReplaceOrPush ( MonoView instance , MonoView prefab )
421+ {
422+ if ( ! Application . isPlaying )
423+ return null ;
424+
425+ if ( prefab == null )
426+ {
427+ Debug . LogError ( "[WindowStack] Provided prefab is null." , this ) ;
428+ return null ;
429+ }
430+
431+ int idx = _stack . IndexOf ( instance ) ;
432+
433+ if ( idx == - 1 )
434+ return Push ( prefab ) ;
435+
436+ return Replace ( instance , prefab ) ;
437+ }
438+
439+ /// <summary>
440+ /// Replaces the specified instance in the stack with a new window of the specified type.
441+ /// If the instance is no longer part of the stack, pushes the new window instead.
442+ /// </summary>
443+ public T ReplaceOrPush < T > ( MonoView instance ) where T : MonoView
444+ {
445+ if ( ! TryGet < T > ( out var prefab ) )
446+ {
447+ Debug . LogError ( $ "[WindowStack] No window prefab of type `{ typeof ( T ) } ` found in WindowPrefabs.", this ) ;
448+ return null ;
449+ }
450+
451+ return ( T ) ReplaceOrPush ( instance , prefab ) ;
452+ }
453+
331454 /// <summary>
332455 /// Moves the specified instance to the top of the stack. If the instance is not in the stack, does nothing.
333456 /// </summary>
@@ -372,6 +495,7 @@ private void RemoveTop()
372495 var topView = _stack [ ^ 1 ] ;
373496 _stack . RemoveAt ( _stack . Count - 1 ) ;
374497 topView . OnPopped ( ) ;
498+ topView . parentStack = null ;
375499
376500 var transition = topView . ExitTransition ( ) ;
377501 if ( transition != null )
@@ -388,11 +512,15 @@ private void RemoveTop()
388512
389513 private MonoView AddToStack ( MonoView prefab )
390514 {
391- var idx = _stack . Count ;
515+ return InsertIntoStack ( prefab , _stack . Count ) ;
516+ }
517+
518+ private MonoView InsertIntoStack ( MonoView prefab , int idx )
519+ {
392520 var instance = Instantiate ( prefab , _parent ) ;
393- _stack . Add ( instance ) ;
521+ _stack . Insert ( idx , instance ) ;
394522 instance . Initialize ( this ) ;
395- instance . UpdateOrder ( idx + _orderOffset ) ;
523+ UpdateOrder ( idx ) ;
396524 instance . OnPushed ( ) ;
397525
398526 var transition = instance . EnterTransition ( ) ;
@@ -427,5 +555,10 @@ private static IEnumerator RunExitTransition(MonoView view, IEnumerator transiti
427555 yield return transition ;
428556 if ( view ) view . DestroyMe ( ) ;
429557 }
558+
559+ private void OnDestroy ( )
560+ {
561+ Clear ( ) ;
562+ }
430563 }
431564}
0 commit comments