Skip to content

Commit

Permalink
feat(UIComponent): return Task from Initialize
Browse files Browse the repository at this point in the history
  • Loading branch information
jonisavo committed May 8, 2023
1 parent e163110 commit 77a7cb7
Show file tree
Hide file tree
Showing 12 changed files with 46 additions and 58 deletions.
6 changes: 2 additions & 4 deletions Assets/UIComponents.Benchmarks/BenchmarkUtils.cs
Expand Up @@ -20,8 +20,7 @@ public static void MeasureComponentInitWithColdCache<TComponent>() where TCompon
Measure.Method(async () =>
{
var component = new TComponent();
component.Initialize();
await component.InitializationTask;
await component.Initialize();
})
.SetUp(() =>
{
Expand All @@ -41,8 +40,7 @@ public static void MeasureComponentInitWithWarmCache<TComponent>() where TCompon
Measure.Method(async () =>
{
var component = new TComponent();
component.Initialize();
await component.InitializationTask;
await component.Initialize();
})
.SampleGroup(new SampleGroup("Warm Cache Time"))
.WarmupCount(10)
Expand Down
16 changes: 7 additions & 9 deletions Assets/UIComponents.Tests/LayoutAttributeTests.cs
Expand Up @@ -2,6 +2,7 @@
using NSubstitute;
using NSubstitute.ReturnsExtensions;
using NUnit.Framework;
using UIComponents.Internal;
using UIComponents.Testing;
using UIComponents.Tests.Utilities;
using UnityEngine.TestTools;
Expand Down Expand Up @@ -44,8 +45,7 @@ public IEnumerator Given_Layout_Is_Loaded()
{
var testBed = new TestBed<UIComponentWithLayout>().WithSingleton(_mockResolver);
var component = testBed.CreateComponent();
component.Initialize();
yield return component.WaitForInitializationEnumerator();
yield return component.Initialize().AsEnumerator();
_mockResolver.Received().LoadAsset<VisualTreeAsset>("Assets/MyAsset.uxml");
}

Expand All @@ -54,8 +54,7 @@ public IEnumerator Superclass_Layout_Is_Loaded_If_It_Is_Not_Overridden()
{
var testBed = new TestBed<InheritedComponentWithoutAttribute>().WithSingleton(_mockResolver);
var component = testBed.CreateComponent();
component.Initialize();
yield return component.WaitForInitializationEnumerator();
yield return component.Initialize().AsEnumerator();
_mockResolver.Received().LoadAsset<VisualTreeAsset>("Assets/MyAsset.uxml");
}

Expand All @@ -64,18 +63,17 @@ public IEnumerator Superclass_Layout_Is_Not_Loaded_If_Overridden()
{
var testBed = new TestBed<InheritedComponentWithAttribute>().WithSingleton(_mockResolver);
var component = testBed.CreateComponent();
component.Initialize();
yield return component.WaitForInitializationEnumerator();
yield return component.Initialize().AsEnumerator();
_mockResolver.Received().LoadAsset<VisualTreeAsset>("Assets/MyOtherAsset.uxml");
_mockResolver.DidNotReceive().LoadAsset<VisualTreeAsset>("Assets/MyAsset.uxml");
}

[Test]
public void Null_Layout_Is_Handled()
[UnityTest]
public IEnumerator Null_Layout_Is_Handled()
{
var testBed = new TestBed<UIComponentWithNullLayout>().WithSingleton(_mockResolver);
var component = testBed.CreateComponent();
Assert.DoesNotThrow(() => component.Initialize());
yield return component.Initialize().AsEnumerator();
}
}
}
17 changes: 5 additions & 12 deletions Assets/UIComponents.Tests/QueryAttributeTests.cs
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using NSubstitute;
using NUnit.Framework;
using UIComponents.Internal;
using UIComponents.Testing;
using UnityEngine.TestTools;
using UnityEngine.UIElements;
Expand Down Expand Up @@ -51,10 +52,8 @@ public IEnumerator Should_Populate_Fields()
var testBed = new TestBed<ComponentWithQueryAttribute>()
.WithSingleton(_mockLogger);
var component = testBed.CreateComponent();
component.Initialize();
yield return component.Initialize().AsEnumerator();

yield return component.WaitForInitializationEnumerator();

Assert.That(component.HelloWorldLabel, Is.InstanceOf<Label>());
Assert.That(component.HelloWorldLabel.text, Is.EqualTo("Hello world!"));

Expand Down Expand Up @@ -88,10 +87,8 @@ public IEnumerator Should_Populate_Inherited_Fields()
var testBed = new TestBed<ChildComponentWithQueryAttribute>()
.WithSingleton(_mockLogger);
var component = testBed.CreateComponent();
component.Initialize();
yield return component.Initialize().AsEnumerator();

yield return component.WaitForInitializationEnumerator();

