// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Edit { public abstract class DrawableEditRuleset : CompositeDrawable { /// /// The contained by this . /// public abstract Playfield Playfield { get; } public abstract PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer(); internal DrawableEditRuleset() { RelativeSizeAxes = Axes.Both; } /// /// Adds a to the and displays a visual representation of it. /// /// The to add. /// The visual representation of . internal abstract DrawableHitObject Add(HitObject hitObject); /// /// Removes a from the and the display. /// /// The to remove. /// The visual representation of the removed . internal abstract DrawableHitObject Remove(HitObject hitObject); } public class DrawableEditRuleset : DrawableEditRuleset where TObject : HitObject { public override Playfield Playfield => drawableRuleset.Playfield; public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => drawableRuleset.CreatePlayfieldAdjustmentContainer(); private Ruleset ruleset => drawableRuleset.Ruleset; private Beatmap beatmap => drawableRuleset.Beatmap; private readonly DrawableRuleset drawableRuleset; public DrawableEditRuleset(DrawableRuleset drawableRuleset) { this.drawableRuleset = drawableRuleset; InternalChild = drawableRuleset; Playfield.DisplayJudgements.Value = false; } internal override DrawableHitObject Add(HitObject hitObject) { var tObject = (TObject)hitObject; // Add to beatmap, preserving sorting order var insertionIndex = beatmap.HitObjects.FindLastIndex(h => h.StartTime <= hitObject.StartTime); beatmap.HitObjects.Insert(insertionIndex + 1, tObject); // Process object var processor = ruleset.CreateBeatmapProcessor(beatmap); processor?.PreProcess(); tObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty); processor?.PostProcess(); // Add visual representation var drawableObject = drawableRuleset.CreateDrawableRepresentation(tObject); drawableRuleset.Playfield.Add(drawableObject); drawableRuleset.Playfield.PostProcess(); return drawableObject; } internal override DrawableHitObject Remove(HitObject hitObject) { var tObject = (TObject)hitObject; // Remove from beatmap beatmap.HitObjects.Remove(tObject); // Process the beatmap var processor = ruleset.CreateBeatmapProcessor(beatmap); processor?.PreProcess(); processor?.PostProcess(); // Remove visual representation var drawableObject = Playfield.AllHitObjects.Single(d => d.HitObject == hitObject); drawableRuleset.Playfield.Remove(drawableObject); drawableRuleset.Playfield.PostProcess(); return drawableObject; } } }