/// <summary> /// Internal implementation of executing a queue. /// </summary> private IEnumerator ExecuteQueueAsync(int queueId, List <GemAction> queue) { // Current barrier state GemActionBarrier barrier = new GemActionBarrier(); // Execute the queue foreach (var action in queue) { if (action.delay > 0f) { yield return(new WaitForSeconds(action.delay)); } switch (action.type) { case GemActionType.None: break; case GemActionType.Barrier: yield return(StartCoroutine(barrier.WaitAsync())); barrier.Reset(); break; default: StartCoroutine(ExecuteActionAsync(action, barrier)); break; } } // Wait for all the actions to finish yield return(StartCoroutine(barrier.WaitAsync())); // Free unused objects gemMap.ClearUnusedGems(); // Remove the queue from playing dict playingQueueDict.Remove(queueId); }
/// <summary> /// Execute gem action. /// </summary> private IEnumerator ExecuteActionAsync(GemAction action, GemActionBarrier barrier) { barrier.AddTask(); switch (action.type) { case GemActionType.Clear: { var gem = gemMap[action.coord]; gem.Disappear(); GameManager.Instance.Level.GainScore(action.score); yield return(new WaitWhile(() => gem.IsAnimating)); gemMap.FreeGem(gem); // Remove the gem from gem map break; } case GemActionType.Swap: { var gem1 = gemMap[action.coord]; var gem2 = gemMap[action.destCoord]; // Remove the gem from gem map first to avoid them // being overlapped by each other gemMap.FreeGem(gem1); gemMap.FreeGem(gem2); gemMap.SetGemCoord(gem1, action.destCoord, true); gemMap.SetGemCoord(gem2, action.coord, true); yield return(new WaitWhile(() => gem1.IsAnimating || gem2.IsAnimating)); break; } case GemActionType.Move: { var gem = gemMap[action.coord]; gemMap.SetGemCoord(gem, action.destCoord, true); yield return(new WaitWhile(() => gem.IsAnimating)); break; } case GemActionType.Create: { var gem = GemFactory.Instance.CreateGem(action.gemType); gemMap.AddGem(gem, action.coord, true); yield return(new WaitWhile(() => gem.IsAnimating)); break; } case GemActionType.Transform: { var newGem = GemFactory.Instance.CreateGem(action.gemType); // Old gem will be removed from the map automatically gemMap.SetGemCoord(newGem, action.coord); break; } } // Wait for one frame yield return(null); barrier.RemoveTask(); }