Assert.That(component.HelloWorldLabel, Is.InstanceOf<Label>());
Assert.That(component.TestFoldout, Is.InstanceOf<Foldout>());
Assert.That(component.FoldoutContent, Is.InstanceOf<Label>());
Expand All @@ -117,9 +114,7 @@ public IEnumerator Should_Not_Populate_Invalid_Fields()
var testBed = new TestBed<ComponentWithInvalidQueryAttribute>()
.WithSingleton(_mockLogger);
var component = testBed.CreateComponent();
component.Initialize();

yield return component.WaitForInitializationEnumerator();
yield return component.Initialize().AsEnumerator();

Assert.That(component.InvalidField, Is.Null);
Assert.That(component.InvalidArray, Is.Null);
Expand All @@ -144,10 +139,8 @@ public IEnumerator Should_Log_Errors_If_Query_Yields_No_Results()
var testBed = new TestBed<ComponentWithMissingFields>()
.WithSingleton(_mockLogger);
var component = testBed.CreateComponent();
component.Initialize();
yield return component.Initialize().AsEnumerator();

yield return component.WaitForInitializationEnumerator();

Assert.That(component.label, Is.Null);
Assert.That(component.components.Length, Is.EqualTo(0));
Assert.That(component.buttons.Count, Is.EqualTo(0));
Expand Down
4 changes: 2 additions & 2 deletions Assets/UIComponents.Tests/QueryClassAttributeTests.cs
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using NSubstitute;
using NUnit.Framework;
using UIComponents.Internal;
using UIComponents.Testing;
using UnityEngine.TestTools;
using UnityEngine.UIElements;
Expand Down Expand Up @@ -70,8 +71,7 @@ public IEnumerator UnitySetUp()
var testBed = new TestBed<QueryClassTestComponent>()
.WithSingleton(_mockLogger);
_queryClassTestComponent = testBed.CreateComponent();
_queryClassTestComponent.Initialize();
yield return _queryClassTestComponent.WaitForInitializationEnumerator();
yield return _queryClassTestComponent.Initialize().AsEnumerator();
}

[Test]
Expand Down
11 changes: 5 additions & 6 deletions Assets/UIComponents.Tests/RootClassAttributeTests.cs
@@ -1,5 +1,6 @@
using System.Collections;
using NUnit.Framework;
using UIComponents.Internal;
using UnityEngine.TestTools;

namespace UIComponents.Tests
Expand All @@ -14,9 +15,8 @@ private partial class ComponentWithRootClass : UIComponent {}
public IEnumerator Adds_Class_To_Component()
{
var component = new ComponentWithRootClass();
component.Initialize();
yield return component.WaitForInitializationEnumerator();

yield return component.Initialize().AsEnumerator();

Assert.That(component.ClassListContains("test-class"), Is.True);
}

