import { List } from '@pilotlab/lux-collections'; import { Initializable } from '@pilotlab/lux-initializable'; import { IPromise, Result } from '@pilotlab/lux-result'; import { Signal, SignalMonitor } from '@pilotlab/lux-signals'; import IAnimation from './interfaces/iAnimation'; import IAnimationBatch from './interfaces/iAnimationBatch'; import IAnimationEventArgs from './interfaces/iAnimationEventArgs'; import AnimationManager from './animationManager'; import Animation from './animation'; export class AnimationBatch extends Initializable implements IAnimationBatch { constructor( animationManager:AnimationManager = Animation.animate, animations:IAnimation[] = [], isInitialize:boolean = true ) { super(); this.p_animationManager = animationManager; this.p_animations = List.fromArray(animations); this.p_result = new Result(); this.ticked = new Signal(false); this.completed = new Signal(true); if (isInitialize && this.p_animations.size > 0) this.initialize(); } initialize():IPromise { if (this.p_animations.size > 0) { this._signalMonitorTicked = new SignalMonitor(false); this._signalMonitorCompleted = new SignalMonitor(); for (let i:number = 0; i < this.p_animations.size; i++) { const animation:IAnimation = this.p_animations.item(i); this._signalMonitorCompleted.add(animation.completed); if (!animation.isCompleted) { this._signalMonitorTicked.add(animation.ticked); } animation.completed.listenOnce((args:IAnimationEventArgs) => { this._signalMonitorTicked.signals.delete(args.animation.ticked.key); this._signalMonitorTicked.signalsPending.delete(args.animation.ticked); if (!this.p_isInterrupted && animation.isInterrupted) this.p_isInterrupted = true; }, this); this.animationManager.run(animation); } this._signalMonitorTicked.allSignalsDispatched.listen((args:IAnimationEventArgs[]) => { this.ticked.dispatch(args); }, this); this._signalMonitorCompleted.allSignalsDispatched.listenOnce((args:IAnimationEventArgs[]) => { this.p_isCompleted = true; this.completed.dispatch(args); this.p_result.resolve(this); }, this); this._signalMonitorTicked.start(); this._signalMonitorCompleted.start(); } else { this.p_result.resolve(this); } return this.p_result; } private _signalMonitorTicked:SignalMonitor; private _signalMonitorCompleted:SignalMonitor; clear():void { this.interrupt(); this.p_isInterrupted = false; this.p_result = new Result(); this.p_animations.clear(); this._signalMonitorTicked.clear(); this._signalMonitorCompleted.clear(); } get animationManager():AnimationManager { return this.p_animationManager; } protected p_animationManager:AnimationManager; get isCompleted():boolean { return this.p_isCompleted; } protected p_isCompleted:boolean = false; get isInterrupted():boolean { return this.p_isInterrupted; } protected p_isInterrupted:boolean = false; get animations():List { return this.p_animations; } protected p_animations:List; get result():IPromise { return this.p_result; } protected p_result:IPromise; /*====================================================================* START: Signals *====================================================================*/ ticked:Signal; completed:Signal; /*====================================================================* START: Methods *====================================================================*/ then(onDone:(value:TAnimationBatch) => any, onError?:(error:Error) => void):IPromise { return this.p_result.then(onDone, onError); } interrupt():void { if (this.p_isInterrupted) return; for (let i:number = 0; i < this.p_animations.size; i++) { this.p_animations.item(i).interrupt(); } this.p_isInterrupted = true; } } // End class export default AnimationBatch;