import Foundation import SpineCppLite public typealias AnimationStateListener = (_ type: EventType, _ entry: TrackEntry, _ event: Event?) -> Void /// Wrapper class around ``AnimationState``. Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies /// multiple animations on top of each other (layering). /// /// See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. @objc(SpineAnimationStateWrapper) @objcMembers public final class AnimationStateWrapper: NSObject { public let animationState: AnimationState public let aninationStateEvents: AnimationStateEvents private var trackEntryListeners = [spine_track_entry: AnimationStateListener]() private var stateListener: AnimationStateListener? public init(animationState: AnimationState, aninationStateEvents: AnimationStateEvents) { self.animationState = animationState self.aninationStateEvents = aninationStateEvents super.init() } /// The listener for events generated by the provided ``TrackEntry``, or nil. /// /// A track entry returned from ``AnimationState/setAnimation(trackIndex:animation:loop:)`` is already the current animation /// for the track, so the track entry listener will not be called for ``EventType`` `SPINE_EVENT_TYPE_START`. public func setTrackEntryListener(entry: TrackEntry, listener: AnimationStateListener?) { if let listener { trackEntryListeners[entry.wrappee] = listener } else { trackEntryListeners.removeValue(forKey: entry.wrappee) } } /// Increments each track entry ``TrackEntry/trackTime``, setting queued animations as current if needed. public func update(delta: Float) { animationState.update(delta: delta) let numEvents = spine_animation_state_events_get_num_events(aninationStateEvents.wrappee) for i in 0..