Files
MicrosoftIris/UIX.RenderApi/Microsoft/Iris/Render/Graphics/TreeNode.cs
T
2022-03-03 08:40:19 -06:00

272 lines
9.0 KiB
C#

// Decompiled with JetBrains decompiler
// Type: Microsoft.Iris.Render.Graphics.TreeNode
// Assembly: UIX.RenderApi, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
// MVID: D47658B8-A8EA-43D6-8837-ECE823BFFFC1
// Assembly location: C:\Program Files\Zune\UIX.RenderApi.dll
using Microsoft.Iris.Render.Common;
using System;
using System.Diagnostics;
namespace Microsoft.Iris.Render.Graphics
{
internal abstract class TreeNode : CachedRenderObject
{
private static int s_idObject;
private ITreeOwner m_treeOwner;
private int m_idObject;
private TreeNode m_nodeParent;
private TreeNode m_nodeFirstChild;
private TreeNode m_nodeNext;
private TreeNode m_nodePrevious;
public static int s_DEBUG_nTotalNodes;
internal TreeNode(ITreeOwner iTreeOwner)
{
Debug2.Validate(iTreeOwner != null, typeof(ArgumentNullException), "Must have a valid ITreeOwner when creating a TreeNode");
this.m_treeOwner = iTreeOwner;
}
protected override void Dispose(bool fInDispose)
{
try
{
if (fInDispose)
{
this.ChangeParent(null);
this.RemoveAllChildren();
}
this.m_treeOwner = null;
}
finally
{
base.Dispose(fInDispose);
}
}
private ITreeOwner Tree => this.m_treeOwner;
internal bool HasChildren => this.m_nodeFirstChild != null;
internal bool IsRoot => this.m_treeOwner.Root == this;
internal TreeNode Parent => this.m_nodeParent;
internal TreeNode NextSibling => this.m_nodeNext;
internal TreeNode PreviousSibling => this.m_nodePrevious;
internal TreeNode FirstSibling => this.m_nodeParent == null ? this : this.m_nodeParent.m_nodeFirstChild;
internal TreeNode LastSibling
{
get
{
TreeNode treeNode = this;
while (treeNode.m_nodeNext != null)
treeNode = treeNode.m_nodeNext;
return treeNode;
}
}
internal TreeNode FirstChild => this.m_nodeFirstChild;
internal TreeNode LastChild => this.m_nodeFirstChild != null ? this.m_nodeFirstChild.LastSibling : null;
internal TreeNodeCollection Children => new TreeNodeCollection(this);
internal AncestorEnumerator Ancestors => new AncestorEnumerator(this);
internal bool HasDescendant(TreeNode nodeOther)
{
for (; nodeOther != null; nodeOther = nodeOther.m_nodeParent)
{
if (nodeOther == this)
return true;
}
return false;
}
public int ChildCount
{
get
{
int num = 0;
for (TreeNode treeNode = this.m_nodeFirstChild; treeNode != null; treeNode = treeNode.m_nodeNext)
++num;
return num;
}
}
internal virtual void RemoveAllChildren()
{
while (this.m_nodeFirstChild != null)
this.m_nodeFirstChild.ChangeParent(null);
}
internal void ChangeParent(TreeNode nodeNewParent) => this.ChangeParent(nodeNewParent, null, LinkType.First);
internal void ChangeParent(TreeNode nodeNewParent, TreeNode nodeSibling, TreeNode.LinkType lt)
{
if (this.m_nodeParent == nodeNewParent)
return;
TreeNode nodeParent = this.m_nodeParent;
if (this.m_nodeParent != null)
DoUnlink(this);
if (nodeNewParent != null)
DoLink(nodeNewParent, this, nodeSibling, lt);
if (nodeParent == null && nodeNewParent != null)
{
this.RegisterUsage(this);
}
else
{
if (nodeParent == null || nodeNewParent != null)
return;
this.UnregisterUsage(this);
}
}
private static void DoLink(
TreeNode nodeParent,
TreeNode nodeChange,
TreeNode nodeSibling,
TreeNode.LinkType lt)
{
nodeChange.m_nodeParent = nodeParent;
TreeNode nodeFirstChild = nodeParent.m_nodeFirstChild;
if (nodeFirstChild == null)
{
nodeParent.m_nodeFirstChild = nodeChange;
}
else
{
switch (lt)
{
case LinkType.Before:
nodeChange.m_nodeNext = nodeSibling;
nodeChange.m_nodePrevious = nodeSibling.m_nodePrevious;
nodeSibling.m_nodePrevious = nodeChange;
if (nodeChange.m_nodePrevious != null)
{
nodeChange.m_nodePrevious.m_nodeNext = nodeChange;
break;
}
nodeParent.m_nodeFirstChild = nodeChange;
break;
case LinkType.Behind:
nodeChange.m_nodePrevious = nodeSibling;
nodeChange.m_nodeNext = nodeSibling.m_nodeNext;
nodeSibling.m_nodeNext = nodeChange;
if (nodeChange.m_nodeNext == null)
break;
nodeChange.m_nodeNext.m_nodePrevious = nodeChange;
break;
case LinkType.First:
nodeParent.m_nodeFirstChild = nodeChange;
nodeChange.m_nodeNext = nodeFirstChild;
if (nodeFirstChild == null)
break;
nodeFirstChild.m_nodePrevious = nodeChange;
break;
case LinkType.Last:
TreeNode lastSibling = nodeFirstChild.LastSibling;
lastSibling.m_nodeNext = nodeChange;
nodeChange.m_nodePrevious = lastSibling;
break;
}
}
}
private static void DoUnlink(TreeNode nodeChange)
{
if (nodeChange.m_nodeParent.m_nodeFirstChild == nodeChange)
nodeChange.m_nodeParent.m_nodeFirstChild = nodeChange.m_nodeNext;
if (nodeChange.m_nodeNext != null)
nodeChange.m_nodeNext.m_nodePrevious = nodeChange.m_nodePrevious;
if (nodeChange.m_nodePrevious != null)
nodeChange.m_nodePrevious.m_nodeNext = nodeChange.m_nodeNext;
nodeChange.m_nodeParent = null;
nodeChange.m_nodeNext = null;
nodeChange.m_nodePrevious = null;
}
internal int InstanceID
{
get
{
if (this.m_idObject == 0)
this.SetInstanceID(GenerateInstanceID());
return this.m_idObject;
}
}
private static int GenerateInstanceID() => ++s_idObject;
private void SetInstanceID(int idObject) => this.m_idObject = idObject;
public override int GetHashCode() => this.InstanceID;
public override bool Equals(object oRHS) => ReferenceEquals(this, oRHS);
public bool TestNodes(
TreeNode.NodeTest test,
TreeNode.NodeRelation nScope,
bool fParentChainsMustGoToRoot)
{
if ((nScope & NodeRelation.FullChain) == NodeRelation.None || (nScope & NodeRelation.Self) != NodeRelation.None && !test(this))
return false;
if ((nScope & NodeRelation.Parents) != NodeRelation.None)
{
TreeNode node = this;
do
{
TreeNode parent = node.Parent;
if (parent != null)
node = parent;
else
goto label_7;
}
while (test(node));
return false;
label_7:
if (fParentChainsMustGoToRoot && node != this.m_treeOwner.Root)
return false;
}
return true;
}
internal int DEBUG_CurrentGeneration => 0;
[Conditional("DEBUG")]
internal void DEBUG_CheckGeneration(int idxIntendedGeneration)
{
}
[Conditional("DEBUG")]
internal void DEBUG_IncTotalNodes() => ++s_DEBUG_nTotalNodes;
[Conditional("DEBUG")]
internal void DEBUG_DecTotalNodes() => --s_DEBUG_nTotalNodes;
internal enum LinkType
{
Before = 1,
Behind = 2,
First = 3,
Last = 4,
}
[Flags]
public enum NodeRelation
{
None = 0,
Self = 1,
Parents = 2,
FullChain = Parents | Self, // 0x00000003
}
public delegate bool NodeTest(TreeNode node);
}
}