Skip to content

Commit c5527d6

Browse files
authored
Merge pull request #9 from semihcelek/feature/mono-composable-for-monobehaviours
MonoComposable Implementation
2 parents 9df70c7 + cc7ca42 commit c5527d6

File tree

4 files changed

+196
-0
lines changed

4 files changed

+196
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#if UNITY_2019_1_OR_NEWER
2+
using UnityEngine;
3+
4+
namespace Gum.Composer.Unity.Runtime
5+
{
6+
public abstract class MonoComposable : MonoBehaviour, IComposable
7+
{
8+
public Composition Composition { get; protected set; }
9+
10+
protected virtual void Awake()
11+
{
12+
Composition = Composition.Create(GetAspects());
13+
}
14+
15+
public Composition GetComposition()
16+
{
17+
return Composition;
18+
}
19+
20+
protected virtual void OnDestroy()
21+
{
22+
Composition.Dispose();
23+
}
24+
25+
protected abstract IAspect[] GetAspects();
26+
}
27+
}
28+
#endif

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,24 @@ public void UseAspects(IComposable composable)
218218
}
219219
```
220220

221+
### MonoComposable
222+
223+
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.
224+
225+
```CSharp
226+
public class FooMonoComposable : MonoComposable
227+
{
228+
private int _value = 12;
229+
230+
protected override IAspect[] GetAspects() // Deriving class implements GetAspects method.
231+
{
232+
IAspect[] aspects = ArrayPool<IAspect>.GetPool(1).Get();
233+
aspects[0] = new FooAspect(_value);
234+
return aspects;
235+
}
236+
}
237+
```
238+
221239
### Other usages
222240
```CSharp
223241
composition
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#if UNITY_2019_1_OR_NEWER
2+
using Gum.Composer;
3+
using Gum.Composer.Unity.Runtime;
4+
using Gum.Pooling;
5+
6+
namespace Tests.CompositionTests.Unity
7+
{
8+
public class FooMonoComposable : MonoComposable
9+
{
10+
private int _value = 12;
11+
12+
protected override IAspect[] GetAspects()
13+
{
14+
IAspect[] aspects = ArrayPool<IAspect>.GetPool(1).Get();
15+
aspects[0] = new FooAspect(_value);
16+
return aspects;
17+
}
18+
}
19+
}
20+
#endif
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#if UNITY_2019_1_OR_NEWER
2+
using Gum.Composer;
3+
using Gum.Composer.Exception;
4+
using Gum.Composer.Unity.Runtime;
5+
using NUnit.Framework;
6+
using UnityEngine;
7+
8+
namespace Tests.CompositionTests.Unity
9+
{
10+
public class MonoComposableTests
11+
{
12+
private MonoComposable _mockMonoComposable;
13+
14+
private const int VALUE = 12;
15+
16+
[SetUp]
17+
public void SetUp()
18+
{
19+
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
20+
FooMonoComposable fooMonoComposable = cube.AddComponent<FooMonoComposable>();
21+
_mockMonoComposable = fooMonoComposable;
22+
}
23+
24+
[Test]
25+
public void Add_Aspect_To_MonoComposable()
26+
{
27+
Assert.IsFalse(_mockMonoComposable.Composition.HasAspect(BarAspect.ASPECT_TYPE));
28+
29+
_mockMonoComposable.Composition.AddAspect(new BarAspect(VALUE));
30+
31+
Assert.IsTrue(_mockMonoComposable.Composition.HasAspect(BarAspect.ASPECT_TYPE));
32+
}
33+
34+
[Test]
35+
public void MonoComposable_Has_Aspect()
36+
{
37+
Assert.IsTrue(_mockMonoComposable.Composition.HasAspect(FooAspect.ASPECT_TYPE));
38+
}
39+
40+
[Test]
41+
public void Get_Aspect_From_MonoComposable()
42+
{
43+
FooAspect fooAspect = _mockMonoComposable.Composition.GetAspect<FooAspect>();
44+
Assert.AreEqual(VALUE, fooAspect.MyInt);
45+
}
46+
47+
[Test]
48+
public void Try_Get_Aspect_From_MonoComposable()
49+
{
50+
Assert.IsTrue(_mockMonoComposable.Composition.TryGetAspect(out FooAspect fooAspect));
51+
Assert.AreEqual(VALUE, fooAspect.MyInt);
52+
Assert.IsFalse(_mockMonoComposable.Composition.TryGetAspect(out BarAspect _));
53+
}
54+
55+
[Test]
56+
public void Get_Aspect_Fluent()
57+
{
58+
_mockMonoComposable.Composition.GetAspectFluent(out FooAspect fooAspect);
59+
60+
Assert.AreEqual(VALUE, fooAspect.MyInt);
61+
}
62+
63+
[Test]
64+
public void Get_Aspect_With_Indexer()
65+
{
66+
_mockMonoComposable.Composition.AddAspect(new BarAspect(VALUE));
67+
BarAspect barAspect = (BarAspect)_mockMonoComposable.Composition[BarAspect.ASPECT_TYPE];
68+
69+
Assert.IsNotNull(barAspect);
70+
Assert.AreEqual(VALUE, barAspect.MyInt);
71+
}
72+
73+
[Test]
74+
public void Set_Aspect()
75+
{
76+
FooAspect fooAspect = _mockMonoComposable.Composition.GetAspect<FooAspect>();
77+
78+
Assert.AreEqual(VALUE, fooAspect.MyInt);
79+
80+
const int newValue = 20;
81+
_mockMonoComposable.Composition.SetAspect(new FooAspect(newValue));
82+
Assert.AreEqual(newValue, _mockMonoComposable.Composition.GetAspect<FooAspect>().MyInt);
83+
Assert.AreEqual(1, _mockMonoComposable.Composition.AspectCount);
84+
}
85+
86+
[Test]
87+
public void Set_Non_Existing_Aspect()
88+
{
89+
Assert.IsFalse(_mockMonoComposable.Composition.HasAspect(BarAspect.ASPECT_TYPE));
90+
91+
const int newValue = 20;
92+
_mockMonoComposable.Composition.SetAspect(new BarAspect(newValue));
93+
94+
Assert.AreEqual(newValue, _mockMonoComposable.Composition.GetAspect<BarAspect>().MyInt);
95+
Assert.AreEqual(VALUE, _mockMonoComposable.Composition.GetAspect<FooAspect>().MyInt);
96+
97+
Assert.AreEqual(2, _mockMonoComposable.Composition.AspectCount);
98+
}
99+
100+
[Test]
101+
public void Remove_Aspect()
102+
{
103+
Assert.IsTrue(_mockMonoComposable.Composition.HasAspect(FooAspect.ASPECT_TYPE));
104+
105+
_mockMonoComposable.Composition.RemoveAspect(FooAspect.ASPECT_TYPE);
106+
107+
Assert.IsFalse(_mockMonoComposable.Composition.HasAspect(FooAspect.ASPECT_TYPE));
108+
}
109+
110+
[Test]
111+
public void Enumerator()
112+
{
113+
_mockMonoComposable.Composition.AddAspect(new BarAspect(VALUE));
114+
115+
foreach (IAspect aspect in _mockMonoComposable.Composition)
116+
{
117+
Assert.IsTrue(aspect is BarAspect || aspect is FooAspect);
118+
}
119+
120+
Assert.Pass();
121+
}
122+
123+
[TearDown]
124+
public void TearDown()
125+
{
126+
Object.Destroy(_mockMonoComposable.gameObject);
127+
}
128+
}
129+
}
130+
#endif

0 commit comments

Comments
 (0)