Skip to content

Commit

Permalink
feat(UIComponent): wait for child components to be initialized
Browse files Browse the repository at this point in the history
BREAKING CHANGE: UIComponents now wait for their hierarchy to be initialized before calling OnInit.
  • Loading branch information
jonisavo committed Oct 9, 2022
1 parent a7faca3 commit fe9bdaa
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 5 deletions.
66 changes: 61 additions & 5 deletions Assets/UIComponents.Tests/UIComponentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,23 @@ public class Initialization
{
private class MockAssetResolver : IAssetResolver
{
public readonly Dictionary<string, object> TaskCompletionSources =
private readonly Dictionary<string, object> _taskCompletionSources =
new Dictionary<string, object>();

public Task<T> LoadAsset<T>(string assetPath) where T : Object
{
var source = new TaskCompletionSource<T>();
TaskCompletionSources.Add(assetPath, source);
return source.Task;
if (!_taskCompletionSources.ContainsKey(assetPath))
{
var source = new TaskCompletionSource<T>();
_taskCompletionSources.Add(assetPath, source);
}

return ((TaskCompletionSource<T>) _taskCompletionSources[assetPath]).Task;
}

public void CompleteLoad<T>(string assetPath) where T : ScriptableObject
{
var source = (TaskCompletionSource<T>) TaskCompletionSources[assetPath];
var source = (TaskCompletionSource<T>) _taskCompletionSources[assetPath];
source.SetResult(ScriptableObject.CreateInstance<T>());
}

Expand Down Expand Up @@ -117,6 +121,58 @@ public IEnumerator Allows_Waiting_For_Initialization_With_Obsolete_Method()
Assert.That(component.Initialized, Is.True);
}

[Layout("Child")]
[Stylesheet("ChildStylesheet")]
private class ChildComponent : UIComponent {}

[Layout("NestedChild")]
private class NestedChildComponent : UIComponent {}

[Test]
public void Does_Not_Initialize_If_Children_Are_Uninitialized()
{
var component = _testBed.CreateComponent<TestComponent>();

var firstChild = _testBed.CreateComponent<ChildComponent>();
var secondChild = _testBed.CreateComponent<ChildComponent>();

component.Add(firstChild);
component.Add(secondChild);

_mockAssetResolver.CompleteLoad<VisualTreeAsset>("Layout");
_mockAssetResolver.CompleteLoad<StyleSheet>("Stylesheet1");
_mockAssetResolver.CompleteLoad<StyleSheet>("Stylesheet2");

Assert.That(component.Initialized, Is.False);
}

[Test]
public void Initializes_When_Children_Are_Initialized()
{
var component = _testBed.CreateComponent<TestComponent>();

var firstChild = _testBed.CreateComponent<ChildComponent>();
var secondChild = _testBed.CreateComponent<ChildComponent>();

var nestedChild = _testBed.CreateComponent<NestedChildComponent>();

firstChild.Add(nestedChild);

component.Add(firstChild);
component.Add(secondChild);

_mockAssetResolver.CompleteLoad<VisualTreeAsset>("Layout");
_mockAssetResolver.CompleteLoad<StyleSheet>("Stylesheet1");
_mockAssetResolver.CompleteLoad<StyleSheet>("Stylesheet2");

_mockAssetResolver.CompleteLoad<VisualTreeAsset>("Child");
_mockAssetResolver.CompleteLoad<StyleSheet>("ChildStylesheet");

_mockAssetResolver.CompleteLoad<VisualTreeAsset>("NestedChild");

Assert.That(component.Initialized, Is.True);
}

private class BareTestComponent : UIComponent {}

[Test]
Expand Down
12 changes: 12 additions & 0 deletions Assets/UIComponents/Core/UIComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ private async void Initialize()
LoadLayout(layoutAsset);
LoadStyles(styles);

var childInitializationTasks = new List<Task>();

for (var i = 0; i < childCount; i++)
{
var child = hierarchy.ElementAt(i);

if (child is UIComponent component)
childInitializationTasks.Add(component.InitializationTask);
}

await Task.WhenAll(childInitializationTasks);

PostHierarchySetupProfilerMarker.Begin();

ApplyEffects();
Expand Down

0 comments on commit fe9bdaa

Please sign in to comment.