2019-03-17 23:45:48 -05:00
|
|
|
import * as I from 'immutable';
|
|
|
|
|
|
|
|
import {compose} from '@avocado/core';
|
|
|
|
import {EventEmitter} from '@avocado/mixins';
|
|
|
|
import {Resource} from '@avocado/resource';
|
|
|
|
|
|
|
|
import {Traits} from './traits';
|
|
|
|
|
2019-04-12 14:11:26 -05:00
|
|
|
// Cache builtins to avoid HasProperty
|
|
|
|
const entityBuiltins = [
|
|
|
|
'$$events',
|
|
|
|
'$$namespaces',
|
|
|
|
'_instanceUuid',
|
|
|
|
'_traits',
|
|
|
|
'_uri',
|
|
|
|
'_uuid',
|
|
|
|
'addListener',
|
|
|
|
'addTrait',
|
|
|
|
'addTraits',
|
|
|
|
'allTraitInstances',
|
|
|
|
'allTraitTypes',
|
|
|
|
'emit',
|
|
|
|
'fromJSON',
|
|
|
|
'is',
|
|
|
|
'hydrate',
|
|
|
|
'instanceUuid',
|
|
|
|
'invokeHook',
|
|
|
|
'invokeHookFlat',
|
|
|
|
'lookupEmitListeners',
|
|
|
|
'off',
|
|
|
|
'offSingleEvent',
|
|
|
|
'on',
|
|
|
|
'_on',
|
|
|
|
'once',
|
|
|
|
'onSingleEvent',
|
|
|
|
'patchState',
|
|
|
|
'regenerateUuid',
|
|
|
|
'removeAllTraits',
|
|
|
|
'removeEventListenersFor',
|
|
|
|
'removeListener',
|
|
|
|
'removeTrait',
|
|
|
|
'removeTraits',
|
|
|
|
'state',
|
|
|
|
'tick',
|
|
|
|
'toJSON',
|
|
|
|
'uuid',
|
|
|
|
'uri',
|
|
|
|
];
|
|
|
|
const entityBuiltinsMap = new Map();
|
|
|
|
for (const entityBuiltin of entityBuiltins) {
|
|
|
|
entityBuiltinsMap.set(entityBuiltin, true);
|
|
|
|
}
|
2019-03-17 23:45:48 -05:00
|
|
|
class TraitProxy {
|
|
|
|
|
|
|
|
has(entity, property, receiver) {
|
2019-04-12 14:11:26 -05:00
|
|
|
const isBuiltin = entityBuiltinsMap.get(property);
|
|
|
|
if (isBuiltin) {
|
|
|
|
return true;
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
else {
|
2019-04-07 12:00:11 -05:00
|
|
|
return entity._traits.hasProperty(property);
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
get(entity, property, receiver) {
|
2019-04-12 14:11:26 -05:00
|
|
|
const isBuiltin = entityBuiltinsMap.get(property);
|
|
|
|
if (isBuiltin) {
|
|
|
|
return entity[property];
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
else {
|
2019-04-07 12:00:11 -05:00
|
|
|
return entity._traits.getProperty(property);
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
set(entity, property, value, receiver) {
|
2019-04-12 14:11:26 -05:00
|
|
|
const isBuiltin = entityBuiltinsMap.get(property);
|
|
|
|
if (isBuiltin) {
|
|
|
|
entity[property] = value;
|
2019-04-07 12:18:20 -05:00
|
|
|
return true;
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
2019-04-12 14:11:26 -05:00
|
|
|
return entity._traits.setProperty(property, value, receiver);
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
2019-04-07 11:51:28 -05:00
|
|
|
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const decorate = compose(
|
|
|
|
EventEmitter,
|
|
|
|
);
|
|
|
|
|
|
|
|
class Entity extends decorate(Resource) {
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
super();
|
2019-04-07 12:00:11 -05:00
|
|
|
this._traits = new Traits(createProxy(this));
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
addTrait(type, trait) {
|
2019-04-07 12:00:11 -05:00
|
|
|
this._traits.addTrait(type, trait);
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
addTraits(traits) {
|
|
|
|
for (const type in traits) {
|
2019-04-07 12:00:11 -05:00
|
|
|
this._traits.addTrait(type, traits[type]);
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
allTraitInstances() {
|
2019-04-07 12:00:11 -05:00
|
|
|
return this._traits.allInstances();
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
allTraitTypes() {
|
2019-04-07 12:00:11 -05:00
|
|
|
return this._traits.allTypes();
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
fromJSON(json) {
|
|
|
|
super.fromJSON(json);
|
2019-04-07 12:00:11 -05:00
|
|
|
this._traits.fromJSON(json.traits);
|
2019-03-17 23:45:48 -05:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2019-03-23 18:49:19 -05:00
|
|
|
is(type) {
|
2019-04-07 12:00:11 -05:00
|
|
|
return this._traits.hasTrait(type);
|
2019-03-20 18:27:06 -05:00
|
|
|
}
|
|
|
|
|
2019-03-17 23:45:48 -05:00
|
|
|
hydrate() {
|
2019-04-07 12:00:11 -05:00
|
|
|
return this._traits.hydrate();
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
invokeHook(hook, ...args) {
|
2019-04-07 12:00:11 -05:00
|
|
|
return this._traits.invokeHook(hook, ...args);
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
invokeHookFlat(hook, ...args) {
|
2019-04-07 12:00:11 -05:00
|
|
|
return this._traits.invokeHookFlat(hook, ...args);
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
|
2019-04-05 15:16:55 -05:00
|
|
|
patchState(patch) {
|
2019-04-07 12:00:11 -05:00
|
|
|
this._traits.patchState(patch);
|
2019-04-05 15:16:55 -05:00
|
|
|
}
|
|
|
|
|
2019-03-17 23:45:48 -05:00
|
|
|
removeAllTraits() {
|
2019-04-07 12:00:11 -05:00
|
|
|
const types = this._traits.allTypes();
|
2019-03-17 23:45:48 -05:00
|
|
|
this.removeTraits(types);
|
|
|
|
}
|
|
|
|
|
|
|
|
removeTrait(type) {
|
2019-04-07 12:00:11 -05:00
|
|
|
this._traits.removeTrait(type);
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
removeTraits(types) {
|
|
|
|
types.forEach((type) => this.removeTrait(type));
|
|
|
|
}
|
|
|
|
|
2019-03-27 01:02:16 -05:00
|
|
|
get state() {
|
2019-04-07 12:00:11 -05:00
|
|
|
return this._traits.state;
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
|
2019-04-12 13:05:30 -05:00
|
|
|
tick(elapsed) {
|
|
|
|
if (this.isTicking) {
|
|
|
|
this._traits.tick(elapsed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-17 23:45:48 -05:00
|
|
|
toJSON() {
|
|
|
|
return {
|
|
|
|
...super.toJSON(),
|
2019-04-07 12:00:11 -05:00
|
|
|
traits: this._traits.toJSON(),
|
2019-03-17 23:45:48 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export function create() {
|
|
|
|
return createProxy(new Entity());
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createProxy(entity) {
|
|
|
|
return new Proxy(entity, new TraitProxy());
|
|
|
|
}
|
|
|
|
|
|
|
|
export {EntityList} from './list';
|
2019-04-13 20:48:52 -05:00
|
|
|
export {EntityListView} from './list-view';
|
2019-03-17 23:45:48 -05:00
|
|
|
|
|
|
|
export {
|
|
|
|
hasTrait,
|
|
|
|
lookupTrait,
|
|
|
|
registerTrait,
|
2019-03-19 19:52:00 -05:00
|
|
|
} from './trait-registry';
|
2019-03-17 23:45:48 -05:00
|
|
|
|
2019-03-23 23:24:18 -05:00
|
|
|
export {StateProperty, Trait} from './trait';
|