Skip to content

Commit

Permalink
feat(Event): add gameobject relations event proxy emitter
Browse files Browse the repository at this point in the history
The GameObjectRelationsEventProxyEmitter makes it possible to proxy
events containing the GameObjectRelations Payload.
  • Loading branch information
thestonefox committed Apr 30, 2023
1 parent 883cf7d commit d1d8c2e
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 0 deletions.
66 changes: 66 additions & 0 deletions Runtime/Event/Proxy/GameObjectRelationEventProxyEmitter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
namespace Zinnia.Event.Proxy
{
using System;
using UnityEngine;
using UnityEngine.Events;
using Zinnia.Data.Collection.List;

/// <summary>
/// Emits a <see cref="UnityEvent"/> with a <see cref="GameObjectRelationObservableList.Relation"/> payload whenever the <see cref="SingleEventProxyEmitter{TValue,TEvent}.Receive"/> method is called.
/// </summary>
public class GameObjectRelationEventProxyEmitter : RestrictableSingleEventProxyEmitter<GameObjectRelationObservableList.Relation, GameObjectRelationEventProxyEmitter.UnityEvent>
{
/// <summary>
/// The types of <see cref="GameObject"/> that can be used for the rule source.
/// </summary>
public enum RuleSourceType
{
/// <summary>
/// Use the Relation Key as the source for the rule.
/// </summary>
Key,
/// <summary>
/// Use the Relation Value as the target for the rule.
/// </summary>
Value
}

[Tooltip("The source GameObject to apply to the RestrictableSingleEventProxyEmitter.ReceiveValidity.")]
[SerializeField]
private RuleSourceType ruleSource;
/// <summary>
/// The source <see cref="GameObject"/> to apply to the <see cref="RestrictableSingleEventProxyEmitter.ReceiveValidity"/>.
/// </summary>
public RuleSourceType RuleSource
{
get
{
return ruleSource;
}
set
{
ruleSource = value;
}
}

/// <summary>
/// Defines the event with the specified state.
/// </summary>
[Serializable]
public class UnityEvent : UnityEvent<GameObjectRelationObservableList.Relation> { }

/// <inheritdoc />
protected override object GetTargetToCheck()
{
switch (RuleSource)
{
case RuleSourceType.Key:
return Payload != null ? Payload?.Key : null;
case RuleSourceType.Value:
return Payload != null ? Payload?.Value : null;
}

return null;
}
}
}
11 changes: 11 additions & 0 deletions Runtime/Event/Proxy/GameObjectRelationEventProxyEmitter.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

151 changes: 151 additions & 0 deletions Tests/Editor/Event/Proxy/GameObjectRelationEventProxyEmitterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
using Zinnia.Data.Collection.List;
using Zinnia.Event.Proxy;
using Zinnia.Rule;

