144 lines
2.7 KiB
JavaScript
144 lines
2.7 KiB
JavaScript
![]() |
import * as I from 'immutable';
|
||
|
|
||
|
import {compose} from '@avocado/core';
|
||
|
import {EventEmitter} from '@avocado/mixins';
|
||
|
import {Resource} from '@avocado/resource';
|
||
|
|
||
|
import {Traits} from './traits';
|
||
|
|
||
|
class TraitProxy {
|
||
|
|
||
|
has(entity, property, receiver) {
|
||
|
if (property in entity) {
|
||
|
return Reflect.has(entity, property, receiver);
|
||
|
}
|
||
|
else {
|
||
|
return entity.traits_PRIVATE.hasProperty(property);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
get(entity, property, receiver) {
|
||
|
if (property in entity) {
|
||
|
return Reflect.get(entity, property, receiver);
|
||
|
}
|
||
|
else {
|
||
|
return entity.traits_PRIVATE.getProperty(property);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
set(entity, property, value, receiver) {
|
||
|
if (property in entity) {
|
||
|
return Reflect.set(entity, property, value, receiver);
|
||
|
}
|
||
|
else {
|
||
|
if (!entity.traits_PRIVATE.setProperty(property, value, receiver)) {
|
||
|
return Reflect.set(entity, property, value, receiver);
|
||
|
}
|
||
|
else {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const decorate = compose(
|
||
|
EventEmitter,
|
||
|
);
|
||
|
|
||
|
class Entity extends decorate(Resource) {
|
||
|
|
||
|
constructor() {
|
||
|
super();
|
||
|
this.isTicking_PRIVATE = true;
|
||
|
this.traits_PRIVATE = new Traits(createProxy(this));
|
||
|
}
|
||
|
|
||
|
acceptStateChange(change) {
|
||
|
this.traits_PRIVATE.acceptStateChange(change);
|
||
|
}
|
||
|
|
||
|
addTrait(type, trait) {
|
||
|
this.traits_PRIVATE.addTrait(type, trait);
|
||
|
}
|
||
|
|
||
|
addTraits(traits) {
|
||
|
for (const type in traits) {
|
||
|
this.traits_PRIVATE.addTrait(type, traits[type]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
allTraitInstances() {
|
||
|
return this.traits_PRIVATE.allInstances();
|
||
|
}
|
||
|
|
||
|
allTraitTypes() {
|
||
|
return this.traits_PRIVATE.allTypes();
|
||
|
}
|
||
|
|
||
|
destroy() {
|
||
|
this.isTicking = false;
|
||
|
this.emit('destroyed');
|
||
|
}
|
||
|
|
||
|
fromJSON(json) {
|
||
|
super.fromJSON(json);
|
||
|
this.traits_PRIVATE.fromJSON(json.traits);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
hydrate() {
|
||
|
return this.traits_PRIVATE.hydrate();
|
||
|
}
|
||
|
|
||
|
invokeHook(hook, ...args) {
|
||
|
return this.traits_PRIVATE.invokeHook(hook, ...args);
|
||
|
}
|
||
|
|
||
|
invokeHookFlat(hook, ...args) {
|
||
|
return this.traits_PRIVATE.invokeHookFlat(hook, ...args);
|
||
|
}
|
||
|
|
||
|
removeAllTraits() {
|
||
|
const types = this.traits_PRIVATE.allTypes();
|
||
|
this.removeTraits(types);
|
||
|
}
|
||
|
|
||
|
removeTrait(type) {
|
||
|
this.traits_PRIVATE.removeTrait(type);
|
||
|
}
|
||
|
|
||
|
removeTraits(types) {
|
||
|
types.forEach((type) => this.removeTrait(type));
|
||
|
}
|
||
|
|
||
|
state() {
|
||
|
return this.traits_PRIVATE.state();
|
||
|
}
|
||
|
|
||
|
toJSON() {
|
||
|
return {
|
||
|
...super.toJSON(),
|
||
|
traits: this.traits_PRIVATE.toJSON(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export function create() {
|
||
|
return createProxy(new Entity());
|
||
|
}
|
||
|
|
||
|
export function createProxy(entity) {
|
||
|
return new Proxy(entity, new TraitProxy());
|
||
|
}
|
||
|
|
||
|
export {EntityList} from './list';
|
||
|
|
||
|
export {
|
||
|
hasTrait,
|
||
|
lookupTrait,
|
||
|
registerTrait,
|
||
|
} from './traits/registry';
|
||
|
|
||
|
export {simpleState, Trait} from './trait';
|