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) { bool delta = lastObject == null || hitObject.HitType != lastObject.HitType; if (delta == previous.Delta) { previous.DeltaRunLength += 1; return previous; } else { // Calculate RepetitionInterval for previous previous.RepetitionInterval = findRepetitionInterval(previous); return new TaikoDifficultyHitObjectColour() { Delta = delta, DeltaRunLength = 1, RepetitionInterval = -1, previous = previous }; } } /// /// Finds the closest previous that has the identical delta value /// and run length to target, and returns the amount of notes between them. /// private static int findRepetitionInterval(TaikoDifficultyHitObjectColour target) { if (target.previous == null || target.previous.previous == null) return -1; int interval = target.previous.DeltaRunLength; TaikoDifficultyHitObjectColour other = target.previous.previous; while(other != null && interval < max_repetition_interval) { if (other.Delta == target.Delta && other.DeltaRunLength == target.DeltaRunLength) return interval; else interval += other.DeltaRunLength; other = other.previous; } return -1; } } }