Skip to content

Commit

Permalink
feat(operator): avoid using cachedFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
MrTelanie committed Apr 3, 2020
1 parent 8735a2c commit c6d9833
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 115 deletions.
28 changes: 24 additions & 4 deletions src/operator.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

// @ts-nocheck
const X = 0;
const Y = 1;
const Z = 2;
Expand Down Expand Up @@ -155,6 +155,11 @@ export function cachedValueOf(VectorClass, getSource) {
};
}

/**
* @template {Function} F
* @param {F} org
* @returns {org}
*/
function bindCache(org) {
return function (...args) {
if (inProgress === X) {
Expand Down Expand Up @@ -198,7 +203,7 @@ export function cachedGetter(VectorClass, name) {
};

Object.defineProperty(Vector, name, {
get: bindCache(org)
get: bindCache(org),
});
}

Expand All @@ -208,10 +213,25 @@ export function defineVectorLength(VectorClass, value) {
Object.defineProperty(Vector, VECTOR_LENGTH, { value });
}

/**
* @template {} F, A
* @param {{new(...args: A[]): F}} VectorClass
* @returns {(...args: A[]) => F}
*/
export function cachedFactory(VectorClass) {
return bindCache((...args) => new VectorClass(...args));
}

export function cachedFunction(realFactory) {
return bindCache((...args) => realFactory(...args));
/**
* @template T
* @typedef {{new(...args: any[]): T}} IsClass
*/

/**
* @template {Function} F
* @param {F} fun
* @returns {F}
*/
export function cachedFunction(fun) {
return bindCache(fun);
}
24 changes: 8 additions & 16 deletions src/point.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
// @ts-nocheck
import { isArray, normRad } from './util';
import {
cachedMethod,
cachedGetter,
cachedValueOf,
operatorCalc,
defineVectorLength,
cachedFactory
} from './operator';
import { cachedFunction, cachedGetter, cachedMethod, cachedValueOf, defineVectorLength, operatorCalc } from './operator';

const X = 0;
const Y = 1;
Expand All @@ -29,13 +22,11 @@ function square(val) {
* @typedef {Point & number} PointType
* @typedef {() => number} Alg
* @typedef {APoint & number} APointType
*/
/**
* @abstract
*/
class APoint {
/**
* @param {number | [number, number] | {x: number, y: number} | Alg} [x]
* @param {number} [y]
*/
constructor(x, y) {
if (typeof x === 'function') {
operatorCalc(x, (nx, ny) => {
Expand Down Expand Up @@ -338,8 +329,6 @@ export function calc(alg) {
return operatorCalc(alg);
}

const pointFactory = cachedFactory(Point);

/**
* @template P
* @typedef {() => P} PZero
Expand All @@ -364,12 +353,15 @@ const pointFactory = cachedFactory(Point);
* @template P
* @typedef {PZero<P> & PAlg<P> & PCon<P> & PArr<P> & PObj<P>} Po
*/

const pointFactory = cachedFunction((x, y) => new Point(x, y));

/**
* @type {Po<PointType>}
*/
export const point = (...args) => pointFactory(...args);
export const point = (x, y) => pointFactory(x, y);

const ipointFactory = cachedFactory(IPoint);
const ipointFactory = cachedFunction((x, y) => new IPoint(x, y));

/**
* @type {Po<IPointType>}
Expand Down
120 changes: 66 additions & 54 deletions src/quaternion.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// @ts-nocheck
import {
Vector, Victor, FORWARD, LEFT, UP, RIGHT
} from './vector';
import { FORWARD, LEFT, RIGHT, UP, Vector, Victor } from './vector';
import { isArray, multQuatVec } from './util';
import { formatNumber } from './formatter';
import { cachedFactory } from './operator';
import { isAngle, degree } from './degree';
import { cachedFunction } from './operator';
import { degree, isAngle } from './degree';

const X = 0;
const Y = 1;
Expand All @@ -21,6 +19,7 @@ const INVERSE_CACHE = Symbol('inverse cache');
function length([x, y, z, w]) {
return Math.sqrt(x * x + y * y + z * z + w * w);
}

function normalize(axes) {
const len = length(axes);
axes[X] /= len;
Expand Down Expand Up @@ -114,12 +113,6 @@ function from(x, y, z, w) {
}

class AQuaternion {
/**
* @param {number | Vector | Victor | Quaternion | IQuaternion | [number, number, number, number] } [x]
* @param {number | Vector | Victor} [y]
* @param {number} [z]
* @param {number} [w]
*/
constructor(x, y, z, w) {
this[AXES] = from(x, y, z, w);
normalize(this[AXES]);
Expand Down Expand Up @@ -169,7 +162,7 @@ class AQuaternion {

get inverse() {
const {
x, y, z, w
x, y, z, w,
} = this;
return this.constructor(x * -1, y * -1, z * -1, w);
}
Expand All @@ -179,10 +172,10 @@ class AQuaternion {
}

/**
*
* @param {AQuaternion} v
* @returns {boolean}
*/
*
* @param {AQuaternion} v
* @returns {boolean}
*/
equals(v) {
return this.x === v.x && this.y === v.y && this.z === v.z && this.w === v.w;
}
Expand All @@ -200,17 +193,17 @@ class AQuaternion {
}

/**
*
* @returns {number}
*/
*
* @returns {number}
*/
get x() {
return this[AXES][X];
}

/**
*
* @throws SetNotImplementedError
*/
*
* @throws SetNotImplementedError
*/
set x(_) {
throw new Error('set x() not implemented');
}
Expand Down Expand Up @@ -274,11 +267,11 @@ class AQuaternion {

export class Quaternion extends AQuaternion {
/**
* @param {number | Quaternion | IQuaternion | Vector | Victor | [number, number, number, number] } [x]
* @param {number | Vector | Victor} [y]
* @param {number} [z]
* @param {number} [w]
*/
* @param {number | Quaternion | IQuaternion | Vector | Victor | [number, number, number, number] } [x]
* @param {number | Vector | Victor} [y]
* @param {number} [z]
* @param {number} [w]
*/
set(x, y, z, w) {
if (x instanceof AQuaternion) {
this[AXES] = [...x[AXES]];
Expand All @@ -289,9 +282,9 @@ export class Quaternion extends AQuaternion {
}

/**
*
* @param {number} x
*/
*
* @param {number} x
*/
set x(x) {
this[AXES][X] = x;
}
Expand All @@ -313,9 +306,9 @@ export class Quaternion extends AQuaternion {
}

/**
*
* @param {number} w
*/
*
* @param {number} w
*/
set w(w) {
this[AXES][W] = w;
}
Expand Down Expand Up @@ -378,41 +371,60 @@ export class IQuaternion extends AQuaternion {
get inverse() {
return fromCache(this, INVERSE_CACHE, () => {
const {
x, y, z, w
x, y, z, w,
} = this;
return this.constructor(x * -1, y * -1, z * -1, w);
});
}
}

const quaternionFactory = cachedFactory(Quaternion);
const q = new Quaternion();

const quaternionFactory = cachedFunction((x, y, z, w) => new Quaternion(x, y, z, w));

/**
* @typedef {Vector | Victor} VectorType
* @typedef {() => Quaternion} QuatZero
* @typedef {(x: number , y: number, z: number, w: number) => Quaternion} QuatNumber
* @typedef {(dir: VectorType) => Quaternion} QuatDir
* @typedef {(dir: VectorType, up: VectorType) => Quaternion} QuatDirUp
* @typedef {(axis: VectorType, angle: number) => Quaternion} QuatAxis
* @typedef {(arr: [number, number, number, number]) => Quaternion} QuatArr
* @type {QuatNumber & QuatDir & QuatDirUp & QuatAxis & QuatArr & QuatZero}
*/
export const quaternion = function (x, y, z, w) {
return quaternionFactory(x, y, z, w);
};
/**
* @template Q
* @typedef {() => Q} QuatZero
*/
/**
* @template Q
* @typedef {(x: number, y: number, z: number, w: number) => Q} QuatNumber
*/
/**
* @template Q
* @typedef {(dir: VectorType) => Q} QuatDir
*/
/**
* @template Q
* @typedef {(dir: VectorType, up: VectorType) => Q} QuatDirUp
*/
/**
* @template Q
* @typedef {(axis: VectorType, angle: number) => Q} QuatAxis
*/
/**
* @template Q
* @typedef {(arr: [number, number, number, number]) => Q} QuatArr
*/
/**
* @template Q
* @typedef {QuatZero<Q> & QuatDir<Q> & QuatDirUp<Q> & QuatAxis<Q> & QuatArr<Q> & QuatZero<Q>} QuatFac
*/

/**
* @type {QuatFac<Quaternion>}
*/
export const quaternion = (x, y, z, w) => quaternionFactory(x, y, z, w);

const iquaternionFactory = cachedFactory(IQuaternion);
const iquaternionFactory = cachedFunction((x, y, z, w) => new IQuaternion(x, y, z, w));

/**
* @typedef {() => IQuaternion} IQuatZero
* @typedef {(x: number, y: number, z: number, w: number) => IQuaternion} IQuatNumber
* @typedef {(dir: VectorType) => IQuaternion} IQuatDir
* @typedef {(dir: VectorType, up: VectorType) => IQuaternion} IQuatDirUp
* @typedef {(axis: VectorType, angle: number) => IQuaternion} IQuatAxis
* @typedef {(arr: [number, number, number, number]) => IQuaternion} IQuatArr
* @type {IQuatNumber & IQuatDir & IQuatDirUp & IQuatAxis & IQuatArr & IQuatZero}
* @type {QuatFac<IQuaternion>}
*/
export const iquaternion = (...args) => iquaternionFactory(...args);
export const iquaternion = (x, y, z, w) => iquaternionFactory(x, y, z, w);

const LEFT90 = new IQuaternion(LEFT, degree(90));

Expand Down
Loading

0 comments on commit c6d9833

Please sign in to comment.