import {compose} from '@avocado/core'; import {Synchronized} from '@avocado/state'; import {Ticker} from '@avocado/timing'; import {WorldTimePacket} from './world-time.packet'; const MAGIC_TO_FIT_HOUR_INTO_USHORT = 2730; const decorate = compose( Synchronized, ); export class WorldTime extends decorate(class {}) { constructor() { super(); this._hour = 0; this._isUpdateReady = true; this._lastHour = 0; this.ticker = new Ticker(0.25); this.ticker.on('tick', () => { this._isUpdateReady = true; }); } acceptPacket(packet) { if (packet instanceof WorldTimePacket) { this._hour = packet.data / MAGIC_TO_FIT_HOUR_INTO_USHORT; } } static format(time) { const rawHour = (time + 12) % 12; const hour = Math.floor(0 === Math.floor(rawHour) ? 12 : rawHour); const minutes = String(Math.floor((rawHour - Math.floor(rawHour)) * 60)).padStart(2, '0'); if (time >= 12) { return `${hour}:${minutes} pm`; } else { return `${hour}:${minutes} am`; } } get hour() { return this._hour; } set hour(hour) { this._hour = hour; } packetsForUpdate(force) { const updates = []; if (force || this._isUpdateReady) { updates.push(new WorldTimePacket( (this._hour * MAGIC_TO_FIT_HOUR_INTO_USHORT) >> 0 )); } if (!force) { this._isUpdateReady = false; } return updates; } secondsPerHour() { return 60; } tick(elapsed) { this._hour += (elapsed / this.secondsPerHour()); this._hour = this._hour % 24; this.ticker.tick(elapsed); } }