Skip to content

Commit fd06b8f

Browse files
committed
feat: refactor view stack management with Replace and AddToStack methods
1 parent 3bdb696 commit fd06b8f

1 file changed

Lines changed: 83 additions & 70 deletions

File tree

Assets/PurrUI/Runtime/ViewStack.cs

Lines changed: 83 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -109,32 +109,9 @@ public MonoView Push(MonoView prefab)
109109
}
110110

111111
if (_stack.Count > 0)
112-
{
113-
var currentTop = _stack[^1];
114-
currentTop.MoveToBackground();
115-
}
116-
117-
var idx = _stack.Count;
118-
var instance = Instantiate(prefab, _parent);
119-
_stack.Add(instance);
120-
instance.Initialize(this);
121-
instance.UpdateOrder(idx + _orderOffset);
122-
instance.OnPushed();
112+
_stack[^1].MoveToBackground();
123113

124-
var transition = instance.EnterTransition();
125-
if (transition != null)
126-
{
127-
instance.canvasGroup.interactable = false;
128-
instance.canvasGroup.blocksRaycasts = false;
129-
StartCoroutine(RunEnterTransition(instance, transition));
130-
ApplyCulling(false);
131-
}
132-
else
133-
{
134-
ApplyCulling(true);
135-
}
136-
137-
return instance;
114+
return AddToStack(prefab);
138115
}
139116

140117
private void UpdateVisibility()
@@ -233,8 +210,6 @@ private IEnumerator RunUncullTransition(MonoView view, IEnumerator transition)
233210
/// The prefab must be included in the WindowPrefabs collection.
234211
/// If no prefab of that type is found, logs an error and does nothing.
235212
/// </summary>
236-
/// <typeparam name="T"></typeparam>
237-
/// <returns></returns>
238213
public T Push<T>() where T : MonoView
239214
{
240215
if (!TryGet<T>(out var prefab))
@@ -243,34 +218,7 @@ public T Push<T>() where T : MonoView
243218
return null;
244219
}
245220

246-
var idx = _stack.Count;
247-
248-
if (idx > 0)
249-
{
250-
var currentTop = _stack[idx - 1];
251-
currentTop.MoveToBackground();
252-
}
253-
254-
var instance = Instantiate(prefab, _parent);
255-
_stack.Add(instance);
256-
instance.Initialize(this);
257-
instance.UpdateOrder(idx + _orderOffset);
258-
instance.OnPushed();
259-
260-
var transition = instance.EnterTransition();
261-
if (transition != null)
262-
{
263-
instance.canvasGroup.interactable = false;
264-
instance.canvasGroup.blocksRaycasts = false;
265-
StartCoroutine(RunEnterTransition(instance, transition));
266-
ApplyCulling(false);
267-
}
268-
else
269-
{
270-
ApplyCulling(true);
271-
}
272-
273-
return instance;
221+
return (T)Push(prefab);
274222
}
275223

276224
/// <summary>
@@ -284,21 +232,7 @@ public void Pop()
284232
return;
285233
}
286234

287-
var topView = _stack[^1];
288-
_stack.RemoveAt(_stack.Count - 1);
289-
topView.OnPopped();
290-
291-
var transition = topView.ExitTransition();
292-
if (transition != null)
293-
{
294-
topView.canvasGroup.interactable = false;
295-
topView.canvasGroup.blocksRaycasts = false;
296-
StartCoroutine(RunExitTransition(topView, transition));
297-
}
298-
else
299-
{
300-
topView.DestroyMe();
301-
}
235+
RemoveTop();
302236

303237
if (_stack.Count > 0)
304238
{
@@ -359,6 +293,41 @@ public void Pop(MonoView instance)
359293
UpdateVisibility();
360294
}
361295

296+
/// <summary>
297+
/// Replaces the top window with a new window instantiated from the provided prefab.
298+
/// The old top plays its exit transition while the new one plays its enter transition.
299+
/// Views below are not affected (no unnecessary uncull/re-cull).
300+
/// </summary>
301+
public MonoView Replace(MonoView prefab)
302+
{
303+
if (prefab == null)
304+
{
305+
Debug.LogError("[WindowStack] Provided prefab is null.", this);
306+
return null;
307+
}
308+
309+
if (_stack.Count > 0)
310+
RemoveTop();
311+
312+
return AddToStack(prefab);
313+
}
314+
315+
/// <summary>
316+
/// Replaces the top window with a new window of the specified type.
317+
/// The old top plays its exit transition while the new one plays its enter transition.
318+
/// Views below are not affected (no unnecessary uncull/re-cull).
319+
/// </summary>
320+
public T Replace<T>() where T : MonoView
321+
{
322+
if (!TryGet<T>(out var prefab))
323+
{
324+
Debug.LogError($"[WindowStack] No window prefab of type `{typeof(T)}` found in WindowPrefabs.", this);
325+
return null;
326+
}
327+
328+
return (T)Replace(prefab);
329+
}
330+
362331
/// <summary>
363332
/// Moves the specified instance to the top of the stack. If the instance is not in the stack, does nothing.
364333
/// </summary>
@@ -398,6 +367,50 @@ public void MoveToTop<T>() where T : MonoView
398367
}
399368
}
400369

370+
private void RemoveTop()
371+
{
372+
var topView = _stack[^1];
373+
_stack.RemoveAt(_stack.Count - 1);
374+
topView.OnPopped();
375+
376+
var transition = topView.ExitTransition();
377+
if (transition != null)
378+
{
379+
topView.canvasGroup.interactable = false;
380+
topView.canvasGroup.blocksRaycasts = false;
381+
StartCoroutine(RunExitTransition(topView, transition));
382+
}
383+
else
384+
{
385+
topView.DestroyMe();
386+
}
387+
}
388+
389+
private MonoView AddToStack(MonoView prefab)
390+
{
391+
var idx = _stack.Count;
392+
var instance = Instantiate(prefab, _parent);
393+
_stack.Add(instance);
394+
instance.Initialize(this);
395+
instance.UpdateOrder(idx + _orderOffset);
396+
instance.OnPushed();
397+
398+
var transition = instance.EnterTransition();
399+
if (transition != null)
400+
{
401+
instance.canvasGroup.interactable = false;
402+
instance.canvasGroup.blocksRaycasts = false;
403+
StartCoroutine(RunEnterTransition(instance, transition));
404+
ApplyCulling(false);
405+
}
406+
else
407+
{
408+
ApplyCulling(true);
409+
}
410+
411+
return instance;
412+
}
413+
401414
private IEnumerator RunEnterTransition(MonoView view, IEnumerator transition)
402415
{
403416
yield return transition;

0 commit comments

Comments
 (0)