mirror of
https://github.com/SK-la/osu-framework.git
synced 2026-03-13 11:20:31 +00:00
117 lines
4.1 KiB
C#
117 lines
4.1 KiB
C#
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
#nullable disable
|
|
|
|
using osu.Framework.Graphics.Rendering;
|
|
|
|
namespace osu.Framework.Graphics
|
|
{
|
|
public abstract partial class Drawable
|
|
{
|
|
private partial class ProxyDrawable : Drawable
|
|
{
|
|
private readonly ulong[] drawNodeValidationIds = new ulong[IRenderer.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() => true;
|
|
|
|
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)
|
|
: base(proxyDrawable)
|
|
{
|
|
}
|
|
|
|
protected override void DrawOpaqueInterior(IRenderer renderer)
|
|
{
|
|
if (getCurrentFrameSource() != null)
|
|
DrawOtherOpaqueInterior(getCurrentFrameSource(), renderer);
|
|
}
|
|
|
|
protected override void Draw(IRenderer renderer)
|
|
{
|
|
if (getCurrentFrameSource() != null)
|
|
DrawOther(getCurrentFrameSource(), renderer);
|
|
}
|
|
|
|
protected internal override bool CanDrawOpaqueInterior => getCurrentFrameSource()?.CanDrawOpaqueInterior ?? false;
|
|
|
|
private DrawNode getCurrentFrameSource()
|
|
{
|
|
var target = Source.originalDrawNodes[DrawNodeIndex];
|
|
|
|
if (target == null)
|
|
return null;
|
|
|
|
if (Source.drawNodeValidationIds[DrawNodeIndex] != FrameCount)
|
|
return null;
|
|
|
|
if (target.IsDisposed)
|
|
return null;
|
|
|
|
return target;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|