// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Runtime.CompilerServices; using osu.Framework.Layout; namespace osu.Framework.Graphics { /// /// Contains the internal logic for the state management of . /// internal struct InvalidationList { private Invalidation selfInvalidation; private Invalidation parentInvalidation; private Invalidation childInvalidation; /// /// Creates a new . /// /// The initial invalidation state. public InvalidationList(Invalidation initialState) { this = default; invalidate(ref selfInvalidation, initialState); invalidate(ref parentInvalidation, initialState); invalidate(ref childInvalidation, initialState); } /// /// Invalidates a with given flags. /// /// The to invalidate. /// The flags to invalidate with. /// Whether an invalidation was performed. /// If was not a valid source. [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Invalidate(InvalidationSource source, Invalidation flags) { switch (source) { case InvalidationSource.Self: return invalidate(ref selfInvalidation, flags); case InvalidationSource.Parent: return invalidate(ref parentInvalidation, flags); case InvalidationSource.Child: return invalidate(ref childInvalidation, flags); default: throw new ArgumentException("Unexpected invalidation source.", nameof(source)); } } /// /// Validates all s with given flags. /// /// The flags to validate with. /// Whether any was validated. [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Validate(Invalidation validation) { return validate(ref selfInvalidation, validation) | validate(ref parentInvalidation, validation) | validate(ref childInvalidation, validation); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool invalidate(ref Invalidation target, Invalidation flags) { if ((target & flags) == flags) return false; // Remove all non-layout flags, as they should always propagate and are thus not to be stored. target |= flags & Invalidation.Layout; return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool validate(ref Invalidation target, Invalidation flags) { if ((target & flags) == 0) return false; target &= ~flags; return true; } } }