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.

145 lines (124 loc) 4.89 kB
import { serializable } from "../../engine/engine_serialization_decorator.js"; import { getParam } from "../../engine/engine_utils.js"; import { Behaviour } from "../Component.js"; import { EventList } from "../EventList.js"; const debug = getParam("debugsignals") export class SignalAsset { @serializable() guid!: string; } export class SignalReceiverEvent { @serializable(SignalAsset) signal!: SignalAsset; @serializable(EventList) reaction!: EventList<void>; } /** SignalReceiver is a component that listens for signals and invokes a reaction when a signal is received. * Signals can be added to a signal track on a timeline */ export class SignalReceiver extends Behaviour { private static receivers: { [key: string]: SignalReceiver[] } = {}; static invoke(guid: string) { if (SignalReceiver.receivers[guid]) { const receivers = SignalReceiver.receivers[guid]; if (!receivers) return; for (const rec of receivers) rec.invoke(guid); } } @serializable(SignalReceiverEvent) events?: SignalReceiverEvent[]; /** @internal */ awake(): void { if(debug) console.log("SignalReceiver awake", this); } /** @internal */ onEnable(): void { if (this.events) { for (const evt of this.events) { if (!SignalReceiver.receivers[evt.signal.guid]) SignalReceiver.receivers[evt.signal.guid] = []; SignalReceiver.receivers[evt.signal.guid].push(this); } } } /** @internal */ onDisable(): void { if (this.events) { for (const evt of this.events) { if (SignalReceiver.receivers[evt.signal.guid]) { const idx = SignalReceiver.receivers[evt.signal.guid].indexOf(this); if (idx >= 0) SignalReceiver.receivers[evt.signal.guid].splice(idx, 1); } } } } invoke(sig: SignalAsset | string) { if (!this.events || !Array.isArray(this.events)) return; const id = typeof sig === "object" ? sig.guid : sig; for (const evt of this.events) { if (evt.signal.guid === id) { try { if (!evt.reaction) { console.warn("Missing reaction for signal", evt, this); continue; } else if (!evt.reaction.invoke) { console.warn("Missing invoke - possibly a serialization error", evt, this); continue; } evt.reaction.invoke(); } catch (err) { console.error(err); } } } } // onDeserialize(key: string, value: any): any | void // { // switch(key){ // case "events": // console.log(value); // const evt = eventListSerializer; // for(const e in value){ // } // break; // } // } } // class SignalAssetSerializer extends TypeSerializer { // constructor() { // super("SignalReceiverEvent"); // } // onSerialize(_data: EventList, _context: SerializationContext) { // console.log("TODO: SERIALIZE EVENT"); // return undefined; // } // onDeserialize(data: SignalReceiverEvent, context: SerializationContext): EventList | undefined | null { // console.log("DESERIALIZE", data); // // if (data && data.type === "EventList") { // // console.log("DESERIALIZE EVENT", data); // // const fns = new Array<Function>(); // // for (const call of data.calls) { // // const target = componentSerializer.findObjectForGuid(call.target, context.root); // // let fn; // // if (call.argument) { // // let arg = call.argument; // // if (typeof arg === "object") { // // arg = objectSerializer.onDeserialize(call.argument, context); // // if (!arg) arg = componentSerializer.onDeserialize(call.argument, context); // // } // // fn = () => target[call.method](arg); // // } // // else fn = () => target[call.method](); // // fns.push(fn); // // } // // const evt: EventList = new EventList(fns); // // return evt; // // } // return undefined; // } // } // new SignalAssetSerializer();