player.ts 3.27 KB
import { EventEmitter } from 'events';
import {ProgramRepository} from './program-repository';
import {ProgramManager} from './program-manager';
import {Util} from './util';

const STATE_START = "start";
const STATE_STOP  = "stop";

export class Player extends EventEmitter {

    constructor() {
        super();
    }

    protected _programRepository:ProgramRepository;
    protected _programManager:ProgramManager;
    protected _minutesReplication:number = 3;
    protected _replicationRetry:number = 10000;

    protected _currentProgramItemId:string = '';
    protected _currentReplicationCounter:number = 0;
    protected _state = STATE_STOP;

    set state(st:string) {
        this._state = st;
    }

    set programManager(pm:ProgramManager) {
        this._programManager = pm;
    }

    get programManager() : ProgramManager {
        return this._programManager;
    }

    set programRepository(pr:ProgramRepository) {
        this._programRepository = pr;
    }

    get programRepository() : ProgramRepository {
        return this._programRepository;
    }

    set minutesReplication(mr:number) {
        this._minutesReplication = mr;
    }

    get minutesReplication() : number {
        return this._minutesReplication;
    }

    set replicationRetry(rr:number) {
        this._replicationRetry = rr;
    }

    get replicationRetry() : number {
        return this._replicationRetry;
    }

    triggerReplication() : Promise<void> {
        console.info("digsig-player-service: trigger replication");

        return this.programRepository.replicate()
            .then(changes => { 
                this._currentReplicationCounter = 0;
                this.trigger(() => { this.triggerProgramItemId(changes); });
            })
            .catch(error => {                
                this.trigger(() => { this.triggerReplication(); }, this.replicationRetry);
                this.emit('error', error);
            });
    }

    triggerProgramItemId(changes:boolean = false) {
        console.info("digsig-player-service: trigger program item id");

        this.programManager.getCurrentProgramItemId()
            .then(programItemId => {
                this._currentReplicationCounter++;

                // if there is a new program item id trigger play
                // else (1) calculate next potential program change point
                // or (2) trigger replication

                if (programItemId && (programItemId != this._currentProgramItemId || changes)) {
                    this._currentProgramItemId = programItemId;
                    this.emit('play', programItemId);
                }
                
                if (this._currentReplicationCounter >= this._minutesReplication) {
                    this.triggerReplication();
                } else {
                    this.trigger(() => { this.triggerProgramItemId(); }, Util.calculateNextMinute());
                }
            });
    }

    trigger(func:Function, milliseconds:number = 0) {
        if (this._state === STATE_START) { 
            setTimeout(() => { func(); }, milliseconds);
        }        
    }

    start() {
        if (this._state === STATE_STOP) {
            this.triggerReplication();
            this._state = STATE_START;
        }
    }

    stop() {
        this._state = STATE_STOP;
    }

}