Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
erkerkiii committed Feb 15, 2023
2 parents 3ce5afe + c5527d6 commit 12851a8
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 2 deletions.
28 changes: 28 additions & 0 deletions Gum.Composer/Unity/Runtime/MonoComposable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#if UNITY_2019_1_OR_NEWER
using UnityEngine;

namespace Gum.Composer.Unity.Runtime
{
public abstract class MonoComposable : MonoBehaviour, IComposable
{
public Composition Composition { get; protected set; }

protected virtual void Awake()
{
Composition = Composition.Create(GetAspects());
}

public Composition GetComposition()
{
return Composition;
}

protected virtual void OnDestroy()
{
Composition.Dispose();
}

protected abstract IAspect[] GetAspects();
}
}
#endif
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Add this to the ```Packages\manifest.json```
Dependencies
```
"dependencies": {
"com.erkerkiii.gum": "1.0.8"
"com.erkerkiii.gum": "1.0.11"
}
```

Expand Down Expand Up @@ -218,6 +218,24 @@ public void UseAspects(IComposable composable)
}
```

### MonoComposable

Composition are also available on Unity `MonoBehaviours `. Deriving from the abstract `MonoComposable` class enables using composition on Unity objects. `MonoComposable` class handles creation of composable, deriving classes only responsible for implementing the `GetAspects()` absrtact method to assign aspects.

```CSharp
public class FooMonoComposable : MonoComposable
{
private int _value = 12;

protected override IAspect[] GetAspects() // Deriving class implements GetAspects method.
{
IAspect[] aspects = ArrayPool<IAspect>.GetPool(1).Get();
aspects[0] = new FooAspect(_value);
return aspects;
}
}
```

### Other usages
```CSharp
composition
Expand Down Expand Up @@ -285,4 +303,4 @@ private void Bar(FooSignal fooSignal)
signalCenter.Subscribe<FooSignal>(Action); //to subscribe
signalCenter.Unsubscribe<FooSignal>(Action); //to unsubscribe
signalCenter.Fire(new FooSignal()); //to fire signals
```
```
20 changes: 20 additions & 0 deletions Tests/CompositionTests/Unity/FooMonoComposable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#if UNITY_2019_1_OR_NEWER
using Gum.Composer;
using Gum.Composer.Unity.Runtime;
using Gum.Pooling;

namespace Tests.CompositionTests.Unity
{
public class FooMonoComposable : MonoComposable
{
private int _value = 12;

protected override IAspect[] GetAspects()
{
IAspect[] aspects = ArrayPool<IAspect>.GetPool(1).Get();
aspects[0] = new FooAspect(_value);
return aspects;
}
}
}
#endif
130 changes: 130 additions & 0 deletions Tests/CompositionTests/Unity/MonoComposableTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#if UNITY_2019_1_OR_NEWER
using Gum.Composer;
using Gum.Composer.Exception;
using Gum.Composer.Unity.Runtime;
using NUnit.Framework;
using UnityEngine;

namespace Tests.CompositionTests.Unity
{
public class MonoComposableTests
{
private MonoComposable _mockMonoComposable;

private const int VALUE = 12;

[SetUp]
public void SetUp()
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
FooMonoComposable fooMonoComposable = cube.AddComponent<FooMonoComposable>();
_mockMonoComposable = fooMonoComposable;
}

[Test]
public void Add_Aspect_To_MonoComposable()
{
Assert.IsFalse(_mockMonoComposable.Composition.HasAspect(BarAspect.ASPECT_TYPE));

_mockMonoComposable.Composition.AddAspect(new BarAspect(VALUE));

Assert.IsTrue(_mockMonoComposable.Composition.HasAspect(BarAspect.ASPECT_TYPE));
}

[Test]
public void MonoComposable_Has_Aspect()
{
Assert.IsTrue(_mockMonoComposable.Composition.HasAspect(FooAspect.ASPECT_TYPE));
}

[Test]
public void Get_Aspect_From_MonoComposable()
{
FooAspect fooAspect = _mockMonoComposable.Composition.GetAspect<FooAspect>();
Assert.AreEqual(VALUE, fooAspect.MyInt);
}

[Test]
public void Try_Get_Aspect_From_MonoComposable()
{
Assert.IsTrue(_mockMonoComposable.Composition.TryGetAspect(out FooAspect fooAspect));
Assert.AreEqual(VALUE, fooAspect.MyInt);
Assert.IsFalse(_mockMonoComposable.Composition.TryGetAspect(out BarAspect _));
}

[Test]
public void Get_Aspect_Fluent()
{
_mockMonoComposable.Composition.GetAspectFluent(out FooAspect fooAspect);

Assert.AreEqual(VALUE, fooAspect.MyInt);
}

[Test]
public void Get_Aspect_With_Indexer()
{
_mockMonoComposable.Composition.AddAspect(new BarAspect(VALUE));
BarAspect barAspect = (BarAspect)_mockMonoComposable.Composition[BarAspect.ASPECT_TYPE];

Assert.IsNotNull(barAspect);
Assert.AreEqual(VALUE, barAspect.MyInt);
}

[Test]
public void Set_Aspect()
{
FooAspect fooAspect = _mockMonoComposable.Composition.GetAspect<FooAspect>();

Assert.AreEqual(VALUE, fooAspect.MyInt);

const int newValue = 20;
_mockMonoComposable.Composition.SetAspect(new FooAspect(newValue));
Assert.AreEqual(newValue, _mockMonoComposable.Composition.GetAspect<FooAspect>().MyInt);
Assert.AreEqual(1, _mockMonoComposable.Composition.AspectCount);
}

[Test]
public void Set_Non_Existing_Aspect()
{
Assert.IsFalse(_mockMonoComposable.Composition.HasAspect(BarAspect.ASPECT_TYPE));

const int newValue = 20;
_mockMonoComposable.Composition.SetAspect(new BarAspect(newValue));

Assert.AreEqual(newValue, _mockMonoComposable.Composition.GetAspect<BarAspect>().MyInt);
Assert.AreEqual(VALUE, _mockMonoComposable.Composition.GetAspect<FooAspect>().MyInt);

Assert.AreEqual(2, _mockMonoComposable.Composition.AspectCount);
}

[Test]
public void Remove_Aspect()
{
Assert.IsTrue(_mockMonoComposable.Composition.HasAspect(FooAspect.ASPECT_TYPE));

_mockMonoComposable.Composition.RemoveAspect(FooAspect.ASPECT_TYPE);

Assert.IsFalse(_mockMonoComposable.Composition.HasAspect(FooAspect.ASPECT_TYPE));
}

[Test]
public void Enumerator()
{
_mockMonoComposable.Composition.AddAspect(new BarAspect(VALUE));

foreach (IAspect aspect in _mockMonoComposable.Composition)
{
Assert.IsTrue(aspect is BarAspect || aspect is FooAspect);
}

Assert.Pass();
}

[TearDown]
public void TearDown()
{
Object.Destroy(_mockMonoComposable.gameObject);
}
}
}
#endif

0 comments on commit 12851a8

Please sign in to comment.