/// <summary>Visually executes the move.</summary> /// <param name="move">The move to perform</param> /// <param name="pit">The array of visual pits</param> /// <param name="nextMethodToCall">The method to be called once all moves have been performed</param> /// <param name="moveFast">Flag whether or not to move the seeds very fast</param> public async static void ExecuteMove(Move move, Kalaha.View.Model.Pit[] pit, NextMethodToCall nextMethodToCall, bool moveFast) { // Take the seed movement that comes next in the move: SeedMovement seedMovement = move.GetNextSeedMovement(); // Remove this seed movement from the move: move.RemoveSeedmovement(seedMovement); // Get data out of the seed movement: Kalaha.View.Model.Pit fromPit = pit[seedMovement.FromPit]; Kalaha.View.Model.Pit toPit = pit[seedMovement.ToPit]; int numSeeds = seedMovement.NumberOfSeeds; // Prepare the move executor by telling it the total number of seeds: MoveExecutor.PrepareMove(numSeeds); //DEBUG Logging.I.LogMessage("Performing move with " + fromPit + ", " + toPit + ", and " + numSeeds + ".\n"); for (int seedIndex = 0; seedIndex < numSeeds; ++seedIndex) { Seed seedToMove = fromPit.GetSomeSeedAndRemoveIt(); Point newPlace = toPit.FindPlaceForNewSeed(seedToMove.GetWidth(), seedToMove.GetHeight()); Storyboard story = CreateLinearMoveStory(seedToMove.GetImage(), seedToMove.GetTopLeftCorner(), newPlace, moveFast); // Set the zIndex of the seed to a high number it order to put it visually "on top" of the stack: seedToMove.SetZIndex(_seedMoveCounter); _seedMoveCounter++; //DEBUG Logging.I.LogMessage("ExcuteMove (fromPit = " + fromPit + ", toPit = " + toPit + ", numSeeds = " + numSeeds + //DEBUG "), seedIndex = " + seedIndex + " -> Before asyncLock.\n"); // The following line is pretty tricky: We jump out of this method if some other seed is still being visualized. // This causes the complete call stack to return to the original call of the GameBoardPage.ButtonClickedOnPit() method. // Only if one seed is fully animated, the lock is released and the next seed will be animated: // using (var releaser = await _asyncLock.LockAsync()) { //DEBUG Logging.I.LogMessage("ExcuteMove (fromPit = " + fromPit + ", toPit = " + toPit + ", numSeeds = " + numSeeds + //DEBUG "), seedIndex = " + seedIndex + " -> Inside asyncLock.\n"); await story.BeginAsync(); story.Stop(); } // Play the sound when moving the seed: seedToMove.PlayMovingSound(); // Rotate the image to the angle that it had at the time of creation of the seed: seedToMove.RotateImage(); //DEBUG Logging.I.LogMessage("ExcuteMove (fromPit = " + fromPit + ", toPit = " + toPit + ", numSeeds = " + numSeeds + //DEBUG "), seedIndex = " + seedIndex + " -> After asyncLock.\n"); toPit.MoveSeedHere(seedToMove, newPlace); // Check if in all the asynchronous storyboards we are now done with the last storyboard for this move: if (MoveIsCompletelyVisualized()) { //DEBUG Logging.I.LogMessage("This was the last seed to be completed.\n"); // This is the last seed that has been visualized. All aynchronous calls have been executed. // If there is some seed movement left in the original move, we perform this now by calling the visualization method // recursively. If there is nothing left, and some original caller of this method told us what to do once we are done, we do it now: if (move.GetNumberOfSeedMovements() > 0) { //DEBUG Logging.I.LogMessage("Recursively calling the visualizer.\n"); ExecuteMove(move, pit, nextMethodToCall, moveFast); } else { // We are completely done with the move. if (nextMethodToCall != null) { //DEBUG Logging.I.LogMessage("Calling the next method to call.\n"); nextMethodToCall(); } } } } }
/// <summary>Shows the given move in detail.</summary> /// <param name="move">The move to be shown</param> /// <param name="nextMethodToCall">The method that shall be called after the visualization has finished</param> /// <param name="moveFast">Flag whether or not to move the seeds very fast</param> public void VisualizeMove(Move move, NextMethodToCall nextMethodToCall, bool moveFast = false) { MoveExecutor.ExecuteMove(move, _pit, nextMethodToCall, moveFast); }