namespace Zinnia.Tracking.Collision.Active
{
using System;
using UnityEngine;
using UnityEngine.Events;
using Zinnia.Extension;
using Zinnia.Rule;
///
/// Consumes a published .
///
public class ActiveCollisionConsumer : MonoBehaviour
{
///
/// Holds data about a event.
///
[Serializable]
public class EventData
{
[Tooltip("The publisher payload data that is being pushed to the consumer.")]
[SerializeField]
private ActiveCollisionPublisher.PayloadData publisher;
///
/// The publisher payload data that is being pushed to the consumer.
///
public ActiveCollisionPublisher.PayloadData Publisher
{
get
{
return publisher;
}
set
{
publisher = value;
}
}
[Tooltip("The current collision data.")]
[SerializeField]
private CollisionNotifier.EventData currentCollision;
///
/// The current collision data.
///
public CollisionNotifier.EventData CurrentCollision
{
get
{
return currentCollision;
}
set
{
currentCollision = value;
}
}
///
/// Clears .
///
public virtual void ClearPublisher()
{
Publisher = default;
}
///
/// Clears .
///
public virtual void ClearCurrentCollision()
{
CurrentCollision = default;
}
public EventData Set(EventData source)
{
return Set(source.Publisher, source.CurrentCollision);
}
public EventData Set(ActiveCollisionPublisher.PayloadData publisher, CollisionNotifier.EventData currentCollision)
{
Publisher = publisher;
CurrentCollision = currentCollision;
return this;
}
///
public override string ToString()
{
string[] titles = new string[]
{
"Publisher",
"CurrentCollision"
};
object[] values = new object[]
{
Publisher,
CurrentCollision
};
return StringExtensions.FormatForToString(titles, values);
}
public void Clear()
{
Set(default, default);
}
}
///
/// Defines the event with the .
///
[Serializable]
public class UnityEvent : UnityEvent { }
[Tooltip("The highest level container of the consumer to allow for nested consumers.")]
[SerializeField]
private GameObject container;
///
/// The highest level container of the consumer to allow for nested consumers.
///
public GameObject Container
{
get
{
return container;
}
set
{
container = value;
}
}
[Tooltip("Determines whether to consume the received call from specific publishers.")]
[SerializeField]
private RuleContainer publisherValidity;
///
/// Determines whether to consume the received call from specific publishers.
///
public RuleContainer PublisherValidity
{
get
{
return publisherValidity;
}
set
{
publisherValidity = value;
}
}
///
/// The publisher payload that was last received from.
///
public ActiveCollisionPublisher.PayloadData PublisherSource { get; protected set; }
///
/// The current active collision data from the broadcaster.
///
public CollisionNotifier.EventData ActiveCollision { get; protected set; }
///
/// The current highest level container of the consumer to allow for nested consumers.
///
public GameObject ConsumerContainer { get; protected set; }
///
/// Emitted when the publisher call has been consumed.
///
public UnityEvent Consumed = new UnityEvent();
///
/// Emitted when the consumer is cleared.
///
public UnityEvent Cleared = new UnityEvent();
///
/// The event data emitted when collisions are consumed.
///
protected readonly EventData eventData = new EventData();
///
/// Clears .
///
public virtual void ClearContainer()
{
if (!this.IsValidState())
{
return;
}
Container = default;
}
///
/// Clears .
///
public virtual void ClearPublisherValidity()
{
if (!this.IsValidState())
{
return;
}
PublisherValidity = default;
}
///
/// Consumes data from a from a .
///
/// The publisher payload data.
/// The current collision within published data.
/// Whether the consumption was allowed and successful.
public virtual bool Consume(ActiveCollisionPublisher.PayloadData publisherPayload, CollisionNotifier.EventData currentCollision)
{
if (!this.IsValidState() || !PublisherValidity.Accepts(publisherPayload.PublisherContainer))
{
return false;
}
PublisherSource = publisherPayload;
ActiveCollision = currentCollision;
ConsumerContainer = currentCollision != null ? currentCollision.ColliderData.GetContainingTransform().TryGetGameObject() : null;
Consumed?.Invoke(eventData.Set(PublisherSource, currentCollision));
return true;
}
///
/// Clears the previously consumed data.
///
public virtual void Clear()
{
if (!this.IsValidState())
{
return;
}
if (PublisherSource != null && PublisherSource.Publisher != null)
{
PublisherSource.Publisher.UnregisterRegisteredConsumer(this);
}
Cleared?.Invoke(eventData.Set(PublisherSource, ActiveCollision));
PublisherSource = null;
ActiveCollision = null;
}
}
}