experiment simplifying how/what matrix into separate methods

This commit is contained in:
alex
2022-11-30 08:45:34 +00:00
parent 805bd7e930
commit d2375f89ee
3 changed files with 73 additions and 82 deletions
+1 -1
View File
@@ -400,7 +400,7 @@ const generic_params = [
* @example
* freq("220 110 440 110").s("superzow").osc()
* @example
* freq("110".mulOut(".5 1.5 .6 [2 3]")).s("superzow").osc()
* freq("110".mul.out(".5 1.5 .6 [2 3]")).s("superzow").osc()
*
*/
['f', 'freq', ''],
+45 -54
View File
@@ -1463,53 +1463,43 @@ function _composeOp(a, b, func) {
// generate methods to do what and how
for (const [what, [op, preprocess]] of Object.entries(composers)) {
for (const how of hows) {
Pattern.prototype[what + how] = function (...other) {
var pat = this;
other = sequence(other);
if (preprocess) {
pat = preprocess(pat);
other = preprocess(other);
}
var result;
// hack to remove undefs when doing 'keepif'
if (what === 'keepif') {
// avoid union, as we want to throw away the value of 'b' completely
result = pat['_op' + how](other, (a) => (b) => op(a, b));
result = result.removeUndefineds();
} else {
result = pat['_op' + how](other, (a) => (b) => _composeOp(a, b, op));
}
return result;
};
if (how === 'Squeeze') {
// support 'squeezeIn' longhand
Pattern.prototype[what + 'SqueezeIn'] = Pattern.prototype[what + how];
Object.defineProperty(Pattern.prototype, what, {
// a getter that returns a function, so 'pat' can be
// accessed by closures that are methods of that function..
get: function() {
const pat = this;
// wrap the 'in' function as default behaviour
const wrapper = (...other) => pat[what]['in'](...other);
// add methods to that function for each behaviour
for (const how of hows) {
wrapper[how.toLowerCase()] = function (...other) {
var howpat = pat;
other = sequence(other);
if (preprocess) {
howpat = preprocess(howpat);
other = preprocess(other);
}
var result;
// hack to remove undefs when doing 'keepif'
if (what === 'keepif') {
// avoid union, as we want to throw away the value of 'b' completely
result = howpat['_op' + how](other, (a) => (b) => op(a, b));
result = result.removeUndefineds();
} else {
result = howpat['_op' + how](other, (a) => (b) => _composeOp(a, b, op));
}
return result;
}
}
wrapper.squeezeIn = wrapper.squeeze
return wrapper;
}
if (how === 'In') {
// set 'in' to default, but with magic properties to pick a different 'how'
Object.defineProperty(Pattern.prototype, what, {
// a getter that returns a function, so 'pat' can be
// accessed by closures that are methods of that function..
get: function() {
const pat = this;
// wrap the 'in' function as default behaviour
const wrapper = (...other) => pat[what + "In"](...other);
// add methods to that function to pick alternative behaviours
for (const wraphow of hows) {
wrapper[wraphow.toLowerCase()] = (...other) => pat[what + wraphow](...other);
}
return wrapper;
}
});
} else {
// default what to 'set', e.g. squeeze = setSqueeze
if (what === 'set') {
Pattern.prototype[how.toLowerCase()] = Pattern.prototype[what + how];
}
}
}
});
}
// binary composers
@@ -1524,14 +1514,14 @@ function _composeOp(a, b, func) {
* .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~")
* .slow(4)
*/
Pattern.prototype.struct = Pattern.prototype.keepifOut;
Pattern.prototype.structAll = Pattern.prototype.keepOut;
Pattern.prototype.mask = Pattern.prototype.keepifIn;
Pattern.prototype.maskAll = Pattern.prototype.keepIn;
Pattern.prototype.reset = Pattern.prototype.keepifTrig;
Pattern.prototype.resetAll = Pattern.prototype.keepTrig;
Pattern.prototype.restart = Pattern.prototype.keepifTrigzero;
Pattern.prototype.restartAll = Pattern.prototype.keepTrigzero;
Pattern.prototype.struct = function(...args) { return this.keepif.out(...args) }
Pattern.prototype.structAll = function(...args) { return this.keep.out(...args) }
Pattern.prototype.mask = function(...args) { return this.keepif.in(...args) }
Pattern.prototype.maskAll = function(...args) { return this.keep.in(...args) }
Pattern.prototype.reset = function(...args) { return this.keepif.trig(...args) }
Pattern.prototype.resetAll = function(...args) { return this.keep.trig(...args) }
Pattern.prototype.restart = function(...args) { return this.keepif.trigzero(...args) }
Pattern.prototype.restartAll = function(...args) { return this.keep.trigzero(...args) }
})();
// methods of Pattern that get callable factories
@@ -1901,6 +1891,7 @@ Pattern.prototype.range2 = function (...args) {
};
// call this after all Pattern.prototype.define calls have been executed! (right before evaluate)
// (but isn't this called for every define call anyway?)
Pattern.prototype.bootstrap = function () {
// makeComposable(Pattern.prototype);
const bootstrapped = Object.fromEntries(
+27 -27
View File
@@ -156,32 +156,32 @@ describe('Pattern', () => {
describe('add()', () => {
it('can structure In()', () => {
expect(pure(3).add(pure(4)).query(st(0, 1))[0].value).toBe(7);
expect(pure(3).addIn(pure(4)).query(st(0, 1))[0].value).toBe(7);
expect(pure(3).add.in(pure(4)).query(st(0, 1))[0].value).toBe(7);
});
it('can structure Out()', () => {
sameFirst(sequence(1, 2).addOut(4), sequence(5, 6).struct(true));
sameFirst(sequence(1, 2).add.out(4), sequence(5, 6).struct(true));
});
it('can Mix() structure', () => {
expect(sequence(1, 2).addMix(silence, 5, silence).firstCycle()).toStrictEqual([
expect(sequence(1, 2).add.mix(silence, 5, silence).firstCycle()).toStrictEqual([
new Hap(ts(1 / 3, 1 / 2), ts(1 / 3, 1 / 2), 6),
new Hap(ts(1 / 2, 2 / 3), ts(1 / 2, 2 / 3), 7),
]);
});
it('can Trig() structure', () => {
sameFirst(
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).addTrig(20, 30).early(2),
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).add.trig(20, 30).early(2),
sequence(26, 27, 36, 37),
);
});
it('can Trigzero() structure', () => {
sameFirst(
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).addTrigzero(20, 30).early(2),
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).add.trigzero(20, 30).early(2),
sequence(21, 22, 31, 32),
);
});
it('can Squeeze() structure', () => {
sameFirst(
sequence(1, [2, 3]).addSqueeze(sequence(10, 20, 30)),
sequence(1, [2, 3]).add.squeeze(sequence(10, 20, 30)),
sequence(
[11, 21, 31],
[
@@ -193,7 +193,7 @@ describe('Pattern', () => {
});
it('can SqueezeOut() structure', () => {
sameFirst(
sequence(1, [2, 3]).addSqueezeOut(10, 20, 30),
sequence(1, [2, 3]).add.squeezeout(10, 20, 30),
sequence([11, [12, 13]], [21, [22, 23]], [31, [32, 33]]),
);
});
@@ -204,32 +204,32 @@ describe('Pattern', () => {
describe('keep()', () => {
it('can structure In()', () => {
expect(pure(3).keep(pure(4)).query(st(0, 1))[0].value).toBe(3);
expect(pure(3).keepIn(pure(4)).query(st(0, 1))[0].value).toBe(3);
expect(pure(3).keep.in(pure(4)).query(st(0, 1))[0].value).toBe(3);
});
it('can structure Out()', () => {
sameFirst(sequence(1, 2).keepOut(4), sequence(1, 2).struct(true));
sameFirst(sequence(1, 2).keep.out(4), sequence(1, 2).struct(true));
});
it('can Mix() structure', () => {
expect(sequence(1, 2).keepMix(silence, 5, silence).firstCycle()).toStrictEqual([
expect(sequence(1, 2).keep.mix(silence, 5, silence).firstCycle()).toStrictEqual([
new Hap(ts(1 / 3, 1 / 2), ts(1 / 3, 1 / 2), 1),
new Hap(ts(1 / 2, 2 / 3), ts(1 / 2, 2 / 3), 2),
]);
});
it('can Trig() structure', () => {
sameFirst(
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).keepTrig(20, 30).early(2),
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).keep.trig(20, 30).early(2),
sequence(6, 7, 6, 7),
);
});
it('can Trigzero() structure', () => {
sameFirst(
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).keepTrigzero(20, 30).early(2),
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).keep.trigzero(20, 30).early(2),
sequence(1, 2, 1, 2),
);
});
it('can Squeeze() structure', () => {
sameFirst(
sequence(1, [2, 3]).keepSqueeze(sequence(10, 20, 30)),
sequence(1, [2, 3]).keep.squeeze(sequence(10, 20, 30)),
sequence(
[1, 1, 1],
[
@@ -239,39 +239,39 @@ describe('Pattern', () => {
),
);
});
it('can SqueezeOut() structure', () => {
sameFirst(sequence(1, [2, 3]).keepSqueezeOut(10, 20, 30), sequence([1, [2, 3]], [1, [2, 3]], [1, [2, 3]]));
it('can squeezeOut() structure', () => {
sameFirst(sequence(1, [2, 3]).keep.squeezeout(10, 20, 30), sequence([1, [2, 3]], [1, [2, 3]], [1, [2, 3]]));
});
});
describe('keepif()', () => {
it('can structure In()', () => {
sameFirst(sequence(3, 4).keepif(true, false), sequence(3, silence));
sameFirst(sequence(3, 4).keepifIn(true, false), sequence(3, silence));
sameFirst(sequence(3, 4).keepif.in(true, false), sequence(3, silence));
});
it('can structure Out()', () => {
sameFirst(pure(1).keepifOut(true, false), sequence(1, silence));
sameFirst(pure(1).keepif.out(true, false), sequence(1, silence));
});
it('can Mix() structure', () => {
expect(sequence(1, 2).keepifMix(false, true, false).firstCycle()).toStrictEqual([
expect(sequence(1, 2).keepif.mix(false, true, false).firstCycle()).toStrictEqual([
new Hap(ts(1 / 3, 1 / 2), ts(1 / 3, 1 / 2), 1),
new Hap(ts(1 / 2, 2 / 3), ts(1 / 2, 2 / 3), 2),
]);
});
it('can Trig() structure', () => {
sameFirst(
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).keepifTrig(false, true).early(2),
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).keepif.trig(false, true).early(2),
sequence(silence, silence, 6, 7),
);
});
it('can Trigzero() structure', () => {
sameFirst(
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).keepifTrigzero(false, true).early(2),
slowcat(sequence(1, 2, 3, 4), 5, sequence(6, 7, 8, 9), 10).keepif.trigzero(false, true).early(2),
sequence(silence, silence, 1, 2),
);
});
it('can Squeeze() structure', () => {
sameFirst(
sequence(1, [2, 3]).keepifSqueeze(sequence(true, true, false)),
sequence(1, [2, 3]).keepif.squeeze(sequence(true, true, false)),
sequence(
[1, 1, silence],
[
@@ -282,7 +282,7 @@ describe('Pattern', () => {
);
});
it('can SqueezeOut() structure', () => {
sameFirst(sequence(1, [2, 3]).keepifSqueezeOut(true, true, false), sequence([1, [2, 3]], [1, [2, 3]], silence));
sameFirst(sequence(1, [2, 3]).keepif.squeezeout(true, true, false), sequence([1, [2, 3]], [1, [2, 3]], silence));
});
});
describe('sub()', () => {
@@ -320,15 +320,15 @@ describe('Pattern', () => {
it('Can set things with plain values', () => {
sameFirst(sequence(1, 2, 3).set(4), sequence(4).fast(3));
});
describe('setOut()', () => {
describe('set.out()', () => {
it('Can set things with structure from second pattern', () => {
sameFirst(sequence(1, 2).setOut(4), pure(4).mask(true, true));
sameFirst(sequence(1, 2).set.out(4), pure(4).mask(true, true));
});
});
describe('setSqueeze()', () => {
describe('set.squeeze()', () => {
it('Can squeeze one pattern inside the haps of another', () => {
sameFirst(
sequence(1, [2, 3]).setSqueeze(sequence('a', 'b', 'c')),
sequence(1, [2, 3]).set.squeeze(sequence('a', 'b', 'c')),
sequence(
['a', 'b', 'c'],
[
@@ -338,7 +338,7 @@ describe('Pattern', () => {
),
);
sameFirst(
sequence(1, [2, 3]).setSqueeze('a', 'b', 'c'),
sequence(1, [2, 3]).set.squeeze('a', 'b', 'c'),
sequence(
['a', 'b', 'c'],
[