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();
}
}
}