@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
text/typescript
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 {
guid!: string;
}
export class SignalReceiverEvent {
signal!: SignalAsset;
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);
}
}
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();