namespace Zinnia.Tracking.Collision.Active { using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using Zinnia.Extension; /// /// Holds a collection of consumers that have successfully been published to by a . /// public class ActiveCollisionRegisteredConsumerContainer : MonoBehaviour { /// /// Holds data about a payload. /// [Serializable] public class EventData { [Tooltip("The registered ActiveCollisionConsumer.")] [SerializeField] private ActiveCollisionConsumer consumer; /// /// The registered . /// public ActiveCollisionConsumer Consumer { get { return consumer; } set { consumer = value; } } [Tooltip("The payload data sent to the ActiveCollisionConsumer.")] [SerializeField] private ActiveCollisionPublisher.PayloadData payload; /// /// The payload data sent to the . /// public ActiveCollisionPublisher.PayloadData Payload { get { return payload; } set { payload = value; } } /// /// Clears . /// public virtual void ClearConsumer() { Consumer = default; } /// /// Clears . /// public virtual void ClearPayload() { Payload = default; } public EventData Set(EventData source) { return Set(source.Consumer, source.Payload); } public EventData Set(ActiveCollisionConsumer consumer, ActiveCollisionPublisher.PayloadData payload) { Consumer = consumer; Payload = payload; return this; } /// public override string ToString() { string[] titles = new string[] { "Consumer", "Payload" }; object[] values = new object[] { Consumer, Payload }; return StringExtensions.FormatForToString(titles, values); } public void Clear() { Set(default, default); } } /// /// Defines the event for the output . /// [Serializable] public class UnityEvent : UnityEvent { } /// /// Emitted when each registered consumer payload data is published. /// public ActiveCollisionPublisher.UnityEvent Published = new ActiveCollisionPublisher.UnityEvent(); /// /// Emitted when a consumer is registered. /// public UnityEvent Registered = new UnityEvent(); /// /// Emitted when a consumer is unregistered. /// public UnityEvent Unregistered = new UnityEvent(); /// /// A collection of registered consumers to ignore when publishing. /// public List IgnoredRegisteredConsumers { get; set; } = new List(); /// /// The consumers that have successfully consumed the published payload from the linked to this. /// public Dictionary RegisteredConsumers { get; protected set; } = new Dictionary(); /// /// The event data emitted when collisions are consumed. /// protected readonly EventData eventData = new EventData(); /// /// Publishes the registered components as the component is active and enabled. /// Any that is in the will not be published to and the collection is cleared at the end of the operation. /// public virtual void Publish() { if (!this.IsValidState()) { return; } foreach (ActiveCollisionConsumer registeredConsumer in new List(RegisteredConsumers.Keys)) { if (IgnoredRegisteredConsumers.Contains(registeredConsumer)) { continue; } if (RegisteredConsumers.TryGetValue(registeredConsumer, out ActiveCollisionPublisher.PayloadData payload)) { registeredConsumer.Consume(payload, registeredConsumer.ActiveCollision); Published?.Invoke(payload); } } ClearIgnoredRegisteredConsumers(); } /// /// Registers an . /// /// The consumer to register. /// The payload that the consumer successfully consumed. public virtual void Register(ActiveCollisionConsumer consumer, ActiveCollisionPublisher.PayloadData payload) { if (!this.IsValidState() || consumer == null) { return; } RegisteredConsumers[consumer] = payload; Registered?.Invoke(eventData.Set(consumer, payload)); } /// /// Unregisters an . /// /// The consumer to unregister. public virtual void Unregister(ActiveCollisionConsumer consumer) { if (consumer == null) { return; } RegisteredConsumers.Remove(consumer); IgnoredRegisteredConsumers.Remove(consumer); Unregistered?.Invoke(eventData.Set(consumer, null)); } /// /// Unregisters all components that exist on the given container. /// /// The container to unregister the consumers from. public virtual void UnregisterConsumersOnContainer(GameObject container) { foreach (ActiveCollisionConsumer registeredConsumer in new List(RegisteredConsumers.Keys)) { if (registeredConsumer.ConsumerContainer == container) { Unregister(registeredConsumer); } } } /// /// Clears the collection. /// public virtual void ClearIgnoredRegisteredConsumers() { IgnoredRegisteredConsumers.Clear(); } } }