/// <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(); }