Skip to content

Commit

Permalink
Merge pull request #37 from jonisavo/feature/async-asset-loading
Browse files Browse the repository at this point in the history
Add asynchronous asset loading
  • Loading branch information
jonisavo committed Aug 28, 2022
2 parents 9041ed1 + 5a6cc7e commit e7753fa
Show file tree
Hide file tree
Showing 31 changed files with 599 additions and 240 deletions.
15 changes: 6 additions & 9 deletions .github/workflows/unity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ env:
PROJECT_UNITY_VERSION: 2020.3.38f1

jobs:
buildAndTestForLinuxBasedPlatforms:
name: Build & Test for ${{ matrix.targetPlatform }} on ${{ matrix.unityVersion }}
buildAndTestForLinux:
name: Build & Test for StandaloneLinux64 on ${{ matrix.unityVersion }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand All @@ -23,9 +23,6 @@ jobs:
- 2020.3.38f1
- 2021.3.8f1
- 2022.1.13f1
targetPlatform:
- StandaloneLinux64
- WebGL

steps:
- uses: actions/checkout@v3
Expand All @@ -35,10 +32,10 @@ jobs:
- uses: actions/cache@v3
with:
path: Library
key: Library-${{ matrix.targetPlatform }}-${{ matrix.unityVersion }}-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
key: Library-StandaloneLinux64-${{ matrix.unityVersion }}-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
restore-keys: |
Library-${{ matrix.targetPlatform }}-${{ matrix.unityVersion }}-
Library-${{ matrix.targetPlatform }}-
Library-StandaloneLinux64-${{ matrix.unityVersion }}-
Library-StandaloneLinux64-
Library-
- uses: game-ci/unity-test-runner@v2
Expand Down Expand Up @@ -79,7 +76,7 @@ jobs:
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
targetPlatform: StandaloneLinux64

buildForWindows:
name: Build for 64-bit Windows on ${{ matrix.unityVersion }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ private void CreateGUI()
rootVisualElement.Add(new AddressablesExampleComponent());
}
}
}
}
4 changes: 2 additions & 2 deletions Assets/Samples/Counter/CounterComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ public CounterComponent()
incrementButton.text = "Increment";
Add(incrementButton);
}

private void IncrementCount()
{
_counterService.IncrementCount();
_countLabel.text = _counterService.GetCount().ToString();
}
}
}
}
16 changes: 10 additions & 6 deletions Assets/Samples/EventInterfaces/EventInterfaceLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,25 @@ namespace UIComponents.Samples.EventInterfaces
public class EventInterfaceLog : UIComponent
{
public new class UxmlFactory : UxmlFactory<EventInterfaceLog> {}

private readonly ScrollView _scrollView;

private readonly EventLogService _eventLogService;

private ScrollView _scrollView;

public EventInterfaceLog()
{
_scrollView = this.Q<ScrollView>("event-scroll-view");

// Unity 2019 does not support interfaces with delegates and events,
// so we need to get the class itself
_eventLogService = Provide<IEventLogService>() as EventLogService;
}

public override void OnInit()
{
_scrollView = this.Q<ScrollView>("event-scroll-view");

foreach (var message in _eventLogService.GetMessages())
_scrollView.Add(new Label(message));

_eventLogService.OnMessageAdd += OnLogMessageAdd;
_eventLogService.OnMessageChange += OnLogMessageChange;
_eventLogService.OnClear += OnLogClear;
Expand Down Expand Up @@ -51,4 +55,4 @@ private void OnLogClear()
_scrollView.Clear();
}
}
}
}
10 changes: 7 additions & 3 deletions Assets/Samples/EventInterfaces/EventInterfacesView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ public class EventInterfacesView : UIComponent,
{
private readonly IEventLogService _eventLogService;

private readonly Button _clearButton;
private Button _clearButton;

public EventInterfacesView()
{
_eventLogService = Provide<IEventLogService>();
}

public override void OnInit()
{
_clearButton = this.Q<Button>("log-clear-button");
_clearButton.clicked += OnClearButtonClicked;
}

~EventInterfacesView()
{
_clearButton.clicked -= OnClearButtonClicked;
Expand Down Expand Up @@ -64,4 +68,4 @@ private void OnClearButtonClicked()
_eventLogService.Clear();
}
}
}
}
8 changes: 4 additions & 4 deletions Assets/Samples/Query/QueryExampleComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ public class QueryExampleComponent : UIComponent

[Query]
private readonly VisualElement[] Everything;
public QueryExampleComponent()

