avocado-old/packages/entity/trait.js
2019-03-17 23:45:48 -05:00

99 lines
1.8 KiB
JavaScript

import * as I from 'immutable';
import {Resource} from '@avocado/resource';
export class Trait {
constructor(entity) {
this.entity = entity;
this.params = I.fromJS(this.constructor.defaultParams());
this.state = I.fromJS(this.constructor.defaultState());
// Attach listeners.
const listeners = this.listeners();
const traitType = this.constructor.type();
for (const type in this.listeners()) {
entity.on(`${type}.trait-${traitType}`, listeners[type]);
}
}
acceptStateChange(change) {
this.state = this.state.merge(change);
}
actions() {
return {};
}
destroy() {
this.entity.off(`.trait-${this.constructor.type()}`);
}
fromJSON({params = {}, state = {}}) {
this.params = I.fromJS(this.constructor.defaultParams()).merge(params);
this.state = I.fromJS(this.constructor.defaultState()).merge(state);
return this;
}
hooks() {
return {};
}
hydrate() {
return Promise.resolve();
}
label() {
return this.constructor.name;
}
listeners() {
return {};
}
toJSON() {
return {
params: this.params.toJS(),
state: this.state.toJS(),
};
}
static contextType() {
return {};
}
static defaultParams() {
return {};
}
static defaultState() {
return {};
}
static dependencies() {
return [];
}
static type() {
return this.name.toLowerCase();
}
}
export function simpleState(name) {
return (Superclass) => {
class SimpleState extends Superclass {}
// Add simple state handler.
Object.defineProperty(SimpleState.prototype, name, {
get() {
return this.state.get(name);
},
set(value) {
this.state = this.state.set(name, value);
},
enumerable: true,
configurable: true,
});
return SimpleState;
}
}