Search code examples
iosswiftsprite-kitgrand-central-dispatchskaction

Performing an unknown amount of animations sequentially


I am creating a game where the user can move a SKShapeNode around. Now, I am trying to write a utility function that will perform back-to-back animations sequentially.

Description of what I'm Trying

I first dispatch_async to a serial thread. This thread then calls a dispatch_sync on the main thread to perform an animation. Now, to make the animations run sequentially, I would like to block the GlobalSerialAnimationQueue until the animation is completed on the main thread. By doing this, I (theoretically) would be able to run animations sequentially. My code is pasted below for more description

func moveToCurrentPosition() {
    let action = SKAction.moveTo(self.getPositionForCurrRowCol(), duration: 1.0)
    dispatch_async(GlobalSerialAnimateQueue) {
        //this just creates an action to move to a point
        dispatch_sync(GlobalMainQueue, { 
            self.userNode!.runAction(action) {
                //inside the completion block now want to continue
                //WOULD WANT TO TRIGGER THREAD TO CONTINUE HERE
            }
        })
        //WOULD LIKE TO PAUSE HERE, THIS BLOCK FINISHING ONLY WHEN THE ANIMATION IS COMPLETE
    }
}

So, my question is, how would I write a function that can take in requests for animations, and then perform them sequentially? What grand-central-dispatch tools should I use, or should I be trying a completely different approach?


Solution

  • I figured out how to do this using a grand-central-dispatch semaphore. My updated code is here.

    func moveToCurrentPosition() {
    
        let action = SKAction.moveTo(self.getPositionForCurrRowCol(), duration: Animation.USER_MOVE_DURATION)
        dispatch_async(GlobalSerialAnimateQueue) {
            let semaphore = dispatch_semaphore_create(0)
            dispatch_sync(GlobalMainQueue, {
                self.userNode!.runAction(action) {
                    //signal done
                    dispatch_semaphore_signal(semaphore)
                }
            })
            //wait here...
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
        }
    }