UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

92 lines (80 loc) 2.78 kB
import { getParam } from "./engine_utils.js"; const debug = getParam("debugtypes"); declare type Type = new (...args: any[]) => any; class _TypeStore { private _types: Map<string, Type> = new Map(); private _reverseTypes: Map<Type, string> = new Map(); private _lazyLoaders: Map<string, () => Promise<Type>> = new Map(); constructor() { if (debug) console.warn("TypeStore: Created", this); } /** * add a type to the store */ public add(key: string, type: Type) { if (debug) console.warn("ADD TYPE", key); const existing = this._types.get(key); if (!existing) { this._types.set(key, type); this._reverseTypes.set(type, key); } else { if (debug) { if (existing !== type) { console.warn("Type name exists multiple times in your project and may lead to runtime errors:", key) } } } } /** * Register a lazy-loadable type. The loader is called on first use via {@link getAsync}. * Once resolved, the type is cached for synchronous access via {@link get}. */ public addLazy(key: string, loader: () => Promise<Type>) { if (!this._types.has(key)) { this._lazyLoaders.set(key, loader); } } /** * @returns the type for the given key if registered */ public get(key: string): Type | null { return this._types.get(key) || null; } /** * Async version of {@link get} that also resolves lazy-registered types. * After resolving, the type is cached for future synchronous access. */ public async getAsync(key: string): Promise<Type | null> { const existing = this._types.get(key); if (existing) return existing; const loader = this._lazyLoaders.get(key); if (loader) { if (debug) console.warn("LAZY LOAD TYPE", key); const type = await loader(); this.add(key, type); this._lazyLoaders.delete(key); return type; } return null; } /** * @returns the key/name for the given type if registered */ public getKey(type: Type): string | null { return this._reverseTypes.get(type) || null; } } export const $BuiltInTypeFlag = Symbol("BuiltInType"); export const TypeStore = new _TypeStore(); /** * add to a class declaration to automatically register it to the TypeStore (required for HMR right now) * * `@registerType` * * `export class MyType extends Behaviour { ... }` */ export const registerType = function (constructor: Type) { if (!TypeStore.get(constructor.name)) TypeStore.add(constructor.name, constructor); }