92 lines
2.0 KiB
JavaScript
92 lines
2.0 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();
|
|
}
|
|
|
|
synchronizedChildren() {
|
|
return [];
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
tick(elapsed) {
|
|
const children = this.synchronizedChildren();
|
|
for (let i = 0; i < children.length; ++i) {
|
|
const key = children[i];
|
|
if (
|
|
'undefined' !== typeof this[key]
|
|
&& 'undefined' !== typeof this[key].tick
|
|
) {
|
|
this[key].tick(elapsed);
|
|
}
|
|
}
|
|
if (AVOCADO_SERVER) {
|
|
this.state = this.state.withMutations((state) => {
|
|
for (let i = 0; i < children.length; ++i) {
|
|
const key = children[i];
|
|
if (
|
|
'undefined' !== typeof this[key]
|
|
&& 'undefined' !== typeof this[key].state
|
|
) {
|
|
state.set(key, this[key].state);
|
|
}
|
|
else {
|
|
state.set(key, this[key]);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|