2019-05-17 04:33:16 -05:00
|
|
|
import {compose, merge, mergeDiff, 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
|
|
|
|
2019-03-19 10:02:18 -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;
|
2019-04-05 11:54:25 -05:00
|
|
|
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);
|
2019-05-13 21:07:51 -05:00
|
|
|
this.state = Object.assign({}, ctor.defaultState(), state);
|
|
|
|
this.previousState = JSON.parse(JSON.stringify(this.state));
|
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
|
|
|
}
|
|
|
|
|
2019-05-14 05:45:22 -05:00
|
|
|
createTraitPacketUpdates(Packet) {
|
|
|
|
const packets = [];
|
|
|
|
if (this.isDirty) {
|
|
|
|
packets.push(new Packet(this.state, this.entity));
|
|
|
|
this.makeClean();
|
|
|
|
}
|
|
|
|
return packets;
|
|
|
|
}
|
|
|
|
|
2019-03-18 20:00:02 -05:00
|
|
|
destroy() {}
|
2019-03-17 23:45:48 -05:00
|
|
|
|
|
|
|
hooks() {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
hydrate() {
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
2019-05-14 05:45:22 -05:00
|
|
|
get isDirty() {
|
|
|
|
for (const key in this.state) {
|
|
|
|
if (this.state[key] !== this.previousState[key]) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-03-17 23:45:48 -05:00
|
|
|
label() {
|
|
|
|
return this.constructor.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
listeners() {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2019-05-14 05:45:22 -05:00
|
|
|
makeClean() {
|
|
|
|
for (const key in this.state) {
|
|
|
|
this.previousState[key] = this.state[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-03-17 23:45:48 -05:00
|
|
|
toJSON() {
|
|
|
|
return {
|
2019-05-04 14:06:47 -05:00
|
|
|
params: this.params,
|
2019-05-13 21:07:51 -05:00
|
|
|
state: this.state,
|
2019-03-17 23:45:48 -05:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-04-10 21:01:58 -05:00
|
|
|
transformPatchValue(key, value) {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2019-03-17 23:45:48 -05:00
|
|
|
static contextType() {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2019-05-17 04:33:30 -05:00
|
|
|
static defaultJSON() {
|
|
|
|
return {
|
|
|
|
params: this.defaultParams(),
|
|
|
|
state: this.defaultState(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-03-17 23:45:48 -05:00
|
|
|
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) => {
|
2019-03-18 20:04:12 -05:00
|
|
|
meta.emit = meta.emit || function(...args) {
|
|
|
|
this.entity.emit(...args);
|
|
|
|
};
|
2019-04-12 17:21:43 -05:00
|
|
|
meta.initialize = meta.initialize || function() {
|
2019-05-13 21:07:51 -05:00
|
|
|
this[transformedProperty] = this.state[key];
|
2019-04-12 17:21:43 -05:00
|
|
|
}
|
|
|
|
meta.get = meta.get || new Function(`
|
|
|
|
return this.${transformedProperty};
|
|
|
|
`);
|
|
|
|
meta.set = meta.set || new Function('value', `
|
|
|
|
this.${transformedProperty} = value;
|
2019-05-13 21:07:51 -05:00
|
|
|
this.state['${key}'] = value;
|
2019-04-12 17:21:43 -05:00
|
|
|
`);
|
2019-03-18 20:04:12 -05:00
|
|
|
return Property(key, meta)(Superclass);
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
}
|