protected override void OnInsertNode(ISceneGraphNode node, ISceneGraphNode parent, int siblingIndex) { var parentEntity = new Parent { Value = (parent as EntityNode)?.Entity ?? Entity.Null }; switch (node) { case EntityNode entityNode: { var entity = entityNode.Entity; if (m_EntityManager.HasComponent <Parent>(entity)) { m_EntityManager.SetComponentData(entity, parentEntity); } else { m_EntityManager.AddComponentData(entity, parentEntity); } m_Scene.AddEntityReference(m_EntityManager, entity); TransferScene(node.Children); } break; } if (null != parent) { ForceSiblingIndex(parent.Children, false); } else { ForceSiblingIndex(false); } }
/// <inheritdoc /> public void Add(IEnumerable <ISceneGraphNode> nodes, ISceneGraphNode parent = null) { foreach (var node in nodes) { Add(node, parent); } }
private void BuildFromNode(ISceneGraphNode node, TreeViewItem parentItem, SearchingScope search) { TreeViewItem item = null; switch (node) { case EntityNode entityNode: { item = new EntityItem(m_Session, entityNode.Entity, entityNode.Guid, entityNode); if (search.IsSearching) { if (search.Map.TryGetValue(entityNode.Entity, out _)) { parentItem.AddChild(item); } } else { parentItem.AddChild(item); } } break; } if (null == item) { return; } foreach (var child in node.Children) { BuildFromNode(child, string.IsNullOrEmpty(m_FilterString) ? item : parentItem, search); } }
/// <inheritdoc /> /// <summary> /// Duplicates the given node and all of it's children /// </summary> public ISceneGraphNode Duplicate(ISceneGraphNode source) { // Create the new node and all children from the source var target = CreateNodes(source, source.Parent); Remap(source, target); return(target); }
/// <summary> /// Enumerates all ancestors /// /// @NOTE Includes self (should the naming be changed?) /// </summary> public static IEnumerable <ISceneGraphNode> GetAncestors(this ISceneGraphNode node) { while (null != node) { yield return(node); node = node.Parent; } }
protected override void OnDeleteNode(ISceneGraphNode node) { switch (node) { case EntityNode entityNode: { m_EntityManager.DestroyEntity(entityNode.Entity); } break; } }
private static EntityNode FindEntityNodeRecursive(ISceneGraphNode node, Guid guid) { if (node is EntityNode entityNode && entityNode.Guid == guid) { return(entityNode); } return(node.Children .Select(r => FindEntityNodeRecursive(r, guid)) .FirstOrDefault(r => null != r)); }
/// <summary> /// Clones /// </summary> /// <param name="source"></param> /// <param name="parent"></param> /// <returns></returns> private ISceneGraphNode CreateNodes(ISceneGraphNode source, ISceneGraphNode parent) { // @NOTE Adding to the graph should be handled in `CreateNode` implementation var node = CreateNode(source, parent); foreach (var child in source.Children) { CreateNodes(child, node); } return(node); }
/// <summary> /// Gathers all descendants and adds them to the given collection /// /// @NOTE Includes self (should the naming be changed?) /// </summary> public static IEnumerable <ISceneGraphNode> GetDescendants(this ISceneGraphNode node) { yield return(node); foreach (var child in node.Children) { foreach (var descendant in child.GetDescendants()) { yield return(descendant); } } }
public void Insert(int siblingIndex, IEnumerable <ISceneGraphNode> nodes, ISceneGraphNode parent = null) { foreach (var node in nodes) { if (node.IsAncestorOrParentOf(parent)) { continue; } Insert(siblingIndex, node, parent); siblingIndex += siblingIndex < 0 ? 0 : 1; } }
private int DoSortBySiblingIndex(ISceneGraphNode x, ISceneGraphNode y) { if (!(y is EntityNode rhs)) { return(-1); } if (!(x is EntityNode lhs)) { return(1); } return(lhs.Index.Index.CompareTo(rhs.Index.Index)); }
private DragAndDropVisualMode DoHandleSingleObjectDrop <TObject>(DragAndDropArgs args, TObject o, int offset) { var handler = HierarchyDragAndDrop <TObject, Key> .SingleObjectDrop; if (null == handler) { return(DragAndDropVisualMode.Rejected); } var item = GetDragAndDropItem(args); var result = DragAndDropVisualMode.Rejected; ISceneGraphNode resultNode = null; if (item is SceneItem sceneItem) { if (null != (resultNode = handler(m_Session, o, sceneItem.Graph, null, args.dragAndDropPosition == DragAndDropPosition.BetweenItems ? args.insertAtIndex : -1))) { IdsToExpand.Add(sceneItem.id); result = DragAndDropVisualMode.Link; } } if (item is EntityItem entityItem) { var node = entityItem.Node; if (null != (resultNode = handler(m_Session, o, node.Graph as SceneGraph, node, args.dragAndDropPosition == DragAndDropPosition.BetweenItems ? args.insertAtIndex : -1))) { IdsToExpand.Add(entityItem.id); result = DragAndDropVisualMode.Link; } } if (null == resultNode) { return(DragAndDropVisualMode.Rejected); } if (result == DragAndDropVisualMode.Link) { if (resultNode is EntityNode entityNode) { EntityHierarchyWindow.SelectOnNextPaint(entityNode.Guid); } } return(result); }
/// <summary> /// Returns true if the node is a direct child or any level descendant of the given node /// </summary> public static bool IsDescendantOrChildOf(this ISceneGraphNode self, ISceneGraphNode node) { var parent = self.Parent; while (null != parent) { if (node == parent) { return(true); } parent = parent.Parent; } return(false); }
/// <summary> /// Returns true if the node is a direct parent or any level ancestor of the given node /// </summary> public static bool IsAncestorOrParentOf(this ISceneGraphNode self, ISceneGraphNode node) { if (self == node) { return(true); } foreach (var child in self.Children) { if (child == node || child.IsAncestorOrParentOf(node)) { return(true); } } return(false); }
public static void SetParent(this ISceneGraphNode self, int siblingIndex, ISceneGraphNode parent) { // Cannot SetParent on a node that is part of the children. if (self.IsAncestorOrParentOf(parent)) { return; } // We defer the operations to the owning graph, since the current node and the parent node may not be in the // same graph. if (null == parent) { self.Graph.Insert(siblingIndex, self); } else { parent.Graph.Insert(siblingIndex, self, parent); } }
/// <inheritdoc /> public bool Remove(List <ISceneGraphNode> inspect, ISceneGraphNode node) { if (inspect.Remove(node)) { OnRemoveNode(node); Changed = true; return(true); } foreach (var n in inspect) { if (Remove(n.Children, node)) { return(true); } } return(false); }
protected override ISceneGraphNode CreateNode(ISceneGraphNode source, ISceneGraphNode parent) { if (source is EntityNode sourceNode) { var targetEntity = m_EntityManager.CreateEntity(m_EntityManager.GetChunk(sourceNode.Entity).Archetype); var sourceEntity = sourceNode.Entity; var visitor = new CopyVisitor(m_EntityManager, sourceEntity, targetEntity); PropertyContainer.Visit(new EntityContainer(m_EntityManager, sourceEntity), visitor); m_WorldManager.SetEntityGuid(targetEntity, Guid.NewGuid()); var entityNode = new EntityNode(this, m_Session, targetEntity); var newEntityName = EntityNameHelper.GetUniqueEntityName(m_WorldManager.GetEntityName(targetEntity), m_WorldManager, parent?.Children ?? Roots); m_WorldManager.SetEntityName(targetEntity, newEntityName); Add(entityNode, parent); return(entityNode); } return(null); }
public bool Delete(ISceneGraphNode node) { if (null == node) { return(false); } Assert.IsTrue(this == node.Graph); if (!Remove(Roots, node)) { return(false); } foreach (var n in node.GetDescendants()) { OnDeleteNode(n); } return(true); }
/// <summary> /// Returns true if the node is a direct child or any level descendant of the given nodes /// </summary> public static bool IsDescendantOrChildOf(this ISceneGraphNode self, List <ISceneGraphNode> candidates) { var parents = ListPool <ISceneGraphNode> .Get(); try { var parent = self.Parent; while (null != parent) { parents.Add(parent); parent = parent.Parent; } return(parents.Intersect(candidates).Any()); } finally { ListPool <ISceneGraphNode> .Release(parents); } }
public static TNode GetFirstAncestorOfType <TNode>(this ISceneGraphNode node) where TNode : class { if (null == node) { return(null); } var parent = node.Parent; while (null != parent) { if (parent is TNode typed) { return(typed); } parent = parent.Parent; } return(null); }
/// <inheritdoc /> public void Insert(int siblingIndex, ISceneGraphNode node, ISceneGraphNode parent = null) { if (node.IsAncestorOrParentOf(parent)) { // The node is already an ancestor of the given node. Bail out. return; } if (this != node.Graph) { // Remove this node from the previous graph; if any node.Graph.Remove(node.Graph.Roots, node); // We are moving from another graph, remap our descendants to this new graph foreach (var descendant in node.GetDescendants()) { descendant.Graph = this; } } // Remove from previous parent or roots; if any if (null != node.Parent) { node.Parent.Children.Remove(node); } else { Roots.Remove(node); } node.Parent = parent; var actualIndex = InsertOrAdd(null == node.Parent ? Roots : node.Parent.Children, siblingIndex, node); // Handle any custom operations in this callback OnInsertNode(node, parent, actualIndex); Changed = true; }
protected override void Remap(ISceneGraphNode source, ISceneGraphNode target) { // Extract all entities from the source and target trees var sourceEntities = source.GetDescendants().OfType <EntityNode>().Select(n => n.Entity).ToList(); var targetEntities = target.GetDescendants().OfType <EntityNode>().Select(n => n.Entity).ToList(); Assert.IsTrue(sourceEntities.Count == targetEntities.Count); // Build the remap information var entityReferenceRemap = new Dictionary <Entity, Entity>(); for (var i = 0; i < sourceEntities.Count; i++) { entityReferenceRemap.Add(sourceEntities[i], targetEntities[i]); } var visitor = new RemapVisitor(entityReferenceRemap); // Remap each component of the target tree foreach (var entity in targetEntities) { PropertyContainer.Visit(new EntityContainer(m_EntityManager, entity), visitor); } }
public void Insert(int siblingIndex, ISceneGraphNode child) { child?.SetParent(siblingIndex, this); }
/// <summary> /// Invoked when deleting a node from the graph /// /// @note This is NOT the same as a removal /// </summary> /// <param name="node">The node being deleted</param> protected virtual void OnDeleteNode(ISceneGraphNode node) { }
public void Insert(ISceneGraphNode child) => Insert(-1, child);
public void Add(ISceneGraphNode node, ISceneGraphNode parent = null) { Insert(-1, node, parent); }
public bool IsRoot(ISceneGraphNode node) { return(Roots.Contains(node)); }
/// <summary> /// Returns true if the node is a direct child of the given node /// </summary> public static bool IsChildOf(this ISceneGraphNode self, ISceneGraphNode node) { return(null != node && node.Children.Contains(self)); }
public static int SiblingIndex(this ISceneGraphNode node) { return(node.Parent?.Children.IndexOf(node) ?? node.Graph.Roots.IndexOf(node)); }
public static void SetParent(this ISceneGraphNode self, ISceneGraphNode parent) { self.SetParent(-1, parent); }