/
Accuracy.ts
62 lines (55 loc) · 1.75 KB
/
Accuracy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { Unit } from '../../utils/unit';
import { Vector3 } from '../../utils/math/Vector3';
import { SerializableObject, SerializableMember } from '../decorators';
@SerializableObject()
export abstract class Accuracy<U extends Unit = Unit, T extends number | Vector3 | any = number> {
@SerializableMember()
value: T;
@SerializableMember({
name: 'unit',
})
protected _unit!: Unit;
constructor(value?: T, unit?: U) {
this.value = value;
this._unit = unit;
}
/**
* Convert the value to another unit
* @param {Unit} unit Target unit
* @returns {Accuracy} Converted value
*/
to<T extends Unit>(unit: T): this {
if (!unit) {
throw new Error(`${this.constructor.name} does not have a unit to convert from!`);
}
const value = this.value;
if (!(value instanceof Vector3) && typeof value !== 'number') {
throw new Error(`${this.constructor.name} can not be converted!`);
}
const result = this.unit.convert(value, unit);
return new (this.constructor as new (...args: any[]) => this)(result, unit);
}
/**
* Unit this value is in
* @returns {Unit} Unit this value is in
*/
get unit(): U {
return this._unit as U;
}
/**
* Get a one dimensional primitive value
* @returns {number} Primitive value
*/
abstract valueOf(): number;
/**
* Returns a string representation of an object.
* @returns {string} Unit value as string
*/
abstract toString(): string;
clone(): this {
const result = new (this.constructor as new (...args: any[]) => this)();
result.value = this.value;
result._unit = this._unit;
return result;
}
}