<commit_before>﻿// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using osu.Framework.Graphics.OpenGL;
using osu.Framework.Graphics.OpenGL.Vertices;
using osu.Framework.Graphics.Primitives;

namespace osu.Framework.Graphics
{
    public abstract partial class Drawable
    {
        private class ProxyDrawable : Drawable
        {
            private readonly ulong[] drawNodeValidationIds = new ulong[GLWrapper.MAX_DRAW_NODES];
            private readonly DrawNode[] originalDrawNodes;

            internal ProxyDrawable(Drawable original)
            {
                Original = original;
                originalDrawNodes = (original as ProxyDrawable)?.originalDrawNodes ?? original.drawNodes;
            }

            internal override void ValidateProxyDrawNode(int treeIndex, ulong frame)
            {
                if (HasProxy)
                {
                    // Proxy of a proxy - forward the next proxy
                    base.ValidateProxyDrawNode(treeIndex, frame);
                    return;
                }

                drawNodeValidationIds[treeIndex] = frame;
            }

            protected override DrawNode CreateDrawNode() => new ProxyDrawNode(this);

            internal override DrawNode GenerateDrawNodeSubtree(ulong frame, int treeIndex, bool forceNewDrawNode)
            {
                var node = (ProxyDrawNode)base.GenerateDrawNodeSubtree(frame, treeIndex, forceNewDrawNode);

                node.DrawNodeIndex = treeIndex;
                node.FrameCount = frame;

                return node;
            }

            internal sealed override Drawable Original { get; }

            public override bool RemoveWhenNotAlive => base.RemoveWhenNotAlive && Original.RemoveWhenNotAlive;

            protected internal override bool ShouldBeAlive => base.ShouldBeAlive && Original.ShouldBeAlive;

            // We do not want to receive updates. That is the business of the original drawable.
            public override bool IsPresent => false;

            public override bool UpdateSubTreeMasking(Drawable source, RectangleF maskingBounds) => Original.UpdateSubTreeMasking(this, maskingBounds);

            private class ProxyDrawNode : DrawNode
            {
                /// <summary>
                /// The index of the original draw node to draw.
                /// </summary>
                public int DrawNodeIndex;

                /// <summary>
                /// The current draw frame index.
                /// If this differs from the frame index of the original draw node, the original drawable will have not been drawn this frame.
                /// </summary>
                public ulong FrameCount;

                protected new ProxyDrawable Source => (ProxyDrawable)base.Source;

                public ProxyDrawNode(ProxyDrawable proxyDrawable)<commit_msg>Fix ProxyDrawable not transferring lifetime<commit_after>﻿// Copyright (c) ppy <NAME> <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using osu.Framework.Graphics.OpenGL;
using osu.Framework.Graphics.OpenGL.Vertices;
using osu.Framework.Graphics.Primitives;

namespace osu.Framework.Graphics
{
    public abstract partial class Drawable
    {
        private class ProxyDrawable : Drawable
        {
            private readonly ulong[] drawNodeValidationIds = new ulong[GLWrapper.MAX_DRAW_NODES];
            private readonly DrawNode[] originalDrawNodes;

            internal ProxyDrawable(Drawable original)
            {
                Original = original;
                originalDrawNodes = (original as ProxyDrawable)?.originalDrawNodes ?? original.drawNodes;

                original.LifetimeChanged += _ => LifetimeChanged?.Invoke(this);
            }

            internal override void ValidateProxyDrawNode(int treeIndex, ulong frame)
            {
                if (HasProxy)
                {
                    // Proxy of a proxy - forward the next proxy
                    base.ValidateProxyDrawNode(treeIndex, frame);
                    return;
                }

                drawNodeValidationIds[treeIndex] = frame;
            }

            protected override DrawNode CreateDrawNode() => new ProxyDrawNode(this);

            internal override DrawNode GenerateDrawNodeSubtree(ulong frame, int treeIndex, bool forceNewDrawNode)
            {
                var node = (ProxyDrawNode)base.GenerateDrawNodeSubtree(frame, treeIndex, forceNewDrawNode);

                node.DrawNodeIndex = treeIndex;
                node.FrameCount = frame;

                return node;
            }

            internal sealed override Drawable Original { get; }

            public override bool RemoveWhenNotAlive => Original.RemoveWhenNotAlive;

            protected internal override bool ShouldBeAlive => Original.ShouldBeAlive;

            public override double LifetimeStart => Original.LifetimeStart;

            public override double LifetimeEnd => Original.LifetimeEnd;

            // We do not want to receive updates. That is the business of the original drawable.
            public override bool IsPresent => false;

            public override bool UpdateSubTreeMasking(Drawable source, RectangleF maskingBounds) => Original.UpdateSubTreeMasking(this, maskingBounds);

            private class ProxyDrawNode : DrawNode
            {
                /// <summary>
                /// The index of the original draw node to draw.
                /// </summary>
                public int DrawNodeIndex;

                /// <summary>
                /// The current draw frame index.
                /// If this differs from the frame index of the original draw node, the original drawable will have not been drawn this frame.
                /// </summary>
                public ulong FrameCount;

                protected new ProxyDrawable Source => (ProxyDrawable)base.Source;

                public ProxyDrawNode(ProxyDrawable proxyDrawable)
{'fraction_non_alphanumeric': 0.0656112289864534, 'fraction_numerical': 0.0, 'mean_word_length': 1.9661181026137464, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3100259', 'n_tokens_mistral': 1454, 'n_tokens_neox': 1379, 'n_words': 446}