private PopulatedObjElem PopulateGraph(NodeElem baseElem, Dictionary <string, PopulatedObjElem> popElems) { var popElem = popElems[baseElem.key]; popElem.children = baseElem.children.Select(child => PopulateGraph(child, popElems)).ToArray(); return(popElem); }
public static NodeElem New(RootProps props) { var root = new NodeElem("Draggable Objects"); foreach (var keyval in props.state.objects) { var id = keyval.Key; var draggable = keyval.Value; root.Child(DraggableNode.New(new DraggableProps { key = $"Draggable {id}", position = draggable.position, size = draggable.size, onClick = () => { if (props.state.heldObject == null) { props.state.heldObject = id; } else { props.state.heldObject = null; } }, material = props.material, mesh = props.mesh, })); } return(root); }
public IEnumerator NodeElem_Render_SecondTime_NodeChanges() { var oldPopNode = new NodeElem( key: "test", layer: 2, tag: "Player", active: true ).Component( new TestComponent(value: 42) ).Render(null); var newPopNode = new NodeElem( key: "test", layer: 3, tag: "Untagged", active: false ).Component( new TestComponent(value: 7) ).Render(oldPopNode); yield return(null); Assert.That(newPopNode.obj, Is.Not.Null); Assert.That(newPopNode.obj.layer, Is.EqualTo(2)); Assert.That(newPopNode.obj.tag, Is.EqualTo("Player")); Assert.That(newPopNode.obj.activeSelf, Is.False); var monoBehaviour = newPopNode.obj.GetComponent <TestMonoBehaviour>(); Assert.That(monoBehaviour, Is.Not.Null); Assert.That(monoBehaviour.value, Is.EqualTo(42)); }
public static UReact.NodeElem New(State state, Material material, Mesh mesh) { // Create an empty node, as a parent object to organize all the draggable objects together var root = new NodeElem("Draggable Objects"); // Iterate through each of the draggables in the state, to make a child node from each foreach (var keyval in state.objects) { var id = keyval.Key; var draggable = keyval.Value; // Use the `Child` function to add a child to the root node root.Child( DraggableNode.New( id: id, position: draggable.position, size: draggable.size, onClick: () => { if (state.heldObject == null) { state.heldObject = id; } else { state.heldObject = null; } }, material: material, mesh: mesh ) ); } return(root); }
public void NodeElem_Component() { var nodeElem = new NodeElem("test"); Assert.That(nodeElem.compElems.ContainsKey(typeof(TestComponent)), Is.False); nodeElem.Component(new TestComponent(value: 42)); Assert.That(nodeElem.compElems.ContainsKey(typeof(TestComponent)), Is.True); }
public void NodeElem_Child() { var parentNode = new NodeElem("parent"); Assert.That(parentNode.children.Count, Is.EqualTo(0)); var childNode = new NodeElem("child"); parentNode.Child(childNode); Assert.That(parentNode.children.Count, Is.EqualTo(1)); Assert.That(parentNode.children[0].key, Is.EqualTo("child")); }
public void NodeElem_Render_SecondTime_PropChanges() { var oldPopNode = new NodeElem( "test" ).Component( new TestComponent(value: 42) ).Render(null); var newPopNode = new NodeElem( "test" ).Component( new TestComponent(value: 7) ).Render(oldPopNode); var monoBehaviour = newPopNode.obj.GetComponent <TestMonoBehaviour>(); Assert.That(monoBehaviour, Is.Not.Null); Assert.That(monoBehaviour.value, Is.EqualTo(7)); }
public IEnumerator NodeElem_Render_SecondTime_ComponentsChange() { var oldPopNode = new NodeElem( "test" ).Component( new TestComponent(value: 42) ).Render(null); var newPopNode = new NodeElem( "test" ).Component( new Test2Component(value: "foo") ).Render(oldPopNode); yield return(null); var test1Behaviour = newPopNode.obj.GetComponent <TestMonoBehaviour>(); var test2Behaviour = newPopNode.obj.GetComponent <Test2MonoBehaviour>(); Assert.That(test1Behaviour, Is.Null); Assert.That(test2Behaviour, Is.Not.Null); Assert.That(test2Behaviour.value, Is.EqualTo("foo")); }
public IEnumerator NodeElem_Render_FirstTime() { var popNode = new NodeElem( key: "test", layer: 2, tag: "Player", active: true ).Component( new TestComponent(value: 42) ).Render(null); yield return(null); Assert.That(popNode.elem.key, Is.EqualTo("test")); Assert.That(popNode.obj, Is.Not.Null); Assert.That(popNode.obj.name, Is.EqualTo("test")); Assert.That(popNode.obj.layer, Is.EqualTo(2)); Assert.That(popNode.obj.tag, Is.EqualTo("Player")); Assert.That(popNode.obj.activeSelf, Is.True); var monoBehaviour = popNode.obj.GetComponent <TestMonoBehaviour>(); Assert.That(monoBehaviour, Is.Not.Null); Assert.That(monoBehaviour.value, Is.EqualTo(42)); }
public NodeElem Child(NodeElem child) { children.Add(child); return(this); }
public void Render(NodeElem newGraph) { if (oldGraph == null) { oldGraph = BuildFirstTimeGraph(newGraph, null); } else { // Build dictionaries of new and old elements indexed by key, to diff against var oldElemDict = new Dictionary <string, PopulatedObjElem>(); var newElemDict = new Dictionary <string, (NodeElem, string?)>(); FillOldElemDict(oldElemDict, oldGraph.Value); FillNewElemDict(newElemDict, newGraph); // Build the creation, move and update queues, by iterating over the new // elements and comparing to the old ones var creationQueue = new List <(NodeElem, string?)>(); var moveQueue = new List <(string, string?)>(); var updateQueue = new List <string>(); foreach (var newElem in newElemDict) { if (oldElemDict.ContainsKey(newElem.Key)) { var(elem, parentKey) = newElem.Value; var oldElem = oldElemDict[newElem.Key]; if (oldElem.parentKey != parentKey) { moveQueue.Add((elem.key, parentKey)); } updateQueue.Add(elem.key); } else { creationQueue.Add(newElem.Value); } } // Build the destruction queue by iterating over the old elements and comparing // to the new ones var destructionQueue = new List <GameObject>(); foreach (var oldElem in oldElemDict) { if (!newElemDict.ContainsKey(oldElem.Key)) { destructionQueue.Add(oldElem.Value.obj); } } // As we update and create elements, they will be converted to PopulatedElements. // The set of elements in the update and create queues should exactly emcompass all // the elements in the new graph, so by the time those are processed this dictionary // should contain all of the new elements, to allow us to rebuild the graph of // populated elements at the end. var newPopElemDict = new Dictionary <string, PopulatedObjElem>(); // Execute the creation queue foreach (var(newElem, parentKey) in creationQueue) { var popElem = newElem.Render(null); if (parentKey != null) { popElem.obj.transform.SetParent(newPopElemDict[parentKey].obj.transform, false); } newPopElemDict[popElem.elem.key] = popElem; } // Execute the update queue foreach (var updateKey in updateQueue) { var oldElem = oldElemDict[updateKey]; (var newElem, _) = newElemDict[updateKey]; newPopElemDict[updateKey] = newElem.Render(oldElem); } // Execute the move queue // Do this after the creation queue, to make sure the parent objects exist. foreach (var(src, dst) in moveQueue) { if (dst == null) { newPopElemDict[src].obj.transform.SetParent(null); } else { newPopElemDict[src].obj.transform.SetParent(newPopElemDict[dst].obj.transform, false); } } // Execute the destruction queue // Do this last, so we don't inadvertently destroy children that got unparented from // this GameObject. foreach (var obj in destructionQueue) { GameObject.Destroy(obj); } // Build the new populated graph oldGraph = PopulateGraph(newGraph, newPopElemDict); } }