namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing { /// /// Stores colour compression information for a . /// public class TaikoDifficultyHitObjectColour { const int max_repetition_interval = 16; private TaikoDifficultyHitObjectColour previous; /// /// True if the current colour is different from the previous colour. /// public bool Delta { get; private set; } /// /// How many notes are Delta repeated /// public int DeltaRunLength { get; private set; } /// /// How many notes between the current and previous identical . /// Negative number means that there is no repetition in range. /// public int RepetitionInterval { get; private set; } /// /// Get the instance for the given hitObject. This is implemented /// as a static function instead of constructor to allow for reusing existing instances. /// TODO: findRepetitionInterval needs to be called a final time after all hitObjects have been processed. /// public static TaikoDifficultyHitObjectColour GetInstanceFor( TaikoDifficultyHitObject hitObject, TaikoDifficultyHitObject lastObject) { TaikoDifficultyHitObjectColour previous = lastObject?.Colour; bool delta = lastObject == null || hitObject.HitType != lastObject.HitType; if (previous != null && delta == previous.Delta) { previous.DeltaRunLength += 1; return previous; } else { // Calculate RepetitionInterval for previous previous?.FindRepetitionInterval(); return new TaikoDifficultyHitObjectColour() { Delta = delta, DeltaRunLength = 1, RepetitionInterval = -1, previous = previous }; } } /// /// Finds the closest previous that has the identical delta value /// and run length with the current instance, and returns the amount of notes between them. /// public void FindRepetitionInterval() { if (this.previous == null || this.previous.previous == null) { this.RepetitionInterval = -1; return; } int interval = this.previous.DeltaRunLength; TaikoDifficultyHitObjectColour other = this.previous.previous; while (other != null && interval < max_repetition_interval) { if (other.Delta == this.Delta && other.DeltaRunLength == this.DeltaRunLength) { this.RepetitionInterval = interval; return; } else { interval += other.DeltaRunLength; } other = other.previous; } this.RepetitionInterval = -1; } } }