2018-04-13 17:19:50 +08:00
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
2018-07-17 14:48:51 +08:00
using System ;
2018-04-13 17:19:50 +08:00
using System.Collections.Generic ;
2018-07-17 14:48:51 +08:00
using System.Linq ;
2018-04-13 17:19:50 +08:00
using osu.Framework.Graphics ;
using osu.Game.Rulesets.Objects.Drawables ;
using osu.Framework.Allocation ;
2018-07-17 14:48:51 +08:00
using osu.Framework.Extensions.IEnumerableExtensions ;
2018-07-20 16:04:33 +08:00
using osu.Framework.Configuration ;
2018-08-03 20:03:11 +08:00
using osu.Game.Beatmaps ;
using osu.Game.Rulesets.Mods ;
2018-04-13 17:19:50 +08:00
namespace osu.Game.Rulesets.UI
{
public abstract class Playfield : ScalableContainer
{
/// <summary>
2018-07-17 14:51:10 +08:00
/// The <see cref="DrawableHitObject"/> contained in this Playfield.
2018-04-13 17:19:50 +08:00
/// </summary>
2018-08-30 12:30:23 +08:00
public HitObjectContainer HitObjectContainer { get ; private set ; }
2018-04-13 17:19:50 +08:00
/// <summary>
2018-07-17 14:51:10 +08:00
/// All the <see cref="DrawableHitObject"/>s contained in this <see cref="Playfield"/> and all <see cref="NestedPlayfields"/>.
2018-04-13 17:19:50 +08:00
/// </summary>
2018-08-30 12:30:23 +08:00
public IEnumerable < DrawableHitObject > AllHitObjects = > HitObjectContainer ? . Objects . Concat ( NestedPlayfields . SelectMany ( p = > p . AllHitObjects ) ) ? ? Enumerable . Empty < DrawableHitObject > ( ) ;
2018-07-17 14:51:10 +08:00
/// <summary>
/// All <see cref="Playfield"/>s nested inside this <see cref="Playfield"/>.
/// </summary>
2018-07-17 14:48:51 +08:00
public IEnumerable < Playfield > NestedPlayfields = > nestedPlayfields . IsValueCreated ? nestedPlayfields . Value : Enumerable . Empty < Playfield > ( ) ;
2018-04-13 17:19:50 +08:00
2018-07-17 14:51:10 +08:00
private readonly Lazy < List < Playfield > > nestedPlayfields = new Lazy < List < Playfield > > ( ) ;
2018-04-13 17:19:50 +08:00
2018-07-20 16:04:33 +08:00
/// <summary>
/// Whether judgements should be displayed by this and and all nested <see cref="Playfield"/>s.
/// </summary>
public readonly BindableBool DisplayJudgements = new BindableBool ( true ) ;
2018-04-13 17:19:50 +08:00
/// <summary>
/// A container for keeping track of DrawableHitObjects.
/// </summary>
/// <param name="customWidth">The width to scale the internal coordinate space to.
/// May be null if scaling based on <paramref name="customHeight"/> is desired. If <paramref name="customHeight"/> is also null, no scaling will occur.
/// </param>
/// <param name="customHeight">The height to scale the internal coordinate space to.
/// May be null if scaling based on <paramref name="customWidth"/> is desired. If <paramref name="customWidth"/> is also null, no scaling will occur.
/// </param>
protected Playfield ( float? customWidth = null , float? customHeight = null )
: base ( customWidth , customHeight )
{
RelativeSizeAxes = Axes . Both ;
}
2018-08-03 20:03:11 +08:00
private WorkingBeatmap beatmap ;
2018-04-13 17:19:50 +08:00
[BackgroundDependencyLoader]
2018-08-21 11:10:00 +08:00
private void load ( IBindableBeatmap beatmap )
2018-04-13 17:19:50 +08:00
{
2018-08-21 11:10:00 +08:00
this . beatmap = beatmap . Value ;
2018-08-30 12:30:23 +08:00
HitObjectContainer = CreateHitObjectContainer ( ) ;
HitObjectContainer . RelativeSizeAxes = Axes . Both ;
2018-04-13 17:19:50 +08:00
2018-08-30 12:30:23 +08:00
Add ( HitObjectContainer ) ;
2018-04-13 17:19:50 +08:00
}
/// <summary>
/// Performs post-processing tasks (if any) after all DrawableHitObjects are loaded into this Playfield.
/// </summary>
2018-07-17 14:48:51 +08:00
public virtual void PostProcess ( ) = > NestedPlayfields . ForEach ( p = > p . PostProcess ( ) ) ;
2018-04-13 17:19:50 +08:00
/// <summary>
/// Adds a DrawableHitObject to this Playfield.
/// </summary>
/// <param name="h">The DrawableHitObject to add.</param>
2018-08-30 12:30:23 +08:00
public virtual void Add ( DrawableHitObject h ) = > HitObjectContainer . Add ( h ) ;
2018-04-13 17:19:50 +08:00
/// <summary>
/// Remove a DrawableHitObject from this Playfield.
/// </summary>
/// <param name="h">The DrawableHitObject to remove.</param>
2018-08-30 12:30:23 +08:00
public virtual void Remove ( DrawableHitObject h ) = > HitObjectContainer . Remove ( h ) ;
2018-04-13 17:19:50 +08:00
/// <summary>
/// Registers a <see cref="Playfield"/> as a nested <see cref="Playfield"/>.
/// This does not add the <see cref="Playfield"/> to the draw hierarchy.
/// </summary>
/// <param name="otherPlayfield">The <see cref="Playfield"/> to add.</param>
protected void AddNested ( Playfield otherPlayfield )
{
2018-07-20 16:04:33 +08:00
otherPlayfield . DisplayJudgements . BindTo ( DisplayJudgements ) ;
2018-07-23 12:36:10 +08:00
nestedPlayfields . Value . Add ( otherPlayfield ) ;
2018-04-13 17:19:50 +08:00
}
/// <summary>
/// Creates the container that will be used to contain the <see cref="DrawableHitObject"/>s.
/// </summary>
protected virtual HitObjectContainer CreateHitObjectContainer ( ) = > new HitObjectContainer ( ) ;
2018-08-03 20:03:11 +08:00
protected override void Update ( )
{
base . Update ( ) ;
if ( beatmap ! = null )
2018-08-04 06:18:09 +08:00
foreach ( var mod in beatmap . Mods . Value )
if ( mod is IUpdatableByPlayfield updatable )
updatable . Update ( this ) ;
2018-08-03 20:03:11 +08:00
}
2018-04-13 17:19:50 +08:00
}
}