var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
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");
/**
 * Used to reference a signal asset in a SignalReceiver. This is internally used by the {@link SignalReceiverEvent}.
 */
export class SignalAsset {
    guid;
}
__decorate([
    serializable()
], SignalAsset.prototype, "guid", void 0);
/**
 * An event that links a signal to a reaction.
 * Used internally by {@link SignalReceiver}.
 */
export class SignalReceiverEvent {
    signal;
    reaction;
}
__decorate([
    serializable(SignalAsset)
], SignalReceiverEvent.prototype, "signal", void 0);
__decorate([
    serializable(EventList)
], SignalReceiverEvent.prototype, "reaction", void 0);
/** 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 {@link PlayableDirector}
 *
 * @summary Receives signals and invokes reactions
 * @category Sequencing and Timelines
 * @group Components
 */
export class SignalReceiver extends Behaviour {
    static receivers = {};
    static invoke(guid) {
        if (SignalReceiver.receivers[guid]) {
            const receivers = SignalReceiver.receivers[guid];
            if (!receivers)
                return;
            for (const rec of receivers)
                rec.invoke(guid);
        }
    }
    events;
    /** @internal */
    awake() {
        if (debug)
            console.log("SignalReceiver awake", this);
    }
    /** @internal */
    onEnable() {
        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() {
        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) {
        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);
                }
            }
        }
    }
}
__decorate([
    serializable(SignalReceiverEvent)
], SignalReceiver.prototype, "events", void 0);
// 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();
//# sourceMappingURL=SignalAsset.js.map