Add files
This commit is contained in:
commit
77bde04db3
97 changed files with 10327 additions and 0 deletions
49
src/helper/array.ts
Normal file
49
src/helper/array.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
declare global {
|
||||
interface Array<T> {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
interface Float32Array {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
}
|
||||
|
||||
export const applyArrayPlugins = () => {
|
||||
Object.defineProperty(Array.prototype, 'x', {
|
||||
get() {
|
||||
return this[0];
|
||||
},
|
||||
set(value) {
|
||||
this[0] = value;
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(Array.prototype, 'y', {
|
||||
get() {
|
||||
return this[1];
|
||||
},
|
||||
set(value) {
|
||||
this[1] = value;
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(Float32Array.prototype, 'x', {
|
||||
get() {
|
||||
return this[0];
|
||||
},
|
||||
set(value) {
|
||||
this[0] = value;
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(Float32Array.prototype, 'y', {
|
||||
get() {
|
||||
return this[1];
|
||||
},
|
||||
set(value) {
|
||||
this[1] = value;
|
||||
},
|
||||
});
|
||||
};
|
||||
59
src/helper/autoscaler.ts
Normal file
59
src/helper/autoscaler.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { clamp } from './clamp';
|
||||
import { mix } from './mix';
|
||||
|
||||
export class Autoscaler {
|
||||
// can have fractions
|
||||
private index: number;
|
||||
|
||||
constructor(
|
||||
private setters: { [key: string]: (value: number | boolean) => void },
|
||||
private targets: Array<{ [key: string]: number | boolean }>,
|
||||
startingIndex: number,
|
||||
private scalingOptions: {
|
||||
additiveIncrease: number;
|
||||
multiplicativeDecrease: number;
|
||||
}
|
||||
) {
|
||||
this.index = startingIndex;
|
||||
this.applyScaling();
|
||||
}
|
||||
|
||||
public increase() {
|
||||
this.index += this.scalingOptions.additiveIncrease;
|
||||
this.applyScaling();
|
||||
}
|
||||
|
||||
public decrease() {
|
||||
this.index /= this.scalingOptions.multiplicativeDecrease;
|
||||
this.applyScaling();
|
||||
}
|
||||
|
||||
private applyScaling() {
|
||||
this.index = clamp(this.index, 0, this.targets.length - 1);
|
||||
|
||||
const floor = Math.floor(this.index);
|
||||
const fract = this.index - floor;
|
||||
|
||||
const previousTarget = this.targets[floor];
|
||||
const nextTarget =
|
||||
floor + 1 == this.targets.length ? previousTarget : this.targets[floor + 1];
|
||||
|
||||
const result = {};
|
||||
for (const key in this.setters) {
|
||||
const previous = previousTarget[key];
|
||||
const next = nextTarget[key];
|
||||
let current: number | boolean;
|
||||
if (typeof previous == 'number') {
|
||||
current = mix(previous, next as number, fract);
|
||||
} else {
|
||||
current = next;
|
||||
}
|
||||
|
||||
result[key] = current;
|
||||
|
||||
this.setters[key](current);
|
||||
}
|
||||
|
||||
//InfoText.modifyRecord('quality', result);
|
||||
}
|
||||
}
|
||||
4
src/helper/clamp.ts
Normal file
4
src/helper/clamp.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export const clamp = (value: number, min: number, max: number): number =>
|
||||
Math.min(max, Math.max(min, value));
|
||||
|
||||
export const clamp01 = (value: number): number => Math.min(1, Math.max(0, value));
|
||||
5
src/helper/exponential-decay.ts
Normal file
5
src/helper/exponential-decay.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export const exponentialDecay = (
|
||||
accumulator: number,
|
||||
nextValue: number,
|
||||
biasOfNextValue: number
|
||||
) => accumulator * (1 - biasOfNextValue) + nextValue * biasOfNextValue;
|
||||
29
src/helper/get-combinations.ts
Normal file
29
src/helper/get-combinations.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
export const getCombinations = (values: Array<Array<number>>): Array<Array<number>> => {
|
||||
if (!values.every((a) => a.length > 0)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const result: Array<Array<number>> = [];
|
||||
const counters = values.map((_) => 0);
|
||||
|
||||
const increaseCounter = (i: number) => {
|
||||
if (i >= counters.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
counters[i]++;
|
||||
|
||||
if (counters[i] >= values[i].length) {
|
||||
counters[i] = 0;
|
||||
return increaseCounter(i + 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
do {
|
||||
result.push(values.map((v, i) => v[counters[i]]));
|
||||
} while (increaseCounter(0));
|
||||
|
||||
return result;
|
||||
};
|
||||
3
src/helper/last.ts
Normal file
3
src/helper/last.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export function last<T>(a: Array<T>): T | null {
|
||||
return a.length > 0 ? a[a.length - 1] : null;
|
||||
}
|
||||
1
src/helper/mix.ts
Normal file
1
src/helper/mix.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export const mix = (from: number, to: number, q: number) => from + (to - from) * q;
|
||||
18
src/helper/random.ts
Normal file
18
src/helper/random.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// src
|
||||
// https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript
|
||||
// Mulberry32
|
||||
|
||||
export abstract class Random {
|
||||
private static _seed = Math.random();
|
||||
|
||||
public static set seed(value: number) {
|
||||
Random._seed = value;
|
||||
}
|
||||
|
||||
public static getRandom(): number {
|
||||
let t = (Random._seed += 0x6d2b79f5);
|
||||
t = Math.imul(t ^ (t >>> 15), t | 1);
|
||||
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
}
|
||||
}
|
||||
3
src/helper/rotate-90-deg.ts
Normal file
3
src/helper/rotate-90-deg.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
|
||||
export const rotate90Deg = (vec: vec2): vec2 => vec2.fromValues(-vec.y, vec.x);
|
||||
32
src/helper/timing.ts
Normal file
32
src/helper/timing.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
export function timeIt(interval = 60) {
|
||||
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||
let i = 0;
|
||||
let previousTimes: Array<DOMHighResTimeStamp> = [];
|
||||
|
||||
const targetFunction = descriptor.value;
|
||||
|
||||
descriptor.value = function (...values) {
|
||||
const start = performance.now();
|
||||
targetFunction.bind(this)(...values);
|
||||
const end = performance.now();
|
||||
|
||||
previousTimes.push(end - start);
|
||||
|
||||
if (i++ % interval == 0) {
|
||||
previousTimes = previousTimes.sort();
|
||||
|
||||
/*const text = `Max: ${last(previousTimes).toFixed(
|
||||
2
|
||||
)} ms\n\tMedian: ${previousTimes[Math.floor(previousTimes.length / 2)].toFixed(
|
||||
2
|
||||
)} ms`;*/
|
||||
|
||||
//InfoText.modifyRecord(propertyKey, text);
|
||||
|
||||
previousTimes = [];
|
||||
}
|
||||
};
|
||||
|
||||
return descriptor;
|
||||
};
|
||||
}
|
||||
1
src/helper/to-percent.ts
Normal file
1
src/helper/to-percent.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export const toPercent = (value: number) => `${Math.round(value * 100)}%`;
|
||||
29
src/helper/wait-while-false.ts
Normal file
29
src/helper/wait-while-false.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
export const waitWhileFalse = (body: () => boolean): Promise<void> => {
|
||||
let resolveOnDone: () => void;
|
||||
let rejectOnDone: (e: Error) => void;
|
||||
|
||||
const onDone = new Promise<void>((resolve, reject) => {
|
||||
resolveOnDone = resolve;
|
||||
rejectOnDone = reject;
|
||||
});
|
||||
|
||||
const waiter = () => {
|
||||
let success: boolean;
|
||||
|
||||
try {
|
||||
success = body();
|
||||
} catch (e) {
|
||||
rejectOnDone(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (success) {
|
||||
resolveOnDone();
|
||||
} else {
|
||||
requestAnimationFrame(waiter);
|
||||
}
|
||||
};
|
||||
|
||||
waiter();
|
||||
return onDone;
|
||||
};
|
||||
3
src/helper/wait.ts
Normal file
3
src/helper/wait.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export const wait = (ms: number): Promise<void> => {
|
||||
return new Promise<void>((resolve, _) => setTimeout(resolve, ms));
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue