rc-js-util
Version:
A collection of TS and C++ utilities to help writing performant and correct applications, achieved through strict typing and (removable) invariant checking.
182 lines • 7.21 kB
JavaScript
import { SharedBufferView } from "../web-assembly/shared-memory/shared-buffer-view.js";
import { _Debug } from "../debug/_debug.js";
import { numberGetHexString } from "../number/impl/number-get-hex-string.js";
/**
* @public
* Matches ENumberIdentifier in `RTTI.hpp`.
*/
export var ENumberIdentifier;
(function (ENumberIdentifier) {
ENumberIdentifier[ENumberIdentifier["U8"] = 0] = "U8";
ENumberIdentifier[ENumberIdentifier["U16"] = 1] = "U16";
ENumberIdentifier[ENumberIdentifier["U32"] = 2] = "U32";
ENumberIdentifier[ENumberIdentifier["U64"] = 3] = "U64";
ENumberIdentifier[ENumberIdentifier["I8"] = 4] = "I8";
ENumberIdentifier[ENumberIdentifier["I16"] = 5] = "I16";
ENumberIdentifier[ENumberIdentifier["I32"] = 6] = "I32";
ENumberIdentifier[ENumberIdentifier["I64"] = 7] = "I64";
ENumberIdentifier[ENumberIdentifier["F32"] = 8] = "F32";
ENumberIdentifier[ENumberIdentifier["F64"] = 9] = "F64";
})(ENumberIdentifier || (ENumberIdentifier = {}));
/**
* @public
* Given a typed array constructor, get the identifier which matches up with ENumberIdentifier in `RTTI.hpp`.
*/
export function getNumberIdentifier(ctor) {
return numberIdentifierMapping.get(ctor);
}
const numberIdentifierMapping = new Map([
[Uint8Array, ENumberIdentifier.U8],
[Uint16Array, ENumberIdentifier.U16],
[Uint32Array, ENumberIdentifier.U32],
[BigUint64Array, ENumberIdentifier.U64],
[Int8Array, ENumberIdentifier.I8],
[Int16Array, ENumberIdentifier.I16],
[Int32Array, ENumberIdentifier.I32],
[BigInt64Array, ENumberIdentifier.I64],
[Float32Array, ENumberIdentifier.F32],
[Float64Array, ENumberIdentifier.F64],
]);
/**
* @public
* Mirrors the C++ class of the same name. This can be used as a key to get a unique number which can be matched on the C++ side.
*/
export class StableId {
constructor(name) {
this.name = name;
}
}
/**
* @public
* Mirrors the C++ class of the same name. Each category can have multiple kinds of specializations.
*
* @remarks There should only be one instance of a conceptual class (which should have a unique name)
*/
export class IdCategory extends StableId {
}
/**
* @public
* Mirrors the C++ class of the same name. A specialization of a conceptual category. E.g. a number (category) which is a float 32 (specialization).
*
* @remarks There should only be one instance of a conceptual class (which should have a unique name)
*/
export class IdSpecialization extends StableId {
constructor(category, specializationName) {
super(specializationName);
this.category = category;
}
}
/**
* @public
* Supported types of number across C++ and JavaScript.
*/
export const numberCategory = new IdCategory("JSU_NUMBER");
/**
* @public
* A buffer that can be shared with C++.
*/
export const bufferCategory = new IdCategory("JSU_BUFFER");
/**
* @public
* Given a Typed array constructor, get back the associated {@link StableId}.
*/
export function getNumberSpecialization(ctor) {
return numberSpecializationMapping.get(ctor);
}
/**
* @public
* {@link IdSpecialization} for all supported number types.
*/
export const numberSpecializations = new class NumberSpecializations {
constructor() {
this.u8 = new IdSpecialization(numberCategory, "JSU_U8");
this.u16 = new IdSpecialization(numberCategory, "JSU_U16");
this.u32 = new IdSpecialization(numberCategory, "JSU_U32");
this.u64 = new IdSpecialization(numberCategory, "JSU_U64");
this.i8 = new IdSpecialization(numberCategory, "JSU_I8");
this.i16 = new IdSpecialization(numberCategory, "JSU_I16");
this.i32 = new IdSpecialization(numberCategory, "JSU_I32");
this.i64 = new IdSpecialization(numberCategory, "JSU_I64");
this.f32 = new IdSpecialization(numberCategory, "JSU_F32");
this.f64 = new IdSpecialization(numberCategory, "JSU_F64");
}
}();
const numberSpecializationMapping = new Map([
[Uint8Array, numberSpecializations.u8],
[Uint16Array, numberSpecializations.u16],
[Uint32Array, numberSpecializations.u32],
[BigUint64Array, numberSpecializations.u64],
[Int8Array, numberSpecializations.i8],
[Int16Array, numberSpecializations.i16],
[Int32Array, numberSpecializations.i32],
[BigInt64Array, numberSpecializations.i64],
[Float32Array, numberSpecializations.f32],
[Float64Array, numberSpecializations.f64],
]);
/**
* @internal
*/
export function populateTypedArrayConstructorMap(constructors) {
const m = new Map();
m.set(Float64Array, constructors.f64);
m.set(Float32Array, constructors.f32);
if (constructors.i64 != null) {
m.set(BigInt64Array, constructors.i64);
}
if (constructors.u64 != null) {
m.set(BigUint64Array, constructors.u64);
}
m.set(Int32Array, constructors.i32);
m.set(Uint32Array, constructors.u32);
m.set(Int16Array, constructors.i16);
m.set(Uint16Array, constructors.u16);
m.set(Int8Array, constructors.i8);
m.set(Uint8Array, constructors.u8);
m.set(Uint8ClampedArray, constructors.u8c);
return m;
}
/**
* @public
* {@inheritDoc IStableStore}
*/
export class StableIdStore {
constructor(wrapper) {
this.wrapper = wrapper;
this.ids = new Map();
/**
* @internal
*/
this.idBuffer = null;
}
initialize() {
this.idBuffer = new SharedBufferView(this.wrapper, this.wrapper.rootNode, Uint16Array, this.wrapper.instance._jsUtilGetRuntimeMappingAddress(), 32 * Uint16Array.BYTES_PER_ELEMENT);
}
getId(key) {
let id = this.ids.get(key);
if (id == null) {
const namePtr = this.wrapper.instance.stringToNewUTF8(key.name);
if (_BUILD.DEBUG) {
_Debug.verboseLog(["WASM", "MEMORY", "ALLOCATIONS"], `StableIdStore: created temporary string at ${numberGetHexString(namePtr)} (${key.name}).`);
}
id = this.wrapper.instance._jsUtilGetRuntimeMappingId(namePtr);
this.ids.set(key, id);
this.wrapper.instance._jsUtilFree(namePtr);
}
return id;
}
setSpecializations(sharedObjectHandle, specializations) {
_BUILD.DEBUG && _Debug.assert(this.idBuffer != null, "attempted to set ids before initialization happened...");
_BUILD.DEBUG && _Debug.assert(specializations.length <= 32, "a maximum of 32 specializations can be added at one time");
const idBuffer = this.idBuffer.getArray(); // [[category, specialization], ...]
for (let i = 0, iEnd = specializations.length; i < iEnd; i++) {
const specialization = specializations[i];
idBuffer[i * 2] = this.getId(specialization);
idBuffer[i * 2 + 1] = this.getId(specialization.category);
}
this.wrapper.instance._jsUtilAddRuntimeMappings(specializations.length, sharedObjectHandle.pointer);
}
hasId(sharedObjectHandle, specialization) {
return Boolean(this.wrapper.instance._jsUtilHasRuntimeMappingId(sharedObjectHandle.pointer, this.getId(specialization.category), this.getId(specialization)));
}
}
//# sourceMappingURL=rtti-interop.js.map