namespace Test.Zinnia.Event.Proxy
{
using NUnit.Framework;
using Test.Zinnia.Utility.Mock;
using UnityEngine;

public class GameObjectRelationEventProxyEmitterTest
{
private GameObject containingObject;
private GameObjectRelationEventProxyEmitter subject;

[SetUp]
public void SetUp()
{
containingObject = new GameObject("GameObjectRelationEventProxyEmitterTest");
subject = containingObject.AddComponent<GameObjectRelationEventProxyEmitter>();
}

[TearDown]
public void TearDown()
{
Object.DestroyImmediate(containingObject);
}

[Test]
public void Receive()
{
UnityEventListenerMock emittedMock = new UnityEventListenerMock();
subject.Emitted.AddListener(emittedMock.Listen);
GameObject relationKey = new GameObject("GameObjectRelationEventProxyEmitterTest_Key");
GameObject relationValue = new GameObject("GameObjectRelationEventProxyEmitterTest_Value");
GameObjectRelationObservableList.Relation relation = new GameObjectRelationObservableList.Relation();
relation.Key = relationKey;
relation.Value = relationValue;

Assert.IsFalse(emittedMock.Received);
subject.Receive(relation);
Assert.AreEqual(relation, subject.Payload);
Assert.IsTrue(emittedMock.Received);

Object.DestroyImmediate(relationKey);
Object.DestroyImmediate(relationValue);
}

[Test]
public void ReceiveWithRuleRestrictions()
{
UnityEventListenerMock emittedMock = new UnityEventListenerMock();
subject.Emitted.AddListener(emittedMock.Listen);
GameObject validRelationKey = new GameObject("GameObjectRelationEventProxyEmitterTest_Key");
GameObject validRelationValue = new GameObject("GameObjectRelationEventProxyEmitterTest_Value");
GameObjectRelationObservableList.Relation validRelation = new GameObjectRelationObservableList.Relation();
validRelation.Key = validRelationKey;
validRelation.Value = validRelationValue;

GameObject invalidRelationKey = new GameObject("GameObjectRelationEventProxyEmitterTest_Key");
GameObject invalidRelationValue = new GameObject("GameObjectRelationEventProxyEmitterTest_Value");
GameObjectRelationObservableList.Relation invalidRelation = new GameObjectRelationObservableList.Relation();
invalidRelation.Key = invalidRelationKey;
invalidRelation.Value = invalidRelationValue;

ListContainsRule rule = subject.gameObject.AddComponent<ListContainsRule>();
UnityObjectObservableList objects = containingObject.AddComponent<UnityObjectObservableList>();
rule.Objects = objects;

objects.Add(validRelationKey);
subject.ReceiveValidity = new RuleContainer
{
Interface = rule
};

subject.RuleSource = GameObjectRelationEventProxyEmitter.RuleSourceType.Key;

Assert.IsNull(subject.Payload);
Assert.IsFalse(emittedMock.Received);

subject.Receive(validRelation);

Assert.AreEqual(validRelation, subject.Payload);
Assert.IsTrue(emittedMock.Received);

emittedMock.Reset();

Assert.IsFalse(emittedMock.Received);

subject.Receive(invalidRelation);

Assert.AreEqual(validRelation, subject.Payload);
Assert.IsFalse(emittedMock.Received);

Object.DestroyImmediate(validRelationKey);
Object.DestroyImmediate(validRelationValue);
Object.DestroyImmediate(invalidRelationKey);
Object.DestroyImmediate(invalidRelationValue);
}

[Test]
public void ReceiveInactiveGameObject()
{
UnityEventListenerMock emittedMock = new UnityEventListenerMock();
subject.Emitted.AddListener(emittedMock.Listen);
GameObject relationKey = new GameObject("GameObjectRelationEventProxyEmitterTest_Key");
GameObject relationValue = new GameObject("GameObjectRelationEventProxyEmitterTest_Value");
GameObjectRelationObservableList.Relation relation = new GameObjectRelationObservableList.Relation();
relation.Key = relationKey;
relation.Value = relationValue;

subject.gameObject.SetActive(false);

Assert.IsNull(subject.Payload);
Assert.IsFalse(emittedMock.Received);

subject.Receive(relation);

Assert.IsNull(subject.Payload);
Assert.IsFalse(emittedMock.Received);

Object.DestroyImmediate(relationKey);
Object.DestroyImmediate(relationValue);
}

[Test]
public void ReceiveInactiveComponent()
{
UnityEventListenerMock emittedMock = new UnityEventListenerMock();
subject.Emitted.AddListener(emittedMock.Listen);
GameObject relationKey = new GameObject("GameObjectRelationEventProxyEmitterTest_Key");
GameObject relationValue = new GameObject("GameObjectRelationEventProxyEmitterTest_Value");
GameObjectRelationObservableList.Relation relation = new GameObjectRelationObservableList.Relation();
relation.Key = relationKey;
relation.Value = relationValue;

subject.enabled = false;

Assert.IsNull(subject.Payload);
Assert.IsFalse(emittedMock.Received);

subject.Receive(relation);

Assert.IsNull(subject.Payload);
Assert.IsFalse(emittedMock.Received);

Object.DestroyImmediate(relationKey);
Object.DestroyImmediate(relationValue);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d1d8c2e

Please sign in to comment.