Advanced 20 min 22 / 25
Live Demo
Tutorial 18: Plugins: stable lifecycle
Plugins and handlers are public from 1.2.0. The latest registered handler wins; unregister restores the preceding handler. A null result falls back to built-in translation.
Use an existing ComponentType for a typed core node. Registering a custom string in PluginRegistry alone does not widen Node.components or Component.type. Application-specific component schemas need their own adapters.
import { ComponentType, Geometry, GeometryPrimitive, type ComponentHandler, type Plugin } from '@joroya/core';
import * as THREE from 'three';
const handler: ComponentHandler<THREE.Mesh> = {
componentType: ComponentType.Geometry,
create(node) {
const geometry = node.getComponent<Geometry>(ComponentType.Geometry);
if (!geometry || geometry.definition.type !== GeometryPrimitive.Box) return null;
const definition = geometry.definition;
return new THREE.Mesh(new THREE.BoxGeometry(definition.width, definition.height, definition.depth),
new THREE.MeshBasicMaterial({ color: 0xff8844 }));
},
dispose(_node, mesh) {
mesh.geometry.dispose();
for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) material.dispose();
},
};
export const boxPlugin: Plugin = { name: 'custom-box', handlers: [handler] };
// renderer.usePlugin(boxPlugin);
// renderer.removePlugin(boxPlugin);
Handlers run after scene update and before matrix synchronization. advanceScene: false passes zero delta. Handler dispose precedes plugin dispose; the handler owns backend resources.