// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved. // This code can only be used under the standard Unity Asset Store End User License Agreement // A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms using System; using UnityEngine; using UnityEngine.Events; namespace Doozy.Runtime.Signals { /// Specialized class that connects to a signal stream to receive signals [Serializable] public class SignalReceiver : ISignalReceiver { /// Stream connection mode [SerializeField] private StreamConnection ConnectionMode; /// Signal provider id [SerializeField] private ProviderId SignalProviderId; /// Signal provider reference [SerializeField] private SignalProvider ProviderReference; /// Stream id [SerializeField] private StreamId StreamId; /// UnityAction triggered whenever a signal is sent though the stream this receiver is connected to public UnityAction onSignal { get; set; } /// Stream connection mode public StreamConnection streamConnection { get => ConnectionMode; protected internal set => ConnectionMode = value; } /// Signal provider id public ProviderId providerId { get => SignalProviderId; protected internal set => SignalProviderId = value; } /// Signal provider reference public SignalProvider providerReference { get => ProviderReference; protected internal set => ProviderReference = value; } /// Stream id public StreamId streamId { get => StreamId; protected internal set => StreamId = value; } /// Stream id public GameObject signalSource { get; protected internal set; } public SignalStream stream { get; private set; } public bool isConnected { get; private set; } public bool isDisconnecting { get; private set; } public SignalReceiver() { Reset(); } public ISignalReceiver Reset() { ConnectionMode = StreamConnection.None; SignalProviderId = new ProviderId(); ProviderReference = null; StreamId = new StreamId(); signalSource = null; stream = null; isConnected = false; isDisconnecting = false; return this; } public virtual void OnSignal(Signal signal) => onSignal?.Invoke(signal); public void Connect() { if (!Application.isPlaying) { Disconnect(); return; } if (isConnected) return; switch (streamConnection) { case StreamConnection.None: return; case StreamConnection.ProviderId: providerReference = (SignalProvider)SignalsService.GetProvider(providerId, signalSource); if (providerReference == null) { Debug.Log("Provider not found!"); return; } if (!providerReference.isConnected) providerReference.OpenStream(); stream = providerReference.stream; break; case StreamConnection.ProviderReference: if (providerReference == null) { Debug.Log("Provider not referenced!"); return; } if (!providerReference.isConnected) providerReference.OpenStream(); stream = providerReference.stream; break; case StreamConnection.StreamId: if (streamId.Category.Equals(SignalStream.k_DefaultCategory) || streamId.Name.Equals(SignalStream.k_DefaultName)) { Debug.Log($"Will not connect to {streamId.Category} > {streamId.Name}"); return; } stream = SignalsService.GetStream(streamId.Category, streamId.Name); break; default: throw new ArgumentOutOfRangeException(); } if (stream == null) //ToDo: check this particular case when the stream is null { return; } stream.ConnectReceiver(this); streamId.SetStream(stream); isConnected = true; } public void Disconnect() { if (!isConnected) return; SignalStream streamReference = stream; stream = null; isConnected = false; streamReference.DisconnectReceiver(this); } } public static class SignalReceiverExtensions { public static T SetStreamConnection(this T target, StreamConnection streamConnection) where T : SignalReceiver { target.streamConnection = streamConnection; return target; } public static T SetProviderId(this T target, ProviderId providerId, bool updateStreamConnection = true) where T : SignalReceiver { target.providerId = providerId; return updateStreamConnection ? target.SetStreamConnection(StreamConnection.ProviderId) : target; } public static T SetProviderReference(this T target, SignalProvider providerReference, bool updateStreamConnection = true) where T : SignalReceiver { target.providerReference = providerReference; return updateStreamConnection ? target.SetStreamConnection(StreamConnection.ProviderReference) : target; } public static T SetStreamId(this T target, StreamId streamId, bool updateStreamConnection = true) where T : SignalReceiver { target.streamId = streamId; return updateStreamConnection ? target.SetStreamConnection(StreamConnection.StreamId) : target; } public static T SetStreamId(this T target, string category, string name, bool updateStreamConnection = true) where T : SignalReceiver { target.streamId = new StreamId(category, name); return updateStreamConnection ? target.SetStreamConnection(StreamConnection.StreamId) : target; } public static T SetSignalSource(this T target, GameObject signalSource) where T : SignalReceiver { if (target.isConnected) return target; target.signalSource = signalSource; return target; } public static T SetOnSignalCallback(this T target, UnityAction callback) where T : SignalReceiver { target.onSignal = callback; return target; } public static T AddOnSignalCallback(this T target, UnityAction callback) where T : SignalReceiver { target.onSignal += callback; return target; } public static T RemoveOnSignalCallback(this T target, UnityAction callback) where T : SignalReceiver { target.onSignal -= callback; return target; } public static T ClearOnSignalCallback(this T target) where T : SignalReceiver { target.onSignal = null; return target; } } }