Expand All @@ -28,9 +28,8 @@ private partial class ChildComponentWithRootClass : ComponentWithRootClass {}
public IEnumerator Adds_Class_To_Component_And_Child_Component()
{
var component = new ChildComponentWithRootClass();
component.Initialize();
yield return component.WaitForInitializationEnumerator();

yield return component.Initialize().AsEnumerator();

Assert.That(component.ClassListContains("test-class"), Is.True);
Assert.That(component.ClassListContains("other-test-class"), Is.True);
Assert.That(component.ClassListContains("final-test-class"), Is.True);
Expand Down
15 changes: 5 additions & 10 deletions Assets/UIComponents.Tests/StylesheetAttributeTests.cs
Expand Up @@ -2,6 +2,7 @@
using System.Threading.Tasks;
using NSubstitute;
using NUnit.Framework;
using UIComponents.Internal;
using UIComponents.Testing;
using UIComponents.Tests.Utilities;
using UnityEngine;
Expand Down Expand Up @@ -43,10 +44,8 @@ public IEnumerator Given_Stylesheets_Are_Loaded()
.WithSingleton(_mockLogger)
.WithTransient(_mockResolver);
var component = testBed.CreateComponent();
component.Initialize();

yield return component.WaitForInitializationEnumerator();

yield return component.Initialize().AsEnumerator();

_mockResolver.Received().LoadAsset<StyleSheet>("Assets/StylesheetOne.uss");
_mockResolver.Received().LoadAsset<StyleSheet>("Assets/StylesheetTwo.uss");
Assert.That(component.styleSheets.count, Is.EqualTo(2));
Expand All @@ -59,9 +58,7 @@ public IEnumerator Inherited_Stylesheets_Are_Loaded()
.WithSingleton(_mockLogger)
.WithTransient(_mockResolver);
var component = testBed.CreateComponent();
component.Initialize();

yield return component.WaitForInitializationEnumerator();
yield return component.Initialize().AsEnumerator();

_mockResolver.Received().LoadAsset<StyleSheet>("Assets/StylesheetOne.uss");
_mockResolver.Received().LoadAsset<StyleSheet>("Assets/StylesheetTwo.uss");
Expand All @@ -80,9 +77,7 @@ public IEnumerator Invalid_Stylesheets_Output_Error_Message()
.WithTransient(_mockResolver);

var component = testBed.CreateComponent();
component.Initialize();

yield return component.WaitForInitializationEnumerator();
yield return component.Initialize().AsEnumerator();

_mockResolver.Received().LoadAsset<StyleSheet>("Assets/StylesheetOne.uss");
_mockLogger.Received().LogError("Could not find stylesheet Assets/StylesheetOne.uss", component);
Expand Down
5 changes: 2 additions & 3 deletions Assets/UIComponents.Tests/UIComponentEffectAttributeTests.cs
Expand Up @@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UIComponents.Internal;
using UnityEngine.TestTools;

namespace UIComponents.Tests
Expand Down Expand Up @@ -38,9 +39,7 @@ private partial class UIComponentWithEffects : UIComponent
public IEnumerator Effects_Are_Sorted_By_Priority()
{
var component = new UIComponentWithEffects();
component.Initialize();

yield return component.WaitForInitializationEnumerator();
yield return component.Initialize().AsEnumerator();

Assert.That(component.AppliedEffects.Count, Is.EqualTo(4));
Assert.That(component.AppliedEffects[0], Is.EqualTo(999));
Expand Down
4 changes: 2 additions & 2 deletions Assets/UIComponents.Tests/UIComponentNoAttributesTests.cs
Expand Up @@ -2,6 +2,7 @@
using System.Threading.Tasks;
using NSubstitute;
using NUnit.Framework;
using UIComponents.Internal;
using UIComponents.Testing;
using UnityEngine.TestTools;
using UnityEngine.UIElements;
Expand All @@ -27,8 +28,7 @@ public IEnumerator UnitySetUp()
var testBed = new TestBed<UIComponentNoAttributes>()
.WithSingleton(_mockResolver);
_component = testBed.CreateComponent();
_component.Initialize();
yield return _component.WaitForInitializationEnumerator();
yield return _component.Initialize().AsEnumerator();
}

[TearDown]
Expand Down
1 change: 1 addition & 0 deletions Assets/UIComponents.Tests/UIComponentTests.cs
Expand Up @@ -6,6 +6,7 @@
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.UIElements;
#pragma warning disable CS4014

namespace UIComponents.Tests
{
Expand Down
4 changes: 0 additions & 4 deletions Assets/UIComponents/Core/Internal/TaskExtensions.cs
Expand Up @@ -11,14 +11,10 @@ internal static class TaskExtensions
public static IEnumerator AsEnumerator(this Task task)
{
while (!task.IsCompleted)
{
yield return null;
}

if (task.IsFaulted)
{
ExceptionDispatchInfo.Capture(task.Exception!).Throw();
}

yield return null;
}
Expand Down
14 changes: 13 additions & 1 deletion Assets/UIComponents/Core/UIComponent.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using UIComponents.DependencyInjection;
using UIComponents.Internal;
Expand Down Expand Up @@ -80,13 +81,24 @@ protected UIComponent()
UIC_UnregisterEventCallbacks();
}

[ExcludeFromCodeCoverage] // Pragmas are shown as uncovered lines
private void OnFirstAttachToPanel(AttachToPanelEvent evt)
{
#pragma warning disable CS4014
Initialize();
#pragma warning restore CS4014
UnregisterCallback<AttachToPanelEvent>(OnFirstAttachToPanel);
}

public async void Initialize()
/// <summary>
/// Starts the initialization of the UIComponent. Does nothing if the UIComponent has already been initialized
/// or if initialization is already ongoing.
/// </summary>
/// <remarks>
/// This method is called automatically when the UIComponent is first attached to a panel.
/// It can also be called manually to force initialization.
/// </remarks>
public async Task Initialize()
{
if (Initialized || _initializationOngoing)
return;
Expand Down
7 changes: 2 additions & 5 deletions Assets/UIComponents/Testing/TestBed.cs
Expand Up @@ -71,19 +71,16 @@ public TComponent CreateComponent(Func<TComponent> factoryPredicate)
public async Task<TComponent> CreateComponentAsync(Func<TComponent> factoryPredicate)
{
var component = CreateComponent(factoryPredicate);
component.Initialize();

var initTask = component.InitializationTask;
var initTask = component.Initialize();
var timeoutTask = Task.Delay(AsyncTimeout);

var task = await Task.WhenAny(initTask, timeoutTask);

if (task == timeoutTask)
throw new TestBedTimeoutException(component.GetType().Name, (int)AsyncTimeout.TotalMilliseconds);

var initializedComponent = await initTask;

return initializedComponent as TComponent;
return component;
}


Expand Down

0 comments on commit 77a7cb7

Please sign in to comment.