1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 15:12:57 +08:00

Extract random selection logic into CarouselRoot

This commit is contained in:
smoogipoo 2018-04-02 15:16:10 +09:00
parent 7e30375443
commit 82a847b820
3 changed files with 39 additions and 17 deletions

View File

@ -66,7 +66,7 @@ namespace osu.Game.Screens.Select
get { return beatmapSets.Select(g => g.BeatmapSet); } get { return beatmapSets.Select(g => g.BeatmapSet); }
set set
{ {
CarouselGroup newRoot = new CarouselGroupEagerSelect(this); CarouselRoot newRoot = new CarouselRoot(this);
Task.Run(() => Task.Run(() =>
{ {
@ -102,11 +102,11 @@ namespace osu.Game.Screens.Select
private readonly Stack<CarouselBeatmap> randomSelectedBeatmaps = new Stack<CarouselBeatmap>(); private readonly Stack<CarouselBeatmap> randomSelectedBeatmaps = new Stack<CarouselBeatmap>();
protected List<DrawableCarouselItem> Items = new List<DrawableCarouselItem>(); protected List<DrawableCarouselItem> Items = new List<DrawableCarouselItem>();
private CarouselGroup root; private CarouselRoot root;
public BeatmapCarousel() public BeatmapCarousel()
{ {
root = new CarouselGroupEagerSelect(this); root = new CarouselRoot(this);
Child = new OsuContextMenuContainer Child = new OsuContextMenuContainer
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,

View File

@ -11,11 +11,8 @@ namespace osu.Game.Screens.Select.Carousel
/// </summary> /// </summary>
public class CarouselGroupEagerSelect : CarouselGroup public class CarouselGroupEagerSelect : CarouselGroup
{ {
private readonly BeatmapCarousel parent; public CarouselGroupEagerSelect()
public CarouselGroupEagerSelect(BeatmapCarousel parent = null)
{ {
this.parent = parent;
State.ValueChanged += v => State.ValueChanged += v =>
{ {
if (v == CarouselItemState.Selected) if (v == CarouselItemState.Selected)
@ -23,13 +20,16 @@ namespace osu.Game.Screens.Select.Carousel
}; };
} }
/// <summary>
/// The last selected item.
/// </summary>
protected CarouselItem LastSelected { get; private set; }
/// <summary> /// <summary>
/// We need to keep track of the index for cases where the selection is removed but we want to select a new item based on its old location. /// We need to keep track of the index for cases where the selection is removed but we want to select a new item based on its old location.
/// </summary> /// </summary>
private int lastSelectedIndex; private int lastSelectedIndex;
private CarouselItem lastSelected;
/// <summary> /// <summary>
/// To avoid overhead during filter operations, we don't attempt any selections until after all /// To avoid overhead during filter operations, we don't attempt any selections until after all
/// children have been filtered. This bool will be true during the base <see cref="Filter(FilterCriteria)"/> /// children have been filtered. This bool will be true during the base <see cref="Filter(FilterCriteria)"/>
@ -50,7 +50,7 @@ namespace osu.Game.Screens.Select.Carousel
{ {
base.RemoveChild(i); base.RemoveChild(i);
if (i != lastSelected) if (i != LastSelected)
updateSelectedIndex(); updateSelectedIndex();
} }
@ -86,12 +86,11 @@ namespace osu.Game.Screens.Select.Carousel
// we only perform eager selection if none of our children are in a selected state already. // we only perform eager selection if none of our children are in a selected state already.
if (Children.Any(i => i.State == CarouselItemState.Selected)) return; if (Children.Any(i => i.State == CarouselItemState.Selected)) return;
if (parent != null && lastSelected == null) PerformSelection();
{
parent.SelectNextRandom();
return;
} }
protected virtual void PerformSelection()
{
CarouselItem nextToSelect = CarouselItem nextToSelect =
Children.Skip(lastSelectedIndex).FirstOrDefault(i => !i.Filtered) ?? Children.Skip(lastSelectedIndex).FirstOrDefault(i => !i.Filtered) ??
Children.Reverse().Skip(InternalChildren.Count - lastSelectedIndex).FirstOrDefault(i => !i.Filtered); Children.Reverse().Skip(InternalChildren.Count - lastSelectedIndex).FirstOrDefault(i => !i.Filtered);
@ -104,10 +103,10 @@ namespace osu.Game.Screens.Select.Carousel
private void updateSelected(CarouselItem newSelection) private void updateSelected(CarouselItem newSelection)
{ {
lastSelected = newSelection; LastSelected = newSelection;
updateSelectedIndex(); updateSelectedIndex();
} }
private void updateSelectedIndex() => lastSelectedIndex = lastSelected == null ? 0 : Math.Max(0, InternalChildren.IndexOf(lastSelected)); private void updateSelectedIndex() => lastSelectedIndex = LastSelected == null ? 0 : Math.Max(0, InternalChildren.IndexOf(LastSelected));
} }
} }

View File

@ -0,0 +1,23 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Screens.Select.Carousel
{
public class CarouselRoot : CarouselGroupEagerSelect
{
private readonly BeatmapCarousel carousel;
public CarouselRoot(BeatmapCarousel carousel)
{
this.carousel = carousel;
}
protected override void PerformSelection()
{
if (LastSelected == null)
carousel.SelectNextRandom();
else
base.PerformSelection();
}
}
}