public override void OnInit()
{
MyLabel.text = "This text was set in the component constructor.";
MyFoldout.Add(new Label("This label was added in the component constructor."));
MyLabel.text = "This text was set in the component's OnInit function.";
MyFoldout.Add(new Label("This label was added in the component's OnInit function."));

foreach (var label in DescriptionLabels)
label.style.color = Color.green;
Expand Down
16 changes: 12 additions & 4 deletions Assets/UIComponents.Benchmarks/BenchmarkUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace UIComponents.Benchmarks
{
public static class BenchmarkUtils
{
public const string Version = "0.19.0.0";
public const string Version = "0.20.0.0";

private static SampleGroup[] GetProfilerMarkers()
{
Expand All @@ -20,7 +20,11 @@ private static SampleGroup[] GetProfilerMarkers()

public static void MeasureComponentInitWithColdCache<TComponent>() where TComponent : UIComponent, new()
{
Measure.Method(() => { new TComponent(); })
Measure.Method(async () =>
{
var component = new TComponent();
await component.WaitForInitialization();
})
.SetUp(() =>
{
UIComponent.ClearCache<TComponent>();
Expand All @@ -36,7 +40,11 @@ public static void MeasureComponentInitWithColdCache<TComponent>() where TCompon

public static void MeasureComponentInitWithWarmCache<TComponent>() where TComponent : UIComponent, new()
{
Measure.Method(() => { new TComponent(); })
Measure.Method(async () =>
{
var component = new TComponent();
await component.WaitForInitialization();
})
.SampleGroup(new SampleGroup("Warm Cache Time"))
.MeasurementCount(50)
.IterationsPerMeasurement(100)
Expand All @@ -45,4 +53,4 @@ public static void MeasureComponentInitWithWarmCache<TComponent>() where TCompon
.Run();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
using NUnit.Framework;
using System.Collections;
using NUnit.Framework;
using UIComponents.Addressables;
using UnityEngine.TestTools;
using UnityEngine.UIElements;

namespace UIComponents.Tests.Addressables
{
[TestFixture]
public class AddressableAssetResolverTests : AssetResolverTestSuite<AddressableAssetResolver>
{
[Test]
public void Should_Be_Able_To_Load_Existing_Asset()
[UnityTest]
public IEnumerator Should_Be_Able_To_Load_Existing_Asset()
{
Assert_Loads_Existing_Asset<StyleSheet>(
yield return Assert_Loads_Existing_Asset<StyleSheet>(
"Assets/UIComponents.Tests/Addressables/Assets/Component.uss"
);
Assert_Loads_Existing_Asset<VisualTreeAsset>(
yield return Assert_Loads_Existing_Asset<VisualTreeAsset>(
"Assets/UIComponents.Tests/Addressables/Assets/Component.uxml"
);
}
Expand All @@ -29,4 +31,4 @@ public void Should_Be_Able_To_Tell_If_Asset_Exists()
);
}
}
}
}
17 changes: 13 additions & 4 deletions Assets/UIComponents.Tests/AssetResolverTestSuite.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using NUnit.Framework;
using System.Collections;
using System.Threading.Tasks;
using NUnit.Framework;
using UIComponents.Tests.Utilities;

namespace UIComponents.Tests
{
public abstract class AssetResolverTestSuite<T> where T : IAssetResolver, new()
{
protected void Assert_Loads_Existing_Asset<TAsset>(string assetPath)
protected IEnumerator Assert_Loads_Existing_Asset<TAsset>(string assetPath)
where TAsset : UnityEngine.Object
{
var assetResolver = new T();
Expand All @@ -13,7 +16,13 @@ protected void Assert_Loads_Existing_Asset<TAsset>(string assetPath)

Assert.That(obj, Is.Not.Null);

Assert.That(obj, Is.InstanceOf<TAsset>());
Assert.That(obj, Is.InstanceOf<Task<TAsset>>());

yield return obj.AsEnumerator();

Assert.That(obj.Result, Is.Not.Null);

Assert.That(obj.Result, Is.InstanceOf<TAsset>());
}

protected void Assert_Tells_If_Asset_Exists(string assetPath)
Expand All @@ -29,4 +38,4 @@ protected void Assert_Tells_If_Asset_Exists(string assetPath)
Assert.That(nonExistantAssetDoesNotExist, Is.False);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using NUnit.Framework;
using System.Collections;
using NUnit.Framework;
using UIComponents.Tests.Utilities;
using UnityEditor;
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.UIElements;

namespace UIComponents.Tests.Editor.Interfaces
Expand All @@ -13,7 +15,7 @@ private class BaseTestComponent : UIComponent
public bool Fired { get; protected set; }
}

private static void Assert_Registers_Event_Callback<TComponent, TEvent>()
private static IEnumerator Assert_Registers_Event_Callback<TComponent, TEvent>()
where TComponent : BaseTestComponent, new()
where TEvent : EventBase<TEvent>, new()
{
Expand All @@ -22,6 +24,8 @@ private class BaseTestComponent : UIComponent
Assert.That(component.Fired, Is.False);
window.AddTestComponent(component);

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

using (var evt = new TEvent() { target = component })
component.SendEvent(evt);

Expand All @@ -34,54 +38,54 @@ private class UIComponentWithOnGeometryChanged : BaseTestComponent, IOnGeometryC
public void OnGeometryChanged(GeometryChangedEvent evt) => Fired = true;
}

[Test]
public void IOnGeometryChanged_Registers_GeometryChangedEvent_Callback()
[UnityTest]
public IEnumerator IOnGeometryChanged_Registers_GeometryChangedEvent_Callback()
{
Assert_Registers_Event_Callback<UIComponentWithOnGeometryChanged, GeometryChangedEvent>();
yield return Assert_Registers_Event_Callback<UIComponentWithOnGeometryChanged, GeometryChangedEvent>();
}

private class UIComponentWithOnAttachToPanel : BaseTestComponent, IOnAttachToPanel
{
public void OnAttachToPanel(AttachToPanelEvent evt) => Fired = true;
}

[Test]
public void IOnAttachToPanel_Registers_AttachToPanelEvent_Callback()
[UnityTest]
public IEnumerator IOnAttachToPanel_Registers_AttachToPanelEvent_Callback()
{
Assert_Registers_Event_Callback<UIComponentWithOnAttachToPanel, AttachToPanelEvent>();
yield return Assert_Registers_Event_Callback<UIComponentWithOnAttachToPanel, AttachToPanelEvent>();
}

private class UIComponentWithOnDetachFromPanel : BaseTestComponent, IOnDetachFromPanel
{
public void OnDetachFromPanel(DetachFromPanelEvent evt) => Fired = true;
}

[Test]
public void IOnDetachFromPanel_Registers_DetachFromPanelEvent_Callback()
[UnityTest]
public IEnumerator IOnDetachFromPanel_Registers_DetachFromPanelEvent_Callback()
{
Assert_Registers_Event_Callback<UIComponentWithOnDetachFromPanel, DetachFromPanelEvent>();
yield return Assert_Registers_Event_Callback<UIComponentWithOnDetachFromPanel, DetachFromPanelEvent>();
}

private class UIComponentWithOnMouseEnter : BaseTestComponent, IOnMouseEnter
{
public void OnMouseEnter(MouseEnterEvent evt) => Fired = true;
}

[Test]
public void IOnMouseEnter_Registers_MouseEnterEvent_Callback()
[UnityTest]
public IEnumerator IOnMouseEnter_Registers_MouseEnterEvent_Callback()
{
Assert_Registers_Event_Callback<UIComponentWithOnMouseEnter, MouseEnterEvent>();
yield return Assert_Registers_Event_Callback<UIComponentWithOnMouseEnter, MouseEnterEvent>();
}

private class UIComponentWithOnMouseLeave : BaseTestComponent, IOnMouseLeave
{
public void OnMouseLeave(MouseLeaveEvent evt) => Fired = true;
}

[Test]
public void IOnMouseLeave_Registers_MouseLeaveEvent_Callback()
[UnityTest]
public IEnumerator IOnMouseLeave_Registers_MouseLeaveEvent_Callback()
{
Assert_Registers_Event_Callback<UIComponentWithOnMouseLeave, MouseLeaveEvent>();
yield return Assert_Registers_Event_Callback<UIComponentWithOnMouseLeave, MouseLeaveEvent>();
}

#if UNITY_2020_3_OR_NEWER
Expand All @@ -90,11 +94,11 @@ private class UIComponentWithOnClick : BaseTestComponent, IOnClick
public void OnClick(ClickEvent evt) => Fired = true;
}

[Test]
public void IOnClick_Registers_ClickEvent_Callback()
[UnityTest]
public IEnumerator IOnClick_Registers_ClickEvent_Callback()
{
Assert_Registers_Event_Callback<UIComponentWithOnClick, ClickEvent>();
yield return Assert_Registers_Event_Callback<UIComponentWithOnClick, ClickEvent>();
}
#endif
}
}
}
Loading

0 comments on commit e7753fa

Please sign in to comment.