avocado-old/packages/behavior/traits/behaved.trait.js
2020-06-22 04:53:06 -05:00

116 lines
2.2 KiB
JavaScript

import {compose, flatten} from '@avocado/core';
import {StateProperty, Trait} from '@avocado/entity';
import {Context} from '../context';
import {Routines} from '../item/routines';
const decorate = compose(
StateProperty('currentRoutine', {
track: true,
}),
StateProperty('isBehaving'),
);
export default class Behaved extends decorate(Trait) {
static behaviorContextTypes() {
return {
context: {
type: 'context',
label: 'Context',
},
};
}
static defaultParams() {
return {
routines: {},
};
}
static defaultState() {
return {
currentRoutine: 'initial',
isBehaving: true,
}
}
static describeParams() {
return {
routines: {
type: 'routines',
label: 'Routines',
},
}
}
static describeState() {
return {
isBehaving: {
type: 'bool',
label: 'Is behaving',
},
currentRoutine: {
type: 'string',
label: 'Current routine',
},
}
}
static type() {
return 'behaved';
}
constructor(entity, params, state) {
super(entity, params, state);
this._context = new Context({
entity: [this.entity, 'entity'],
});
this._currentRoutine = undefined;
this._routines = (new Routines()).fromJSON(this.params.routines);
this.updateCurrentRoutine(this.state.currentRoutine);
}
destroy() {
this._context.destroy();
this._currentRoutine = undefined;
this._routines = undefined;
}
get context() {
return this._context;
}
updateCurrentRoutine(currentRoutine) {
this._currentRoutine = this._routines.routine(currentRoutine);
}
listeners() {
return {
currentRoutineChanged: (old, currentRoutine) => {
this.updateCurrentRoutine(currentRoutine);
},
isDyingChanged: (_, isDying) => {
this.entity.isBehaving = !isDying;
},
traitAdded: (type) => {
flatten(this.entity.invokeHookFlat('contextTypeHints'))
.forEach(([key, type]) => this._context.add(key, undefined, type));
},
};
}
tick(elapsed) {
if (AVOCADO_SERVER) {
if (this._currentRoutine && this.entity.isBehaving) {
this._currentRoutine.tick(this._context, elapsed);
}
}
}
}