@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.
94 lines • 3.55 kB
JavaScript
/** Please use {@link serializable} - this version has a typo and will be removed in future versions */
export const serializeable = function (type) {
return serializable(type);
};
/**
* Marks a field for serialization and editor exposure. Required for fields that reference
* other objects, components, or assets. Primitive types (string, number, boolean) work without a type argument.
*
* @param type The constructor type for complex objects. Omit for primitives.
*
* @example Primitive types (no type needed)
* ```ts
* @serializable()
* speed: number = 1;
*
* @serializable()
* label: string = "Hello";
* ```
* @example Object references
* ```ts
* @serializable(Object3D)
* target: Object3D | null = null;
*
* @serializable(Renderer)
* myRenderer: Renderer | null = null;
* ```
* @example Arrays
* ```ts
* @serializable([Object3D])
* waypoints: Object3D[] = [];
* ```
* @see {@link syncField} for automatic network synchronization
* @link https://engine.needle.tools/docs/reference/typescript-decorators.html#serializable
*/
export const serializable = function (type) {
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, _propertyKey) {
if (!_target) {
const propertyName = typeof _propertyKey === 'string' ? _propertyKey : _propertyKey.name;
console.warn(`@serializable without a target at '${propertyName}'.`);
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) {
constructor[ALL_PROPERTIES_MARKER] = true;
}
/**
* @internal
*/
export const STRICT_MARKER = "__NEEDLE__STRICT";
/** @deprecated current not used */
export function strict(constructor) {
constructor[STRICT_MARKER] = true;
}
//# sourceMappingURL=engine_serialization_decorator.js.map