From ae4559370b53de0fc3375996cc815be148135398 Mon Sep 17 00:00:00 2001 From: yzrmn Date: Thu, 12 Dec 2024 16:37:16 +0100 Subject: [PATCH] Use more readonly types --- packages/redgeometry/src/core/path.ts | 9 +++- packages/redgeometry/src/primitives/bezier.ts | 41 ++++++++++++---- packages/redgeometry/src/primitives/box.ts | 24 ++++++++-- packages/redgeometry/src/primitives/color.ts | 11 ++++- .../redgeometry/src/primitives/complex.ts | 12 ++--- packages/redgeometry/src/primitives/edge.ts | 18 +++++-- packages/redgeometry/src/primitives/point.ts | 30 ++++++------ .../redgeometry/src/primitives/quaternion.ts | 16 +++---- packages/redgeometry/src/primitives/ray.ts | 18 +++++-- packages/redgeometry/src/primitives/vector.ts | 48 +++++++++---------- packages/redgeometry/src/utility/array.ts | 7 ++- packages/redgeometry/src/utility/hash.ts | 2 +- packages/redgeometry/src/utility/set.ts | 2 +- 13 files changed, 157 insertions(+), 81 deletions(-) diff --git a/packages/redgeometry/src/core/path.ts b/packages/redgeometry/src/core/path.ts index 4293475..2b0009a 100644 --- a/packages/redgeometry/src/core/path.ts +++ b/packages/redgeometry/src/core/path.ts @@ -48,6 +48,11 @@ export enum PathCommandType { Close, } +export type Path2Like = { + readonly points: Point2Like[]; + readonly commands: PathCommand[]; +}; + export type PathCommandMove = { type: PathCommandType.Move }; export type PathCommandLine = { type: PathCommandType.Linear }; export type PathCommandQuad = { type: PathCommandType.Quadratic }; @@ -76,13 +81,13 @@ export class Path2 implements PathSink2 { return new Path2([], []); } - public static fromObject(obj: { points: Point2Like[]; commands: PathCommand[] }): Path2 { + public static fromObject(obj: Path2Like): Path2 { const commands = obj.commands.map((c) => ({ ...c })); const points = obj.points.map((p) => Point2.fromObject(p)); return new Path2(commands, points); } - public static toObject(path: Path2): { points: Point2Like[]; commands: PathCommand[] } { + public static toObject(path: Path2): Path2Like { const commands = path.commands.map((c) => ({ ...c })); const points = path.points.map((p) => Point2.toObject(p)); return { commands, points }; diff --git a/packages/redgeometry/src/primitives/bezier.ts b/packages/redgeometry/src/primitives/bezier.ts index f0fc36f..778a3aa 100644 --- a/packages/redgeometry/src/primitives/bezier.ts +++ b/packages/redgeometry/src/primitives/bezier.ts @@ -21,6 +21,31 @@ export enum CurveType { BezierR, } +export type Bezier1Curve2Like = { + readonly p0: Point2; + readonly p1: Point2; +}; + +export type Bezier2Curve2Like = { + readonly p0: Point2; + readonly p1: Point2; + readonly p2: Point2; +}; + +export type Bezier3Curve2Like = { + readonly p0: Point2; + readonly p1: Point2; + readonly p2: Point2; + readonly p3: Point2; +}; + +export type BezierRCurve2Like = { + readonly p0: Point2; + readonly p1: Point2; + readonly p2: Point2; + readonly w: number; +}; + export type BezierCurve2 = Bezier1Curve2 | Bezier2Curve2 | Bezier3Curve2 | BezierRCurve2; export class Bezier1Curve2 { @@ -40,14 +65,14 @@ export class Bezier1Curve2 { return CurveType.Bezier1; } - public static fromArray(data: number[], offset = 0): Bezier1Curve2 { + public static fromArray(data: ArrayLike, offset = 0): Bezier1Curve2 { const p0 = Point2.fromArray(data, offset); const p1 = Point2.fromArray(data, offset + 2); return new Bezier1Curve2(p0, p1); } - public static fromObject(obj: { p0: Point2Like; p1: Point2Like }): Bezier1Curve2 { + public static fromObject(obj: Bezier1Curve2Like): Bezier1Curve2 { const p0 = Point2.fromObject(obj.p0); const p1 = Point2.fromObject(obj.p1); return new Bezier1Curve2(p0, p1); @@ -198,7 +223,7 @@ export class Bezier2Curve2 { return CurveType.Bezier2; } - public static fromArray(data: number[], offset = 0): Bezier2Curve2 { + public static fromArray(data: ArrayLike, offset = 0): Bezier2Curve2 { const p0 = Point2.fromArray(data, offset); const p1 = Point2.fromArray(data, offset + 2); const p2 = Point2.fromArray(data, offset + 4); @@ -206,7 +231,7 @@ export class Bezier2Curve2 { return new Bezier2Curve2(p0, p1, p2); } - public static fromObject(obj: { p0: Point2Like; p1: Point2Like; p2: Point2Like }): Bezier2Curve2 { + public static fromObject(obj: Bezier2Curve2Like): Bezier2Curve2 { const p0 = Point2.fromObject(obj.p0); const p1 = Point2.fromObject(obj.p1); const p2 = Point2.fromObject(obj.p2); @@ -567,7 +592,7 @@ export class Bezier3Curve2 { return CurveType.Bezier3; } - public static fromArray(data: number[], offset = 0): Bezier3Curve2 { + public static fromArray(data: ArrayLike, offset = 0): Bezier3Curve2 { const p0 = Point2.fromArray(data, offset); const p1 = Point2.fromArray(data, offset + 2); const p2 = Point2.fromArray(data, offset + 4); @@ -576,7 +601,7 @@ export class Bezier3Curve2 { return new Bezier3Curve2(p0, p1, p2, p3); } - public static fromObject(obj: { p0: Point2Like; p1: Point2Like; p2: Point2Like; p3: Point2Like }): Bezier3Curve2 { + public static fromObject(obj: Bezier3Curve2Like): Bezier3Curve2 { const p0 = Point2.fromObject(obj.p0); const p1 = Point2.fromObject(obj.p1); const p2 = Point2.fromObject(obj.p2); @@ -946,7 +971,7 @@ export class BezierRCurve2 { return CurveType.BezierR; } - public static fromArray(data: number[], offset = 0): BezierRCurve2 { + public static fromArray(data: ArrayLike, offset = 0): BezierRCurve2 { const p0 = Point2.fromArray(data, offset); const p1 = Point2.fromArray(data, offset + 2); const p2 = Point2.fromArray(data, offset + 4); @@ -963,7 +988,7 @@ export class BezierRCurve2 { return new BezierRCurve2(p0, p1, p2, w); } - public static fromObject(obj: { p0: Point2Like; p1: Point2Like; p2: Point2Like; w: number }): BezierRCurve2 { + public static fromObject(obj: BezierRCurve2Like): BezierRCurve2 { const p0 = Point2.fromObject(obj.p0); const p1 = Point2.fromObject(obj.p1); const p2 = Point2.fromObject(obj.p2); diff --git a/packages/redgeometry/src/primitives/box.ts b/packages/redgeometry/src/primitives/box.ts index d112d70..c7e61e2 100644 --- a/packages/redgeometry/src/primitives/box.ts +++ b/packages/redgeometry/src/primitives/box.ts @@ -2,6 +2,22 @@ import type { Matrix3, Matrix3A, Matrix4, Matrix4A } from "./matrix.js"; import { Point2, Point3 } from "./point.js"; import type { Ray2, Ray3 } from "./ray.js"; +export type Box2Like = { + readonly x0: number; + readonly x1: number; + readonly y0: number; + readonly y1: number; +}; + +export type Box3Like = { + readonly x0: number; + readonly x1: number; + readonly y0: number; + readonly y1: number; + readonly z0: number; + readonly z1: number; +}; + export class Box2 { public x0: number; public x1: number; @@ -27,11 +43,11 @@ export class Box2 { ); } - public static fromArray(data: number[], offset = 0): Box2 { + public static fromArray(data: ArrayLike, offset = 0): Box2 { return new Box2(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]); } - public static fromObject(obj: { x0: number; y0: number; x1: number; y1: number }): Box2 { + public static fromObject(obj: Box2Like): Box2 { return new Box2(obj.x0, obj.y0, obj.x1, obj.y1); } @@ -223,7 +239,7 @@ export class Box3 { ); } - public static fromArray(data: number[], offset = 0): Box3 { + public static fromArray(data: ArrayLike, offset = 0): Box3 { return new Box3( data[offset], data[offset + 1], @@ -234,7 +250,7 @@ export class Box3 { ); } - public static fromObject(obj: { x0: number; y0: number; z0: number; x1: number; y1: number; z1: number }): Box3 { + public static fromObject(obj: Box3Like): Box3 { return new Box3(obj.x0, obj.y0, obj.z0, obj.x1, obj.y1, obj.z1); } diff --git a/packages/redgeometry/src/primitives/color.ts b/packages/redgeometry/src/primitives/color.ts index 2c529d5..95c2264 100644 --- a/packages/redgeometry/src/primitives/color.ts +++ b/packages/redgeometry/src/primitives/color.ts @@ -1,5 +1,12 @@ import { clamp } from "../utility/scalar.js"; +export type ColorRgbaLike = { + readonly a: number; + readonly b: number; + readonly g: number; + readonly r: number; +}; + export class ColorRgba { public a: number; public b: number; @@ -13,7 +20,7 @@ export class ColorRgba { this.a = a; } - public static fromArray(data: number[], offset = 0): ColorRgba { + public static fromArray(data: ArrayLike, offset = 0): ColorRgba { return new ColorRgba(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]); } @@ -51,7 +58,7 @@ export class ColorRgba { return new ColorRgba(r / 255, g / 255, b / 255, a / 255); } - public static fromObject(obj: { r: number; g: number; b: number; a: number }): ColorRgba { + public static fromObject(obj: ColorRgbaLike): ColorRgba { return new ColorRgba(obj.r, obj.g, obj.b, obj.a); } diff --git a/packages/redgeometry/src/primitives/complex.ts b/packages/redgeometry/src/primitives/complex.ts index aaa0a9b..1fca161 100644 --- a/packages/redgeometry/src/primitives/complex.ts +++ b/packages/redgeometry/src/primitives/complex.ts @@ -2,15 +2,15 @@ import { eqApproxAbs, eqApproxRel } from "../utility/scalar.js"; import { Point2 } from "./point.js"; import { Vector2 } from "./vector.js"; -export interface ComplexLike { - a: number; - b: number; -} +export type ComplexLike = { + readonly a: number; + readonly b: number; +}; /** * A complex number to be used for 2D rotations. */ -export class Complex implements ComplexLike { +export class Complex { public a: number; public b: number; @@ -23,7 +23,7 @@ export class Complex implements ComplexLike { return new Complex(1, 0); } - public static fromArray(data: number[], offset = 0): Complex { + public static fromArray(data: ArrayLike, offset = 0): Complex { return new Complex(data[offset], data[offset + 1]); } diff --git a/packages/redgeometry/src/primitives/edge.ts b/packages/redgeometry/src/primitives/edge.ts index 2bcc3c0..52a68ce 100644 --- a/packages/redgeometry/src/primitives/edge.ts +++ b/packages/redgeometry/src/primitives/edge.ts @@ -6,6 +6,16 @@ import { Point2, Point3, type Point2Like, type Point3Like } from "./point.js"; import { Ray2, Ray3 } from "./ray.js"; import type { Vector2, Vector3 } from "./vector.js"; +export type Edge2Like = { + readonly p0: Point2; + readonly p1: Point2; +}; + +export type Edge3Like = { + readonly p0: Point3; + readonly p1: Point3; +}; + export class Edge2 { public p0: Point2; public p1: Point2; @@ -42,14 +52,14 @@ export class Edge2 { } } - public static fromArray(data: number[], offset = 0): Edge2 { + public static fromArray(data: ArrayLike, offset = 0): Edge2 { const p0 = Point2.fromArray(data, offset); const p1 = Point2.fromArray(data, offset + 2); return new Edge2(p0, p1); } - public static fromObject(obj: { p0: Point2Like; p1: Point2Like }): Edge2 { + public static fromObject(obj: Edge2Like): Edge2 { const p0 = Point2.fromObject(obj.p0); const p1 = Point2.fromObject(obj.p1); return new Edge2(p0, p1); @@ -390,14 +400,14 @@ export class Edge3 { this.p1 = p1; } - public static fromArray(data: number[], offset = 0): Edge3 { + public static fromArray(data: ArrayLike, offset = 0): Edge3 { const p0 = Point3.fromArray(data, offset); const p1 = Point3.fromArray(data, offset + 3); return new Edge3(p0, p1); } - public static fromObject(obj: { p0: Point3Like; p1: Point3Like }): Edge3 { + public static fromObject(obj: Edge3Like): Edge3 { const p0 = Point3.fromObject(obj.p0); const p1 = Point3.fromObject(obj.p1); return new Edge3(p0, p1); diff --git a/packages/redgeometry/src/primitives/point.ts b/packages/redgeometry/src/primitives/point.ts index b834148..aa0bc5f 100644 --- a/packages/redgeometry/src/primitives/point.ts +++ b/packages/redgeometry/src/primitives/point.ts @@ -1,18 +1,18 @@ import { eqApproxAbs, eqApproxRel, lerp, roundToPrecision } from "../utility/scalar.js"; import { Vector2, Vector3 } from "./vector.js"; -export interface Point2Like { - x: number; - y: number; -} - -export interface Point3Like { - x: number; - y: number; - z: number; -} - -export class Point2 implements Point2Like { +export type Point2Like = { + readonly x: number; + readonly y: number; +}; + +export type Point3Like = { + readonly x: number; + readonly y: number; + readonly z: number; +}; + +export class Point2 { public x: number; public y: number; @@ -28,7 +28,7 @@ export class Point2 implements Point2Like { return new Point2(0, 0); } - public static fromArray(data: number[], offset = 0): Point2 { + public static fromArray(data: ArrayLike, offset = 0): Point2 { return new Point2(data[offset], data[offset + 1]); } @@ -161,7 +161,7 @@ export class Point2 implements Point2Like { } } -export class Point3 implements Point3Like { +export class Point3 { public x: number; public y: number; public z: number; @@ -179,7 +179,7 @@ export class Point3 implements Point3Like { return new Point3(0, 0, 0); } - public static fromArray(data: number[], offset = 0): Point3 { + public static fromArray(data: ArrayLike, offset = 0): Point3 { return new Point3(data[offset], data[offset + 1], data[offset + 2]); } diff --git a/packages/redgeometry/src/primitives/quaternion.ts b/packages/redgeometry/src/primitives/quaternion.ts index c7fe026..eeaaeb1 100644 --- a/packages/redgeometry/src/primitives/quaternion.ts +++ b/packages/redgeometry/src/primitives/quaternion.ts @@ -12,12 +12,12 @@ export enum RotationOrder { ZYX, } -export interface QuaternionLike { - a: number; - b: number; - c: number; - d: number; -} +export type QuaternionLike = { + readonly a: number; + readonly b: number; + readonly c: number; + readonly d: number; +}; /** * A quaternion to be used for 3D rotations. @@ -26,7 +26,7 @@ export interface QuaternionLike { * - https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation * - https://danceswithcode.net/engineeringnotes/quaternions/quaternions.html */ -export class Quaternion implements QuaternionLike { +export class Quaternion { public a: number; public b: number; public c: number; @@ -43,7 +43,7 @@ export class Quaternion implements QuaternionLike { return new Quaternion(1, 0, 0, 0); } - public static fromArray(data: number[], offset = 0): Quaternion { + public static fromArray(data: ArrayLike, offset = 0): Quaternion { return new Quaternion(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]); } diff --git a/packages/redgeometry/src/primitives/ray.ts b/packages/redgeometry/src/primitives/ray.ts index 8d6341c..2b8c34c 100644 --- a/packages/redgeometry/src/primitives/ray.ts +++ b/packages/redgeometry/src/primitives/ray.ts @@ -1,6 +1,16 @@ import { Point2, Point3, type Point2Like, type Point3Like } from "./point.js"; import { Vector2, Vector3, type Vector2Like, type Vector3Like } from "./vector.js"; +export type Ray2Like = { + readonly p: Point2; + readonly v: Vector2; +}; + +export type Ray3Like = { + readonly p: Point3; + readonly v: Vector3; +}; + export class Ray2 { public p: Point2; public v: Vector2; @@ -10,14 +20,14 @@ export class Ray2 { this.v = v; } - public static fromArray(data: number[], offset = 0): Ray2 { + public static fromArray(data: ArrayLike, offset = 0): Ray2 { const p = Point2.fromArray(data, offset); const v = Vector2.fromArray(data, offset + 2); return new Ray2(p, v); } - public static fromObject(obj: { p: Point2Like; v: Vector2Like }): Ray2 { + public static fromObject(obj: Ray2Like): Ray2 { const p = Point2.fromObject(obj.p); const v = Vector2.fromObject(obj.v); return new Ray2(p, v); @@ -136,14 +146,14 @@ export class Ray3 { this.v = v; } - public static fromArray(data: number[], offset = 0): Ray3 { + public static fromArray(data: ArrayLike, offset = 0): Ray3 { const p = Point3.fromArray(data, offset); const v = Vector3.fromArray(data, offset + 3); return new Ray3(p, v); } - public static fromObject(obj: { p: Point3Like; v: Vector3Like }): Ray3 { + public static fromObject(obj: Ray3Like): Ray3 { const p = Point3.fromObject(obj.p); const v = Vector3.fromObject(obj.v); return new Ray3(p, v); diff --git a/packages/redgeometry/src/primitives/vector.ts b/packages/redgeometry/src/primitives/vector.ts index b86ded8..710a844 100644 --- a/packages/redgeometry/src/primitives/vector.ts +++ b/packages/redgeometry/src/primitives/vector.ts @@ -1,25 +1,25 @@ import { clamp, eqApproxAbs, eqApproxRel, lerp } from "../utility/scalar.js"; import { Point2, Point3 } from "./point.js"; -export interface Vector2Like { - x: number; - y: number; -} - -export interface Vector3Like { - x: number; - y: number; - z: number; -} - -export interface Vector4Like { - x: number; - y: number; - z: number; - w: number; -} - -export class Vector2 implements Vector2Like { +export type Vector2Like = { + readonly x: number; + readonly y: number; +}; + +export type Vector3Like = { + readonly x: number; + readonly y: number; + readonly z: number; +}; + +export type Vector4Like = { + readonly x: number; + readonly y: number; + readonly z: number; + readonly w: number; +}; + +export class Vector2 { public x: number; public y: number; @@ -56,7 +56,7 @@ export class Vector2 implements Vector2Like { return new Vector2(0, 0); } - public static fromArray(data: number[], offset = 0): Vector2 { + public static fromArray(data: ArrayLike, offset = 0): Vector2 { return new Vector2(data[offset], data[offset + 1]); } @@ -304,7 +304,7 @@ export class Vector2 implements Vector2Like { } } -export class Vector3 implements Vector3Like { +export class Vector3 { public x: number; public y: number; public z: number; @@ -350,7 +350,7 @@ export class Vector3 implements Vector3Like { return new Vector3(0, 0, 0); } - public static fromArray(data: number[], offset = 0): Vector3 { + public static fromArray(data: ArrayLike, offset = 0): Vector3 { return new Vector3(data[offset], data[offset + 1], data[offset + 2]); } @@ -642,7 +642,7 @@ export class Vector3 implements Vector3Like { } } -export class Vector4 implements Vector4Like { +export class Vector4 { public x: number; public y: number; public z: number; @@ -697,7 +697,7 @@ export class Vector4 implements Vector4Like { return new Vector4(0, 0, 0, 0); } - public static fromArray(data: number[], offset = 0): Vector4 { + public static fromArray(data: ArrayLike, offset = 0): Vector4 { return new Vector4(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]); } diff --git a/packages/redgeometry/src/utility/array.ts b/packages/redgeometry/src/utility/array.ts index 263b509..6d205be 100644 --- a/packages/redgeometry/src/utility/array.ts +++ b/packages/redgeometry/src/utility/array.ts @@ -13,7 +13,7 @@ export class ArrayMultiSet { this.data = []; } - public static fromArray(array: T[], compareFn: (a: T, b: T) => number): ArrayMultiSet { + public static fromArray(array: ReadonlyArray, compareFn: (a: T, b: T) => number): ArrayMultiSet { const multiSet = new ArrayMultiSet(compareFn); multiSet.data = array.slice().sort(compareFn); return multiSet; @@ -180,7 +180,10 @@ export class ArrayMultiMap { this.data = []; } - public static fromArray(array: KeyValue[], compareFn: (a: K, b: K) => number): ArrayMultiMap { + public static fromArray( + array: ReadonlyArray>, + compareFn: (a: K, b: K) => number, + ): ArrayMultiMap { const multiMap = new ArrayMultiMap(compareFn); multiMap.data = array.slice().sort((d1, d2) => compareFn(d1.key, d2.key)); return multiMap; diff --git a/packages/redgeometry/src/utility/hash.ts b/packages/redgeometry/src/utility/hash.ts index 9127572..8dfc196 100644 --- a/packages/redgeometry/src/utility/hash.ts +++ b/packages/redgeometry/src/utility/hash.ts @@ -15,7 +15,7 @@ export class Hash { return 0.5 * (x + y) * (x + y + 1) + y; } - public static fromNumbers(...numbers: number[]): number { + public static fromNumbers(...numbers: ReadonlyArray): number { let hash = 0; for (let i = 0; i < numbers.length; i++) { diff --git a/packages/redgeometry/src/utility/set.ts b/packages/redgeometry/src/utility/set.ts index 99641f6..381b087 100644 --- a/packages/redgeometry/src/utility/set.ts +++ b/packages/redgeometry/src/utility/set.ts @@ -16,7 +16,7 @@ export class Bitset { return new Bitset(data); } - public static fromBits(bits: number[]): Bitset { + public static fromBits(bits: ReadonlyArray): Bitset { const maxIdx = Math.max(...bits) >>> 5; const data = new Uint32Array(maxIdx + 1);