111 lines
2.7 KiB
JavaScript
111 lines
2.7 KiB
JavaScript
import * as I from 'immutable';
|
|
|
|
import {compose, Property} from '@avocado/core';
|
|
|
|
import {nextStep} from './next-step';
|
|
|
|
const decorate = compose(
|
|
Property('state'),
|
|
);
|
|
|
|
export function Synchronized(Superclass) {
|
|
return class Synchronized extends decorate(Superclass) {
|
|
|
|
constructor(...args) {
|
|
super(...args);
|
|
this.state = I.Map();
|
|
this._childrenWithState = []
|
|
this._childrenWithoutState = [];
|
|
this._childrenWithTickers = [];
|
|
}
|
|
|
|
initializeSynchronizedChildren() {
|
|
const synchronizedChildren = this.synchronizedChildren();
|
|
for (let i = 0; i < synchronizedChildren.length; ++i) {
|
|
const key = synchronizedChildren[i];
|
|
if (
|
|
'undefined' !== typeof this[key]
|
|
&& 'undefined' !== typeof this[key].tick
|
|
) {
|
|
this._childrenWithTickers.push(key);
|
|
}
|
|
if (
|
|
'undefined' !== typeof this[key]
|
|
&& 'undefined' !== typeof this[key].state
|
|
) {
|
|
this._childrenWithState.push(key);
|
|
}
|
|
else {
|
|
this._childrenWithoutState.push(key);
|
|
}
|
|
}
|
|
}
|
|
|
|
patchState(patch) {
|
|
for (const step of patch) {
|
|
const {op, path, value} = step;
|
|
if ('/' === path) {
|
|
for (const key in value) {
|
|
this.patchStateStep(key, {
|
|
op,
|
|
path,
|
|
value: value[key],
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
const [key, substep] = nextStep(step);
|
|
this.patchStateStep(key, {
|
|
op: substep.op,
|
|
path: substep.path,
|
|
value: substep.value,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
patchStateStep(key, step) {
|
|
if (!(key in this)) {
|
|
return;
|
|
}
|
|
if (
|
|
'undefined' !== typeof this[key]
|
|
&& 'undefined' !== typeof this[key].patchState
|
|
) {
|
|
this[key].patchState([step]);
|
|
}
|
|
else {
|
|
this[key] = step.value;
|
|
}
|
|
}
|
|
|
|
synchronizedChildren() {
|
|
return [];
|
|
}
|
|
|
|
tick(elapsed) {
|
|
for (let i = 0; i < this._childrenWithTickers.length; ++i) {
|
|
const key = this._childrenWithTickers[i];
|
|
this[key].tick(elapsed);
|
|
}
|
|
if (AVOCADO_SERVER) {
|
|
this.tickMutateState();
|
|
}
|
|
}
|
|
|
|
tickMutateState() {
|
|
this.state = this.state.withMutations((state) => {
|
|
for (let i = 0; i < this._childrenWithState.length; ++i) {
|
|
const key = this._childrenWithState[i];
|
|
state.set(key, this[key].state);
|
|
}
|
|
for (let i = 0; i < this._childrenWithoutState.length; ++i) {
|
|
const key = this._childrenWithoutState[i];
|
|
state.set(key, this[key]);
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|
|
}
|