avocado-old/packages/entity/trait/index.js

129 lines
2.6 KiB
JavaScript
Raw Normal View History

2019-03-17 23:45:48 -05:00
import * as I from 'immutable';
2019-05-04 14:06:47 -05:00
import merge from 'lodash.merge';
2019-03-17 23:45:48 -05:00
2019-04-28 23:45:03 -05:00
import {compose, Property} from '@avocado/core';
2019-03-21 23:13:46 -05:00
import {Vector} from '@avocado/math';
2019-03-28 12:56:42 -05:00
import {Resource} from '@avocado/resource';
2019-04-07 11:43:50 -05:00
import {Synchronized} from '@avocado/state';
2019-03-17 23:45:48 -05:00
2019-04-16 17:52:56 -05:00
const decorate = compose(
Synchronized,
);
export class Trait extends decorate(class {}) {
2019-03-17 23:45:48 -05:00
constructor(entity, params, state) {
2019-04-07 11:43:50 -05:00
super();
2019-03-17 23:45:48 -05:00
this.entity = entity;
const ctor = this.constructor;
2019-04-30 17:11:41 -05:00
this._memoizedListeners = undefined;
2019-05-04 14:06:47 -05:00
this.params = Object.assign({}, ctor.defaultParams(), params);
this.state = I.fromJS(ctor.defaultState()).merge(I.fromJS(state));
this.initializeSynchronizedChildren();
2019-05-05 20:04:59 -05:00
if (this.tick) {
this.tick = this.tick.bind(this);
}
if (this.renderTick) {
this.renderTick = this.renderTick.bind(this);
}
2019-03-17 23:45:48 -05:00
}
destroy() {}
2019-03-17 23:45:48 -05:00
hooks() {
return {};
}
hydrate() {
return Promise.resolve();
}
label() {
return this.constructor.name;
}
listeners() {
return {};
}
2019-04-30 17:11:41 -05:00
memoizedListeners() {
if (!this._memoizedListeners) {
this._memoizedListeners = this.listeners();
}
return this._memoizedListeners;
}
2019-03-20 18:32:54 -05:00
methods() {
return {};
}
2019-04-07 11:43:50 -05:00
patchStateStep(key, step) {
if ('state' !== key) {
return;
2019-04-05 15:16:55 -05:00
}
2019-04-07 11:43:50 -05:00
const stateKey = step.path.substr(1);
const value = this.transformPatchValue(stateKey, step.value);
2019-04-07 11:43:50 -05:00
if (stateKey in this.entity) {
this.entity[stateKey] = value;
2019-04-07 11:43:50 -05:00
}
else {
this.state = this.state.set(stateKey, value);
2019-04-06 23:19:32 -05:00
}
}
2019-03-17 23:45:48 -05:00
toJSON() {
return {
2019-05-04 14:06:47 -05:00
params: this.params,
2019-03-17 23:45:48 -05:00
state: this.state.toJS(),
};
}
transformPatchValue(key, value) {
return value;
}
2019-03-17 23:45:48 -05:00
static contextType() {
return {};
}
static defaultParams() {
return {};
}
static defaultState() {
return {};
}
static dependencies() {
return [];
}
}
2019-03-23 23:24:18 -05:00
export function StateProperty(key, meta = {}) {
2019-04-12 17:21:43 -05:00
let transformedProperty;
if (meta.transformProperty) {
transformedProperty = meta.transformProperty(key);
}
else {
transformedProperty = `$$avocado_state_property_${key}`;
}
2019-03-17 23:45:48 -05:00
return (Superclass) => {
meta.emit = meta.emit || function(...args) {
this.entity.emit(...args);
};
2019-04-12 17:21:43 -05:00
meta.initialize = meta.initialize || function() {
this[transformedProperty] = this.state.get(key);
}
meta.get = meta.get || new Function(`
return this.${transformedProperty};
`);
meta.set = meta.set || new Function('value', `
2019-05-08 17:51:29 -05:00
this.entity.setTraitDirty(this.constructor.type());
2019-04-12 17:21:43 -05:00
this.${transformedProperty} = value;
this.state = this.state.set('${key}', value);
`);
return Property(key, meta)(Superclass);
2019-03-17 23:45:48 -05:00
}
}