annotate src/app/services/render-loop/render-loop.service.ts @ 400:e06b62d949de

Return a callback when adding an animation task, allowing it to be removed.
author Lucas Thompson <dev@lucas.im>
date Fri, 02 Jun 2017 19:08:42 +0100
parents 308ea1c2612e
children
rev   line source
dev@397 1 /**
dev@397 2 * Created by lucast on 02/06/2017.
dev@397 3 */
dev@397 4 import {Injectable, NgZone} from '@angular/core';
dev@397 5 import {AudioPlayerService} from '../audio-player/audio-player.service';
dev@397 6 import {Subscription} from 'rxjs/Subscription';
dev@397 7 import {OnSeekHandler} from '../../playhead/PlayHeadHelpers';
dev@397 8
dev@400 9 export type TaskRemover = () => void;
dev@400 10 type TaskId = number;
dev@400 11
dev@397 12 @Injectable()
dev@397 13 export class RenderLoopService {
dev@397 14 private playingStateSubscription: Subscription;
dev@397 15 private seekedSubscription: Subscription;
dev@400 16 private tasks: Map<TaskId, OnSeekHandler>;
dev@400 17 private countingId: TaskId;
dev@397 18
dev@397 19 constructor(private player: AudioPlayerService,
dev@397 20 private zone: NgZone) {
dev@400 21 this.countingId = 0;
dev@400 22 this.tasks = new Map();
dev@397 23 this.seekedSubscription = this.player.seeked$.subscribe(() => {
dev@397 24 if (!this.player.isPlaying()) {
dev@397 25 this.zone.runOutsideAngular(() => {
dev@397 26 this.runTasks();
dev@397 27 });
dev@397 28 }
dev@397 29 });
dev@397 30 this.playingStateSubscription = this.player.playingStateChange$.subscribe(
dev@397 31 isPlaying => {
dev@397 32 if (isPlaying) {
dev@397 33 this.animate();
dev@397 34 }
dev@397 35 });
dev@397 36 }
dev@397 37
dev@400 38 addPlayingTask(task: OnSeekHandler): TaskRemover {
dev@400 39 const id = this.countingId++;
dev@400 40 this.tasks.set(id, task);
dev@400 41 return () => {
dev@400 42 this.tasks.delete(id);
dev@400 43 };
dev@397 44 }
dev@397 45
dev@397 46 private animate(): void {
dev@397 47 this.zone.runOutsideAngular(() => {
dev@397 48 const animateNextFrame = () => {
dev@397 49 if (this.player.isPlaying()) {
dev@397 50 this.runTasks();
dev@397 51 requestAnimationFrame(animateNextFrame);
dev@397 52 }
dev@397 53 };
dev@397 54 requestAnimationFrame(animateNextFrame);
dev@397 55 });
dev@397 56 }
dev@397 57
dev@397 58 private runTasks(): void {
dev@397 59 const currentTime = this.player.getCurrentTime();
dev@400 60 for (const task of this.tasks.values()) {
dev@397 61 task(currentTime);
dev@397 62 }
dev@397 63 }
dev@397 64 }