1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 06:07:25 +08:00

Add basic pooling setup

This commit is contained in:
Dean Herbert 2020-10-12 15:36:03 +09:00
parent f17d661c1a
commit 0a978c6131
5 changed files with 95 additions and 43 deletions

View File

@ -16,6 +16,7 @@ using osu.Framework.Bindables;
using osu.Framework.Caching;
using osu.Framework.Threading;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics.Pooling;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Beatmaps;
@ -136,6 +137,8 @@ namespace osu.Game.Screens.Select
private IBindable<WeakReference<BeatmapInfo>> itemHidden;
private IBindable<WeakReference<BeatmapInfo>> itemRestored;
private readonly DrawablePool<DrawableCarouselBeatmapSet> setPool = new DrawablePool<DrawableCarouselBeatmapSet>(100);
public BeatmapCarousel()
{
root = new CarouselRoot(this);
@ -146,9 +149,13 @@ namespace osu.Game.Screens.Select
{
Masking = false,
RelativeSizeAxes = Axes.Both,
Child = scrollableContent = new Container<DrawableCarouselItem>
Children = new Drawable[]
{
RelativeSizeAxes = Axes.X,
setPool,
scrollableContent = new Container<DrawableCarouselItem>
{
RelativeSizeAxes = Axes.X,
}
}
}
};
@ -580,11 +587,13 @@ namespace osu.Game.Screens.Select
// Add those items within the previously found index range that should be displayed.
for (int i = firstIndex; i < lastIndex; ++i)
{
var panel = scrollableContent.FirstOrDefault(c => c.Item == visibleItems[i]);
var item = visibleItems[i];
var panel = scrollableContent.FirstOrDefault(c => c.Item == item);
if (panel == null)
{
panel = visibleItems[i].CreateDrawableRepresentation();
panel = setPool.Get(p => p.Item = item);
scrollableContent.Add(panel);
}

View File

@ -43,8 +43,6 @@ namespace osu.Game.Screens.Select.Carousel
.ForEach(AddChild);
}
public override DrawableCarouselItem CreateDrawableRepresentation() => new DrawableCarouselBeatmapSet(this);
protected override CarouselItem GetNextToSelect()
{
if (LastSelected == null)

View File

@ -60,10 +60,12 @@ namespace osu.Game.Screens.Select.Carousel
private CancellationTokenSource starDifficultyCancellationSource;
public DrawableCarouselBeatmap(CarouselBeatmap panel)
: base(panel)
{
beatmap = panel.Beatmap;
Height = HEIGHT;
// todo: temporary
Item = panel;
}
[BackgroundDependencyLoader(true)]
@ -79,7 +81,7 @@ namespace osu.Game.Screens.Select.Carousel
if (manager != null)
hideRequested = manager.Hide;
Children = new Drawable[]
Content.Children = new Drawable[]
{
background = new Box
{

View File

@ -45,26 +45,40 @@ namespace osu.Game.Screens.Select.Carousel
public override IEnumerable<DrawableCarouselItem> ChildItems => beatmapContainer?.Children ?? base.ChildItems;
private readonly BeatmapSetInfo beatmapSet;
private BeatmapSetInfo beatmapSet => (Item as CarouselBeatmapSet)?.BeatmapSet;
private Container<DrawableCarouselBeatmap> beatmapContainer;
private Bindable<CarouselItemState> beatmapSetState;
public DrawableCarouselBeatmapSet(CarouselBeatmapSet set)
: base(set)
{
beatmapSet = set.BeatmapSet;
}
[Resolved]
private BeatmapManager manager { get; set; }
[BackgroundDependencyLoader(true)]
private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay)
private void load(BeatmapSetOverlay beatmapOverlay)
{
restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore);
if (beatmapOverlay != null)
viewDetails = beatmapOverlay.FetchAndShowBeatmapSet;
Children = new Drawable[]
// TODO: temporary. we probably want to *not* inherit DrawableCarouselItem for this class, but only the above header portion.
AddRangeInternal(new Drawable[]
{
beatmapContainer = new Container<DrawableCarouselBeatmap>
{
X = 50,
Y = MAX_HEIGHT,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
},
});
}
protected override void UpdateItem()
{
base.UpdateItem();
Content.Children = new Drawable[]
{
new DelayedLoadUnloadWrapper(() =>
{
@ -125,17 +139,7 @@ namespace osu.Game.Screens.Select.Carousel
}
};
// TODO: temporary. we probably want to *not* inherit DrawableCarouselItem for this class, but only the above header portion.
AddRangeInternal(new Drawable[]
{
beatmapContainer = new Container<DrawableCarouselBeatmap>
{
X = 50,
Y = MAX_HEIGHT,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
},
});
beatmapContainer.Clear();
beatmapSetState = Item.State.GetBoundCopy();
beatmapSetState.BindValueChanged(setSelected, true);
@ -153,11 +157,16 @@ namespace osu.Game.Screens.Select.Carousel
float yPos = 0;
foreach (var item in ((CarouselBeatmapSet)Item).Beatmaps.Select(b => b.CreateDrawableRepresentation()).OfType<DrawableCarouselBeatmap>())
var carouselBeatmapSet = (CarouselBeatmapSet)Item;
foreach (var item in carouselBeatmapSet.Children)
{
item.Y = yPos;
beatmapContainer.Add(item);
yPos += item.Item.TotalHeight;
var beatmapPanel = item.CreateDrawableRepresentation();
beatmapPanel.Y = yPos;
yPos += item.TotalHeight;
beatmapContainer.Add((DrawableCarouselBeatmap)beatmapPanel);
}
break;

View File

@ -2,14 +2,17 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Pooling;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Framework.Utils;
@ -19,15 +22,32 @@ using osuTK.Graphics;
namespace osu.Game.Screens.Select.Carousel
{
public abstract class DrawableCarouselItem : Container
public abstract class DrawableCarouselItem : PoolableDrawable
{
public const float MAX_HEIGHT = 80;
public override bool RemoveWhenNotAlive => false;
public override bool IsPresent => base.IsPresent || Item?.Visible == true;
public override bool IsPresent => base.IsPresent || Item.Visible;
public CarouselItem Item
{
get => item;
set
{
if (item == value)
return;
public readonly CarouselItem Item;
if (item != null)
{
Item.Filtered.ValueChanged -= onStateChange;
Item.State.ValueChanged -= onStateChange;
}
item = value;
if (IsLoaded)
UpdateItem();
}
}
public virtual IEnumerable<DrawableCarouselItem> ChildItems => Enumerable.Empty<DrawableCarouselItem>();
@ -37,12 +57,10 @@ namespace osu.Game.Screens.Select.Carousel
private readonly Box hoverLayer;
protected override Container<Drawable> Content => nestedContainer;
protected Container<Drawable> Content => nestedContainer;
protected DrawableCarouselItem(CarouselItem item)
protected DrawableCarouselItem()
{
Item = item;
Height = MAX_HEIGHT;
RelativeSizeAxes = Axes.X;
Alpha = 0;
@ -70,6 +88,7 @@ namespace osu.Game.Screens.Select.Carousel
}
private SampleChannel sampleHover;
private CarouselItem item;
[BackgroundDependencyLoader]
private void load(AudioManager audio, OsuColour colours)
@ -98,14 +117,27 @@ namespace osu.Game.Screens.Select.Carousel
{
base.LoadComplete();
ApplyState();
Item.Filtered.ValueChanged += _ => Schedule(ApplyState);
Item.State.ValueChanged += _ => Schedule(ApplyState);
UpdateItem();
}
protected virtual void UpdateItem()
{
if (item == null)
return;
ApplyState();
Item.Filtered.ValueChanged += onStateChange;
Item.State.ValueChanged += onStateChange;
}
private void onStateChange(ValueChangedEvent<CarouselItemState> obj) => Schedule(ApplyState);
private void onStateChange(ValueChangedEvent<bool> _) => Schedule(ApplyState);
protected virtual void ApplyState()
{
if (!IsLoaded) return;
Debug.Assert(Item != null);
switch (Item.State.Value)
{
@ -126,6 +158,8 @@ namespace osu.Game.Screens.Select.Carousel
protected virtual void Selected()
{
Debug.Assert(Item != null);
Item.State.Value = CarouselItemState.Selected;
BorderContainer.BorderThickness = 2.5f;