2019-04-28 23:45:03 -05:00
|
|
|
import {compose, Property} from '@avocado/core';
|
2019-04-20 16:03:11 -05:00
|
|
|
import {Trait} from '@avocado/entity';
|
2019-04-25 02:28:54 -05:00
|
|
|
import {Ticker} from '@avocado/timing';
|
2019-04-20 16:03:11 -05:00
|
|
|
|
|
|
|
const decorate = compose(
|
2019-04-28 23:45:03 -05:00
|
|
|
);
|
2019-04-20 16:03:11 -05:00
|
|
|
|
|
|
|
export class Emitter extends decorate(Trait) {
|
|
|
|
|
2019-05-06 04:03:43 -05:00
|
|
|
constructor(entity, params, state) {
|
|
|
|
super(entity, params, state);
|
2019-04-20 16:03:11 -05:00
|
|
|
this.emitters = {};
|
2019-05-03 01:22:15 -05:00
|
|
|
if (AVOCADO_CLIENT) {
|
2019-05-09 19:49:44 -05:00
|
|
|
this.ticker = new Ticker(1 / 60);
|
2019-05-03 01:22:15 -05:00
|
|
|
this.ticker.on('tick', this.onTick, this);
|
|
|
|
}
|
2019-04-20 16:03:11 -05:00
|
|
|
}
|
|
|
|
|
2019-05-05 04:26:35 -05:00
|
|
|
static type() {
|
|
|
|
return 'emitter';
|
|
|
|
}
|
|
|
|
|
2019-04-25 19:19:38 -05:00
|
|
|
static addEmitter(emitter) {
|
|
|
|
if (!this._emitters) {
|
|
|
|
this._emitters = [];
|
|
|
|
}
|
|
|
|
this._emitters.push(emitter);
|
|
|
|
}
|
|
|
|
|
|
|
|
static particleCount() {
|
|
|
|
let particleCount = 0;
|
|
|
|
if (!this._emitters) {
|
|
|
|
return particleCount;
|
|
|
|
}
|
|
|
|
for (let i = 0; i < this._emitters.length; i++) {
|
|
|
|
const emitter = this._emitters[i];
|
|
|
|
particleCount += emitter.particleCount;
|
|
|
|
}
|
|
|
|
return particleCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
static removeEmitter(emitter) {
|
|
|
|
const index = this._emitters.indexOf(emitter);
|
|
|
|
if (-1 === index) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this._emitters.splice(index, 1);
|
|
|
|
}
|
|
|
|
|
2019-05-03 01:22:15 -05:00
|
|
|
onTick(elapsed) {
|
|
|
|
for (const key in this.emitters) {
|
|
|
|
const emitter = this.emitters[key];
|
|
|
|
emitter.tick(elapsed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-25 19:19:38 -05:00
|
|
|
updateFrequency() {
|
|
|
|
const particleCount = this.constructor.particleCount();
|
|
|
|
const updatesPerSecond = Math.max(15, (60 - (particleCount / 10)));
|
|
|
|
this.ticker.frequency = 1 / updatesPerSecond;
|
|
|
|
}
|
|
|
|
|
2019-04-20 16:03:11 -05:00
|
|
|
hooks() {
|
2019-05-02 21:07:43 -05:00
|
|
|
const hooks = {};
|
|
|
|
if (AVOCADO_CLIENT) {
|
|
|
|
hooks.afterDestructionTickers = () => {
|
2019-04-20 16:03:11 -05:00
|
|
|
return (elapsed) => {
|
|
|
|
for (const key in this.emitters) {
|
|
|
|
const emitter = this.emitters[key];
|
2019-04-25 02:28:54 -05:00
|
|
|
this.ticker.tick(elapsed);
|
2019-04-20 16:03:11 -05:00
|
|
|
if (!emitter.hasParticles()) {
|
2019-05-03 01:22:15 -05:00
|
|
|
this.ticker.off('tick', this.onTick);
|
2019-04-25 19:19:38 -05:00
|
|
|
emitter.destroy();
|
2019-04-30 17:11:41 -05:00
|
|
|
this.constructor.removeEmitter(emitter);
|
2019-04-20 16:03:11 -05:00
|
|
|
delete this.emitters[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0 === Object.keys(this.emitters).length;
|
|
|
|
};
|
2019-05-02 21:07:43 -05:00
|
|
|
};
|
2019-04-20 16:03:11 -05:00
|
|
|
}
|
2019-05-02 21:07:43 -05:00
|
|
|
return hooks;
|
2019-04-20 16:03:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
methods() {
|
|
|
|
return {
|
|
|
|
|
|
|
|
addEmitter: (key, emitter) => {
|
2019-06-05 21:19:16 -05:00
|
|
|
if (AVOCADO_CLIENT) {
|
|
|
|
this.emitters[key] = emitter;
|
|
|
|
this.constructor.addEmitter(emitter);
|
2019-05-02 21:07:43 -05:00
|
|
|
}
|
2019-04-20 16:03:11 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
addEmitterRenderer: (key, renderer) => {
|
2019-06-05 21:19:16 -05:00
|
|
|
if (AVOCADO_CLIENT) {
|
|
|
|
if (!this.emitters[key]) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.emitters[key].addRenderer(renderer);
|
2019-04-20 16:03:11 -05:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
emitParticle: (key, ...args) => {
|
|
|
|
if (!this.emitters[key]) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.emitters[key].emit(...args);
|
|
|
|
},
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-02 22:17:41 -05:00
|
|
|
tick(elapsed) {
|
2019-05-03 01:22:15 -05:00
|
|
|
if (AVOCADO_CLIENT) {
|
|
|
|
this.ticker.tick(elapsed);
|
|
|
|
}
|
2019-04-20 16:03:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|