import {compose, Property} from '@avocado/core'; import * as Vector from './index' export function VectorMixin( vectorKey = 'vector', x = 'x', y = 'y', meta = {}, ) { meta = { default: [0, 0], eq: function(l, r) { return Vector.equals(l, r); }, ...meta, }; let transformedProperty; if (meta.transformProperty) { transformedProperty = meta.transformProperty(vectorKey); } else { transformedProperty = `$$avocado_property_${vectorKey}`; } meta.initialize = function() { this[transformedProperty] = Vector.copy(meta.default); }; const bypass = `${vectorKey}$bypassChangedEvent`; meta.set = meta.set || new Function('vector', ` this.${transformedProperty} = [ this.${transformedProperty}[0], this.${transformedProperty}[1], ]; if (this.${bypass}) { this.${transformedProperty}[0] = vector[0]; this.${transformedProperty}[1] = vector[1]; } else { this.${x} = vector[0]; this.${y} = vector[1]; } `); function createPropertyPair(axe) { return { get: new Function(` return this.${transformedProperty}[${'x' === axe ? 0 : 1}]; `), set: new Function('value', ` this.${bypass} = true; this.${vectorKey} = [ ${'x' === axe ? 'value' : `this.${x}`}, ${'y' === axe ? 'value' : `this.${y}`}, ]; this.${bypass} = false; `), }; } const decorate = compose( Property(x, { emit: meta.emit, track: meta.track, ...createPropertyPair('x'), }), Property(y, { emit: meta.emit, track: meta.track, ...createPropertyPair('y'), }), Property(vectorKey, meta), ); return (Superclass) => { return class Vector extends decorate(Superclass) { constructor(...args) { super(...args); this[bypass] = false; } } }; }