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.

81 lines (67 loc) 3.31 kB
import { type Constructor } from "./engine_types.js"; export declare type TypeResolver<T> = (data) => Constructor<T> | null; /** Please use {@link serializable} - this version has a typo and will be removed in future versions */ export const serializeable = function <T>(type?: Constructor<T> | null | Array<Constructor<any> | TypeResolver<T>> | TypeResolver<T>) { return serializable(type) } /** * The serializable attribute should be used to annotate all serialized fields / fields and members that should be serialized and exposed in an editor * @param type The type of the field. If not provided the type will be inferred from the constructor of the field. If the field is a primitive type (string, number, boolean) the type should be null. */ export const serializable = function <T>(type?: Constructor<T> | null | Array<Constructor<any> | TypeResolver<T>> | TypeResolver<T>) { if (type === undefined) type = null; // for primitive types the serialization handles it without the constructor and just assigns the value // if the user still passes in a primitive type constructor we can just throw it away :) if (!Array.isArray(type)) { type = setNullForPrimitiveTypes(type); } else { for (let i = 0; i < type.length; i++) { const entry = type[i]; type[i] = setNullForPrimitiveTypes(entry); } } return function (_target: any, _propertyKey: string | { name: string }) { if (!_target) { console.error("Found @serializable decorator without a target"); return; } // The _propertyKey parameter is a string in TS4 with experimentalDecorators // but a ClassFieldDecoratorContext in TS5 without. // Seems when a different TS version is used in VSCode for editor checking, we get errors here // if we don't also check for any. See https://github.com/needle-tools/needle-engine-support/issues/179 if (typeof _propertyKey !== 'string') { _propertyKey = _propertyKey.name; } // this is important so objects with inheritance dont override their serialized type // info if e.g. multiple classes inheriting from the same type implement a member with the same name // and both use @serializable() with different types if (!Object.getOwnPropertyDescriptor(_target, '$serializedTypes')) _target["$serializedTypes"] = {}; const types = _target["$serializedTypes"] = _target["$serializedTypes"] || {} types[_propertyKey] = type; } } function setNullForPrimitiveTypes(type) { switch (type?.prototype?.constructor?.name) { case "Number": case "String": case "Boolean": return null; } return type; } /** @internal */ export const ALL_PROPERTIES_MARKER = "__NEEDLE__ALL_PROPERTIES"; /** @internal @deprecated current not used */ export function allProperties(constructor: Function) { constructor[ALL_PROPERTIES_MARKER] = true; } /** * @internal */ export const STRICT_MARKER = "__NEEDLE__STRICT"; /** @deprecated current not used */ export function strict(constructor: Function) { constructor[STRICT_MARKER] = true; }