/// <summary> /// Queue the top-most screen to be popped from the screen stack. /// Callback will be invoked when the screen is popped from the stack. /// </summary> public void QueuePop(PoppedDelegate callback = null) { #if PRINT_QUEUE DebugPrintQueue(string.Format("[UIManager] QueuePop")); #endif Screen topScreen = GetTopScreen(); if (topScreen == null) { return; } QueuedScreenPop pop = new QueuedScreenPop(); pop.id = topScreen.id; pop.callback = callback; _queue.Enqueue(pop); #if PRINT_QUEUE DebugPrintQueue(string.Format("[UIManager] Enqueued Screen: {0}", pop)); #endif if (CanExecuteNextQueueItem()) { ExecuteNextQueueItem(); } }
/// <summary> /// Queue the screen to be popped from the screen stack. This will pop all screens on top of it as well. /// Callback will be invoked when the screen is reached, or popped if 'include' is true. /// </summary> public void QueuePopTo(RP.Screen.Id id, bool include, PoppedDelegate callback = null) { #if PRINT_QUEUE DebugPrintQueue(string.Format("[UIManager] QueuePopTo id: {0}, include: {1}", id, include)); #endif bool found = false; for (int i = 0; i < _stack.Count; i++) { var screen = _stack[i]; if (screen.id != id) { var queuedPop = new QueuedScreenPop(); queuedPop.id = screen.id; _queue.Enqueue(queuedPop); #if PRINT_QUEUE DebugPrintQueue(string.Format("[UIManager] Enqueued Screen: {0}", queuedPop)); #endif } else { if (include) { var queuedPop = new QueuedScreenPop(); queuedPop.id = screen.id; queuedPop.callback = callback; _queue.Enqueue(queuedPop); #if PRINT_QUEUE DebugPrintQueue(string.Format("[UIManager] Enqueued Screen: {0}", queuedPop)); #endif } if (callback != null) { callback(screen.id); } found = true; break; } } if (!found) { Debug.LogWarning(string.Format("[UIManager] {0} was not in the stack. All screens have been popped.", id)); } if (CanExecuteNextQueueItem()) { ExecuteNextQueueItem(); } }
private void HandlePopFinished(Screen screen) { screen.onPopFinished -= HandlePopFinished; if (screen.keepCached) { // Store in the cache for later use. screen.gameObject.SetActive(false); // TODO: Need to have a better cache storage mechanism that supports multiple screens of the same prefab? if (!_cache.ContainsKey(screen.PrefabName)) { _cache.Add(screen.PrefabName, screen); #if PRINT_CACHE DebugPrintCache(string.Format("[UIManager] Screen added to Cache: {0}", screen.PrefabName)); #endif } } else { // Destroy screen. Object.Destroy(screen.gameObject); } _state = State.Ready; if (_activePopCallback != null) { _activePopCallback(screen.id); _activePopCallback = null; } if (CanExecuteNextQueueItem()) { ExecuteNextQueueItem(); } }
private void ExecuteNextQueueItem() { // Get next queued item. QueuedScreen queued = _queue.Dequeue(); #if PRINT_QUEUE DebugPrintQueue(string.Format("[UIManager] Dequeued Screen: {0}, Frame: {1}", queued, Time.frameCount)); #endif if (queued is QueuedScreenPush) { // Push screen. QueuedScreenPush queuedPush = (QueuedScreenPush)queued; Screen screenInstance; if (_cache.TryGetValue(queuedPush.prefabName, out screenInstance)) { // Use cached instance of screen. _cache.Remove(queuedPush.prefabName); #if PRINT_CACHE DebugPrintCache(string.Format("[UIManager] Screen retrieved from Cache: {0}", queuedPush.prefabName)); #endif // Move cached to the front of the transfrom heirarchy so that it is sorted properly. screenInstance.transform.SetAsLastSibling(); screenInstance.gameObject.SetActive(true); } else { // Instantiate new instance of screen. string path = System.IO.Path.Combine(resourcePrefabDirectory, queuedPush.prefabName); Screen prefab = Resources.Load <Screen>(path); screenInstance = Object.Instantiate(prefab, rootCanvas.transform); screenInstance.Setup(queuedPush.id, queuedPush.prefabName); } if (this.inputOrderFixEnabled) { this.UpdateSortOrderOverrides(); } // Tell previous top screen that it is losing focus. var topScreen = GetTopScreen(); if (topScreen != null) { #if PRINT_FOCUS Debug.Log(string.Format("[UIManager] Lost Focus: {0}", topScreen.id)); #endif topScreen.OnFocusLost(); } // Insert new screen at the top of the stack. _state = State.Push; _stack.Insert(0, screenInstance); _activePushCallback = queuedPush.callback; #if PRINT_STACK DebugPrintStack(string.Format("[UIManager] Pushing Screen: {0}, Frame: {1}", queued.id, Time.frameCount)); #endif screenInstance.onPushFinished += HandlePushFinished; screenInstance.OnPush(queuedPush.data); if (_queue.Count == 0) { #if PRINT_FOCUS Debug.Log(string.Format("[UIManager] Gained Focus: {0}", screenInstance.id)); #endif // Screen gains focus when it is on top of the screen stack and no other items in the queue. screenInstance.OnFocus(); } } else { // Pop screen. QueuedScreenPop queuedPop = (QueuedScreenPop)queued; Screen screenToPop = GetTopScreen(); if (screenToPop.id != queued.id) { throw new System.Exception(string.Format("The top screen does not match the queued pop. " + "TopScreen: {0}, QueuedPop: {1}", screenToPop.id, queued.id)); } #if PRINT_FOCUS Debug.Log(string.Format("[UIManager] Lost Focus: {0}", screenToPop.id)); #endif screenToPop.OnFocusLost(); _state = State.Pop; _stack.RemoveAt(0); // Tell new top screen that it is gaining focus. var newTopScreen = GetTopScreen(); if (newTopScreen != null) { if (_queue.Count == 0) { #if PRINT_FOCUS Debug.Log(string.Format("[UIManager] Gained Focus: {0}", newTopScreen.id)); #endif // Screen gains focus when it is on top of the screen stack and no other items in the queue. newTopScreen.OnFocus(); } } _activePopCallback = queuedPop.callback; #if PRINT_STACK DebugPrintStack(string.Format("[UIManager] Popping Screen: {0}, Frame: {1}", queued.id, Time.frameCount)); #endif screenToPop.onPopFinished += HandlePopFinished; screenToPop.OnPop(); } }