From a333d418222972373cc1f9b256def2f79610d3fa Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 2 Feb 2021 09:52:19 +0000 Subject: [PATCH] feat(api): replace Type enum w/ strings consts BREAKING CHANGE: replace Type enum w/ string consts - update Type, UintType, IntType, FloatType aliases - update GL2TYPE, TYPE2GL, SIZEOF, TYPEDARRAY_CTORS tables - add asNativeType(), asGLType() conversions - add sizeOf() - add uintTypeForBits(), intTypeForBits() - update/rename uintTypeForSize(), intTypeForSize() --- packages/api/src/api/typedarray.ts | 217 +++++++++++++++++------------ 1 file changed, 129 insertions(+), 88 deletions(-) diff --git a/packages/api/src/api/typedarray.ts b/packages/api/src/api/typedarray.ts index e9af80ab92..2a04aef8ea 100644 --- a/packages/api/src/api/typedarray.ts +++ b/packages/api/src/api/typedarray.ts @@ -29,29 +29,27 @@ export type TypedArrayConstructor = | Float64ArrayConstructor; /** - * Type enums for Typedarray-backed buffers. + * Type IDs for typed array backed buffers and generally describing binary data + * values. * - * {@link GLType} - * {@link GL2TYPE} - * {@link TYPE2GL} + * {@link GLType} {@link GL2TYPE} {@link TYPE2GL} */ -export enum Type { - U8, - U8C, - I8, - U16, - I16, - U32, - I32, - F32, - F64, -} +export type Type = + | "u8" + | "u8c" + | "i8" + | "u16" + | "i16" + | "u32" + | "i32" + | "f32" + | "f64"; -export type UintType = Type.U8 | Type.U16 | Type.U32; +export type UintType = "u8" | "u16" | "u32"; -export type IntType = Type.I8 | Type.I16 | Type.I32; +export type IntType = "i8" | "i16" | "i32"; -export type FloatType = Type.F32 | Type.F64; +export type FloatType = "f32" | "f64"; /** * WebGL numeric type constants. Use {@link GL2TYPE} to convert, if needed. @@ -74,13 +72,13 @@ export enum GLType { * Conversion from {@link GLType} to {@link Type} enums. */ export const GL2TYPE: Record = { - [GLType.I8]: Type.I8, - [GLType.U8]: Type.U8, - [GLType.I16]: Type.I16, - [GLType.U16]: Type.U16, - [GLType.I32]: Type.I32, - [GLType.U32]: Type.U32, - [GLType.F32]: Type.F32, + [GLType.I8]: "i8", + [GLType.U8]: "u8", + [GLType.I16]: "i16", + [GLType.U16]: "u16", + [GLType.I32]: "i32", + [GLType.U32]: "u32", + [GLType.F32]: "f32", }; /** @@ -89,66 +87,57 @@ export const GL2TYPE: Record = { * Not all enums are mappable: * * - `F64` maps to `undefined`, since unsupported by WebGL - * - `U8C` maps to U8 + * - `U8C` maps to "u8" */ export const TYPE2GL: Record = { - [Type.I8]: GLType.I8, - [Type.U8]: GLType.U8, - [Type.U8C]: GLType.U8, - [Type.I16]: GLType.I16, - [Type.U16]: GLType.U16, - [Type.I32]: GLType.I32, - [Type.I32]: GLType.I32, - [Type.U32]: GLType.U32, - [Type.F32]: GLType.F32, - [Type.F64]: undefined, + i8: GLType.I8, + u8: GLType.U8, + u8c: GLType.U8, + i16: GLType.I16, + u16: GLType.U16, + i32: GLType.I32, + u32: GLType.U32, + f32: GLType.F32, + f64: undefined, }; /** - * Size information (in bytes) for {@link Type} enums. For {@link GLType}, use this - * form, e.g. `SIZEOF[GL2TYPE[GLType.F32]]` + * Size information (in bytes) for {@link Type}. Also see {@link sizeOf}. */ export const SIZEOF = { - [Type.U8]: 1, - [Type.U8C]: 1, - [Type.I8]: 1, - [Type.U16]: 2, - [Type.I16]: 2, - [Type.U32]: 4, - [Type.I32]: 4, - [Type.F32]: 4, - [Type.F64]: 8, + u8: 1, + u8c: 1, + i8: 1, + u16: 2, + i16: 2, + u32: 4, + i32: 4, + f32: 4, + f64: 8, }; -export const TYPEDARRAY_CTORS: Record = { - [Type.U8]: Uint8Array, - [Type.U8C]: Uint8ClampedArray, - [Type.I8]: Int8Array, - [Type.U16]: Uint16Array, - [Type.I16]: Int16Array, - [Type.U32]: Uint32Array, - [Type.I32]: Int32Array, - [Type.F32]: Float32Array, - [Type.F64]: Float64Array, - [GLType.U8]: Uint8Array, - [GLType.I8]: Int8Array, - [GLType.U16]: Uint16Array, - [GLType.I16]: Int16Array, - [GLType.U32]: Uint32Array, - [GLType.I32]: Int32Array, - [GLType.F32]: Float32Array, +export const TYPEDARRAY_CTORS: Record = { + u8: Uint8Array, + u8c: Uint8ClampedArray, + i8: Int8Array, + u16: Uint16Array, + i16: Int16Array, + u32: Uint32Array, + i32: Int32Array, + f32: Float32Array, + f64: Float64Array, }; export interface TypedArrayTypeMap extends Record { - [Type.U8]: Uint8Array; - [Type.U8C]: Uint8ClampedArray; - [Type.I8]: Int8Array; - [Type.U16]: Uint16Array; - [Type.I16]: Int16Array; - [Type.U32]: Uint32Array; - [Type.I32]: Int32Array; - [Type.F32]: Float32Array; - [Type.F64]: Float64Array; + u8: Uint8Array; + u8c: Uint8ClampedArray; + i8: Int8Array; + u16: Uint16Array; + i16: Int16Array; + u32: Uint32Array; + i32: Int32Array; + f32: Float32Array; + f64: Float64Array; [GLType.U8]: Uint8Array; [GLType.I8]: Int8Array; [GLType.U16]: Uint16Array; @@ -158,6 +147,46 @@ export interface TypedArrayTypeMap extends Record { [GLType.F32]: Float32Array; } +/** + * Returns canonical {@link Type} value of `type` by first + * attempting to resolve it as {@link GLType} enum. + * + * @example + * ```ts + * asNativeType(GLType.F32) => "f32" + * asNativeType("f32") => "f32" + * ``` + * + * @param type - + */ +export const asNativeType = (type: GLType | Type): Type => { + const t = (GL2TYPE)[type]; + return t !== undefined ? t : type; +}; + +/** + * Returns suitable {@link GLType} enum of `type`. + * + * @example + * ```ts + * asGLType("f32") => GLType.F32 + * asGLType(GLType.F32) => GLType.F32 + * ``` + * + * @param type - + */ +export const asGLType = (type: GLType | Type): GLType => { + const t = (TYPE2GL)[type]; + return t !== undefined ? t : type; +}; + +/** + * Returns byte size for given {@link Type} ID or {@link GLType} enum. + * + * @param type + */ +export const sizeOf = (type: GLType | Type) => SIZEOF[asNativeType(type)]; + /** * Constructs new typed array of given {@link Type}/{@link GLType}. Supports all * arities of standard typed array ctors. @@ -171,41 +200,53 @@ export function typedArray(type: T, src: ArrayLike(type: T, buf: ArrayBufferLike, byteOffset: number, length?: number): TypedArrayTypeMap[T]; export function typedArray(type: T, ...xs: any[]) { - return new (TYPEDARRAY_CTORS[type])(...xs); + return new (TYPEDARRAY_CTORS[asNativeType(type)])(...xs); } /** * Takes an {@link NumericArray} and returns its corresponding {@link Type} ID. - * Standard JS arrays will default to {@link Type.F64}. + * Standard JS arrays will default to {@link "f64"}. * * @param x */ export const typedArrayType = (x: NumericArray) => { - if (Array.isArray(x)) return Type.F64; + if (Array.isArray(x)) return "f64"; for (let id in TYPEDARRAY_CTORS) { - if (x instanceof (TYPEDARRAY_CTORS)[id]) return Number(id); + if (x instanceof (TYPEDARRAY_CTORS)[id]) return id; } - return Type.F64; + return "f64"; }; /** * Returns the smallest possible *unsigned* int type enum for given `x`. - * E.g. if `x <= 256`, the function returns `Type.U8`. + * E.g. if `x <= 256`, the function returns `"u8"`. * * @param x - value to classify */ -export const uintType = (x: number): UintType => - x <= 0x100 ? Type.U8 : x <= 0x10000 ? Type.U16 : Type.U32; +export const uintTypeForSize = (x: number): UintType => + x <= 0x100 ? "u8" : x <= 0x10000 ? "u16" : "u32"; /** * Returns the smallest possible *signed* int type enum for given `x`. - * E.g. if `x >= -128 && x < 128`, the function returns `Type.I8`. + * E.g. if `x >= -128 && x < 128`, the function returns `"i8"`. * * @param x - value to classify */ -export const intType = (x: number): IntType => - x >= -0x80 && x < 0x80 - ? Type.I8 - : x >= -0x8000 && x < 0x8000 - ? Type.I16 - : Type.I32; +export const intTypeForSize = (x: number): IntType => + x >= -0x80 && x < 0x80 ? "i8" : x >= -0x8000 && x < 0x8000 ? "i16" : "i32"; + +/** + * Returns suitable {@link UintType} for given bit size (`[0,32]` range) + * + * @param x + */ +export const uintTypeForBits = (x: number): UintType => + x > 16 ? "u32" : x > 8 ? "u16" : "u8"; + +/** + * Returns suitable {@link IntType} for given bit size (`[0,32]` range) + * + * @param x + */ +export const intTypeForBits = (x: number): IntType => + x > 16 ? "i32" : x > 8 ? "i16" : "i8";