fix: Vector mixin emission semantics

This commit is contained in:
cha0s 2022-03-22 22:43:47 -05:00
parent 5a1f85ecd9
commit b41ad17cdb
2 changed files with 65 additions and 63 deletions

View File

@ -16,53 +16,55 @@ export default function VectorMixin(
...meta,
};
const transformedKey = `$$avocado_property_${vectorKey}`;
// eslint-disable-next-line func-names
meta.initialize = function () {
const bypass = `${transformedKey}$bypassChangedEvent`;
meta.initialize = function initialize() {
this[transformedKey] = Vector.copy(meta.default);
};
const bypass = `${transformedKey}$bypassChangedEvent`;
/* eslint-disable no-new-func */
meta.set = meta.set || new Function('vector', `
this.${transformedKey} = [
this.${transformedKey}[0],
this.${transformedKey}[1],
];
if (this.${bypass}) {
this.${transformedKey}[0] = vector[0];
this.${transformedKey}[1] = vector[1];
}
else {
this.${x} = vector[0];
this.${y} = vector[1];
}
this.${bypass} = true;
this.${x} = vector[0];
this.${y} = vector[1];
this.${bypass} = false;
`);
/* eslint-enable no-param-reassign */
function createPropertyPair(axe) {
// eslint-disable-next-line no-bitwise
const opposite = `this.${transformedKey}[${axe ^ 1}]`;
return {
get: new Function(`
return this.${transformedKey}[${'x' === axe ? 0 : 1}];
return this.${transformedKey}[${0 === axe ? 0 : 1}];
`),
set: new Function('value', `
this.${bypass} = true;
this.${vectorKey} = [
${'x' === axe ? 'value' : `this.${x}`},
${'y' === axe ? 'value' : `this.${y}`},
const old = this.${transformedKey}[${axe}];
this.${transformedKey} = [
${0 === axe ? 'value' : opposite},
${1 === axe ? 'value' : opposite},
];
this.${bypass} = false;
if (${meta.track}) {
if (old !== value) {
this.emit('${axe ? y : x}Changed', old, value);
if (!this.${bypass}) {
this.emit(
'${vectorKey}Changed',
[${0 === axe ? 'old' : opposite}, ${1 === axe ? 'old' : opposite}],
this.${transformedKey},
);
}
}
}
`),
};
}
/* eslint-enable no-new-func */
const decorate = compose(
Property(x, {
emit: meta.emit,
track: meta.track,
...createPropertyPair('x'),
// track: meta.track,
...createPropertyPair(0),
}),
Property(y, {
emit: meta.emit,
track: meta.track,
...createPropertyPair('y'),
// track: meta.track,
...createPropertyPair(1),
}),
Property(vectorKey, meta),
);

View File

@ -1,39 +1,39 @@
// describe('@avocado/math', () => {
// describe('Vector.Mixin', () => {
// var O, spy;
// O = null;
// spy = null;
// beforeEach(() => {
// O = new ((function(_super) {
// __extends(_Class, _super);
import {expect} from 'chai';
// function _Class() {
// return _Class.__super__.constructor.apply(this, arguments);
// }
import {Vector} from '@avocado/math';
import {Class, compose, EventEmitter} from '@flecks/core';
// return _Class;
const decorate = compose(
EventEmitter,
Vector.Mixin('vector', 'x', 'y', {track: true}),
);
// })(MixinOf(EventEmitter, Vector.Mixin())));
// return spy = jasmine.createSpy('listener');
// });
// it('can detect changes', () => {
// O.on('xChanged', spy);
// O.on('yChanged', spy);
// O.on('vectorChanged', spy);
// O.setVector([20, 20]);
// return expect(spy.callCount).toEqual(3);
// });
// return it('can detect changes in the correct order', () => {
// var accum;
// accum = 300;
// O.on('xChanged yChanged', () => {
// return accum /= 10;
// });
// O.on('vectorChanged', () => {
// return accum += 200;
// });
// O.setVector([20, 20]);
// return expect(accum).toEqual(203);
// });
// });
// });
it('can detect mixin changes', () => {
class Test extends decorate(Class) {
constructor() {
super();
this.passed = 0;
this.on('xChanged', () => this.passed++);
this.on('yChanged', () => this.passed++);
this.on('vectorChanged', () => {
this.passed *= 2;
});
}
}
const test = new Test();
test.vector = [1, 1];
expect(test.passed)
.to.equal(4);
test.x = 1;
expect(test.passed)
.to.equal(4);
test.x = 2;
expect(test.passed)
.to.equal(10);
test.y = 1;
expect(test.passed)
.to.equal(10);
test.y = 2;
expect(test.passed)
.to.equal(22);
});