// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay; using osu.Game.Screens.OnlinePlay.Lounge.Components; namespace osu.Game.Tests.Visual.OnlinePlay { /// /// A providing all the dependencies cached by for testing s. /// public abstract class OnlinePlayTestScene : ScreenTestScene, IRoomTestDependencies { public Bindable SelectedRoom => RoomDependencies?.SelectedRoom; public IRoomManager RoomManager => RoomDependencies?.RoomManager; public Bindable Filter => RoomDependencies?.Filter; public OngoingOperationTracker OngoingOperationTracker => RoomDependencies?.OngoingOperationTracker; public OnlinePlayBeatmapAvailabilityTracker AvailabilityTracker => RoomDependencies?.AvailabilityTracker; protected RoomTestDependencies RoomDependencies => delegatedDependencies?.RoomDependencies; private DelegatedRoomDependencyContainer delegatedDependencies; protected override Container Content => content; private readonly Container content; private readonly Container drawableDependenciesContainer; protected OnlinePlayTestScene() { base.Content.AddRange(new Drawable[] { drawableDependenciesContainer = new Container { RelativeSizeAxes = Axes.Both }, content = new Container { RelativeSizeAxes = Axes.Both }, }); } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { delegatedDependencies = new DelegatedRoomDependencyContainer(base.CreateChildDependencies(parent)); return delegatedDependencies; } [SetUp] public void Setup() => Schedule(() => { // Reset the room dependencies to a fresh state. drawableDependenciesContainer.Clear(); delegatedDependencies.RoomDependencies = CreateRoomDependencies(); drawableDependenciesContainer.AddRange(RoomDependencies.DrawableComponents); }); /// /// Creates the room dependencies. Called every . /// /// /// Any custom dependencies required for online-play sub-classes should be added here. /// protected virtual RoomTestDependencies CreateRoomDependencies() => new RoomTestDependencies(); /// /// A providing a mutable lookup source for room dependencies. /// private class DelegatedRoomDependencyContainer : IReadOnlyDependencyContainer { /// /// The room's dependencies. /// public RoomTestDependencies RoomDependencies { get; set; } private readonly IReadOnlyDependencyContainer parent; private readonly DependencyContainer injectableDependencies; /// /// Creates a new . /// /// The fallback to use when cannot satisfy a dependency. public DelegatedRoomDependencyContainer(IReadOnlyDependencyContainer parent) { this.parent = parent; injectableDependencies = new DependencyContainer(this); } public object Get(Type type) => RoomDependencies?.Get(type) ?? parent.Get(type); public object Get(Type type, CacheInfo info) => RoomDependencies?.Get(type, info) ?? parent.Get(type, info); public void Inject(T instance) where T : class => injectableDependencies.Inject(instance); } } }