Example #1
0
 public void LayoutTracker_leak_test()
 {
     RunInMainThread(() =>
     {
         AssertIsGarbageCollected(
             () =>
         {
             BehaviorSubject <IEnumerable <IControl> > innerControls =
                 new BehaviorSubject <IEnumerable <IControl> >(Enumerable.Empty <IControl>());
             var container = LayoutTracker.Create(
                 x => innerControls.CachePerElement(y => x.TrackVisualBounds(frame => { }, y)).StackFromLeft());
             container.MountRoot();
             return(new { innerControls, container });
         },
             env =>
         {
             var innerControls   = env.innerControls;
             var rectangleHeight = new BehaviorSubject <Points>(33);
             var rectangle       = Shapes.Rectangle(fill: Brush.Transparent).WithWidth(rectangleHeight);
             Assert.That(rectangleHeight.HasObservers, Is.False);
             innerControls.OnNext(new[] { rectangle });
             Assert.That(rectangleHeight.HasObservers, Is.True);
             innerControls.OnNext(Enumerable.Empty <IControl>());
             Assert.That(rectangleHeight.HasObservers, Is.False);
             return(rectangle);
         });
     });
 }
Example #2
0
    private void spawnSpell(LayoutTracker prefab, Combinator combinator)
    {
        LayoutTracker newSpell = Instantiate(prefab, transform);

        newSpell.enabled = false;
        newSpell.gameObject.AddComponent <LayoutElement>();
    }
Example #3
0
    // Call this to pop the undo stack onto the goal
    public void undo()
    {
        // Invoke the undoTermEvent with the top term, so that the real goal symbol manager can update itself
        if (stack.Count < 1)
        {
            Debug.LogWarning("Tried to undo when there's nothing on the undo stack. Ignoring it.");
            return;
        }
        undoTermEvent.Invoke(stack.Pop());

        // Delete the current term
        if (currentLayoutTracker)
        {
            Destroy(currentLayoutTracker.gameObject);
            currentLayoutTracker = null;
        }

        // If there's no next undo term, that's fine
        if (stack.Count < 1)
        {
            return;
        }

        // Place the next undo term
        Term nextUndoTerm = stack.Peek();

        currentLayoutTracker = symbolManager.Initialize(nextUndoTerm);
    }
    // Set the alpha of the currentLayout parens (top level parens) to 0
    private void resetParensAlpha(LayoutTracker layoutTracker)
    {
        Image image = layoutTracker.GetComponent <Image>();
        Color c     = image.color;

        image.color = new Color(c.r, c.g, c.b, .0f);
    }
Example #5
0
    private IEnumerator addParen(AddParenRule rule, LayoutTracker TopSymbol)
    {
        var parent = AccessTransfrom(TopSymbol.transform, rule.path);
        var lt     = Instantiate(parenSymbol, parent);

        lt.root = skeletonRoot;
        List <Transform> children = new List <Transform>();

        for (int i = 0; i < rule.size; i++)
        {
            children.Add(parent.GetChild(i));
        }
        lt.transform.SetAsFirstSibling();
        foreach (Transform transform in children)
        {
            transform.SetParent(lt.transform, true);
        }

        foreach (Transform child in skeletonRoot)
        {
            Destroy(child.gameObject);
        }
        CreateSkeleton(rule.oldTerm, skeletonRoot);
        yield return(new WaitUntil(() => !lt.Moving()));
    }
    private void Start()
    {
        currentLayout = manager.Initialize(Term.Node(new List <Term>())).GetComponentInChildren <LayoutTracker>();
        resetParensAlpha(currentLayout);

        Destroy(currentLayout.GetComponent <DraggableSpell>());
    }
Example #7
0
 public BackwardTermData(Term newTerm, Func <LayoutTracker> lt, Combinator c, List <int> path, LayoutTracker topSymbol)
 {
     this.newTerm = newTerm;
     this.lt      = lt;
     C            = c;
     this.path    = path;
     TopSymbol    = topSymbol;
 }
Example #8
0
 public BackwardParenData(List <int> path, int size, Func <LayoutTracker> paren, LayoutTracker topSymbol, Term newTerm)
 {
     this.path    = path;
     this.size    = size;
     this.paren   = paren;
     TopSymbol    = topSymbol;
     this.newTerm = newTerm;
 }
Example #9
0
    public LayoutTracker RemoveAtAndReturn(List <int> path, LayoutTracker root)
    {
        var index = path[path.Count - 1];

        path = path.Take(path.Count - 1).ToList();
        var new_term = currentTerm.ApplyAt(parenTerm => parenTerm.Match(l =>
        {
            l = l.ToList();
            var RemovedTerm = l[index];
            l.RemoveAt(index);
            RemovedTerm.Match(children =>
            {
                children.Reverse();
                foreach (Term child in children)
                {
                    l.Insert(index, child);
                }
            }, _ => { /* already removed */ });
            return(Term.Node(l));
        }

                                                                        , x => throw new Exception("Depth Exception")), path);

        foreach (Transform t in skeletonRoot)
        {
            if (Application.isPlaying)
            {
                Destroy(t.gameObject);
            }
        }
        var Paren = AccessTransfrom(root.transform, path);

        var Removed = Paren.GetChild(index);

        if (0 < Removed.childCount)
        {
            backwardUndoStack = new Stack <Sum <BackwardTermData, BackwardParenData> >();
            //forwardUndoStack.Push(new ForwardData(Sum<ElimRule, AddParenRule>.Inl(new ParenElim(path)), root));
            forwardUndoStack.Push(new ForwardData(Sum <ElimRule, AddParenRule> .Inr(new AddParenRule(path, Removed.childCount, currentTerm)), root));
        }

        CreateSkeleton(new_term, skeletonRoot); //sets new term
        List <Transform> ts = new List <Transform>();

        foreach (Transform t in Removed.transform)
        {
            ts.Add(t);
        }

        ts.Reverse();
        foreach (Transform t in ts)
        {
            t.SetParent(Paren);
            t.SetSiblingIndex(index);
        }
        return(Removed.GetComponent <LayoutTracker>());
    }
Example #10
0
 // Push a new term onto the undo stack
 public void pushTerm(Term term)
 {
     stack.Push(term);
     if (currentLayoutTracker)
     {
         Destroy(currentLayoutTracker.gameObject);
     }
     currentLayoutTracker = symbolManager.Initialize(term);
 }
Example #11
0
 public PreviewBackCombinatorInfo(SpawnTarget spawnTarget, LayoutTracker paren, List <int> path, Action place, Action highlight, Action unHighlight)
 {
     this.highlight   = highlight;
     this.unHighlight = unHighlight;
     this.spawnTarget = spawnTarget;
     this.paren       = paren;
     this.path        = path;
     this.place       = place;
 }
 public void reset()
 {
     if (currentLayout)
     {
         Destroy(currentLayout.gameObject);
     }
     currentLayout = manager.Initialize(Term.Node(new List <Term>()));
     resetParensAlpha(currentLayout);
 }
 public void CreateTerm(Term t)
 {
     if (currentLayout && currentLayout.gameObject)
     {
         Destroy(currentLayout.gameObject);
     }
     currentLayout = manager.Initialize(t);
     resetParensAlpha(currentLayout);
 }
        Task TrackerIconTapped()
        {
            if (Setting.Instance is ITrackable tra)
            {
                LayoutTracker.StartTracking(tra);
                Nav.Reload().RunInParallel();
            }

            return(Task.CompletedTask);
        }
Example #15
0
    public void OnPointerClick(PointerEventData eventData)
    {
        LayoutTracker root = this;

        for (int i = 0; i < index.Count - 1; i++)
        {
            root = root.transform.parent.GetComponent <LayoutTracker>();
        }
        GetComponentInParent <SymbolManager>().HandleClick(index.Skip(1).ToList(), root);
    }
Example #16
0
    public void Cast()
    {
        oldterm      = proposal.readTerm();
        evalmode.val = true;
        onApply.Invoke();
        effectAudioEvent.Invoke(7); //Cast Spell Sound

        List <Term> args = Enumerable.Range(0, arity)
                           .Select(i => Term.Leaf(Sum <Combinator, Variable> .Inr((Variable)i))).ToList();

        proposal.Append(args);

        LayoutTracker arg_paren = variable_symbols_here.GetComponentInChildren <LayoutTracker>();


        List <Transform> ts = new List <Transform>();

        for (int i = 0; i < arg_paren.transform.childCount; i++)
        {
            ts.Add(arg_paren.transform.GetChild(i));
        }

        foreach (Transform variable in ts)
        {
            variable.GetComponent <LayoutTracker>().root = proposal.skeletonRoot;
            variable.SetParent(proposal.GetComponentInChildren <LayoutTracker>().transform, true);
        }

        term = proposal.readTerm();

        button.onClick.RemoveListener(Cast);
        button.onClick.AddListener(Step);
        button.GetComponent <Image>().sprite = stepSymbol;
        SkipButton.gameObject.SetActive(true);
        SkipBackButton.gameObject.SetActive(true);
        StepBackButton.gameObject.SetActive(true);
        StopButton.gameObject.SetActive(true);
        refreshButtons();
        LayoutRebuilder.MarkLayoutForRebuild(transform.parent.GetComponent <RectTransform>());

        if (target.goal.Equal(term))
        {
            Success.Invoke();
        }
        Debug.Log(arg_paren);
        Destroy(arg_paren);
        variable_symbols_here.gameObject.SetActive(false);
        foreach (var canvas in FindObjectsOfType <Canvas>())
        {
            LayoutRebuilder.MarkLayoutForRebuild(canvas.GetComponent <RectTransform>());
        }
    }
Example #17
0
    public IEnumerator _BackApplyParens(List <int> path, int size, LayoutTracker paren, LayoutTracker TopSymbol, Term newTerm)
    {
        forwardUndoStack.Push(new ForwardData(Sum <ElimRule, AddParenRule> .Inl(new ParenElim(path)), TopSymbol));
        var target = AccessTransfrom(TopSymbol.transform, path);


        List <Transform> temp = new List <Transform>();

        for (int i = 0; i < size; i++)
        {
            temp.Add(target.GetChild(i));
        }


        paren.transform.parent = target; //this is the problem line. SetParent(target,true) doesn't work and is oddly less effective, lateupdate?

        paren.transform.SetAsFirstSibling();

        foreach (var t in temp)
        {
            t.SetParent(paren.transform, true);
        }



        foreach (Transform t in skeletonRoot)
        {
            Destroy(t.gameObject);
        }
        CreateSkeleton(newTerm, skeletonRoot);
        yield return(new WaitUntil(() =>
        {
            bool moving = false;
            IterateTransform(TopSymbol.transform, t =>
            {
                if (t.GetComponent <LayoutTracker>())
                {
                    moving |= t.GetComponent <LayoutTracker>().Moving();
                }
            });
            return !moving;
        }));
    }
Example #18
0
    public void pushForward(ElimRule rule, LayoutTracker TopSymbol)
    {
        Term term = currentTerm;

        if (rule is CombinatorElim cElim)
        {
            var copy = Instantiate(AccessTransfrom(TopSymbol.transform, cElim.Target()).GetChild(0).gameObject, AccessTransfrom(TopSymbol.transform, cElim.Target()).GetChild(0).position, Quaternion.identity);
            copy.transform.SetParent(GetComponentInParent <Canvas>().transform.GetChild(0), true);
            copy.SetActive(false);
            backwardUndoStack.Push(Sum <BackwardTermData, BackwardParenData> .Inl(new BackwardTermData(term
                                                                                                       , () =>
            {
                copy.SetActive(true);
                copy.transform.SetParent(AccessTransfrom(TopSymbol.transform, cElim.Target()));
                copy.transform.localScale = Vector3.one;
                return(copy.GetComponent <LayoutTracker>());
            }
                                                                                                       , cElim.c, cElim.Target(), TopSymbol
                                                                                                       )));
        }
        else if (rule is ParenElim pElim)
        {
            var copy = Instantiate(AccessTransfrom(TopSymbol.transform, pElim.Target()).gameObject);
            copy.transform.position = TopSymbol.transform.position;
            foreach (Transform t in copy.transform)
            {
                Destroy(t.gameObject);
            }
            copy.transform.SetParent(GetComponentInParent <Canvas>().transform.GetChild(0), true);
            copy.SetActive(false);
            int size = AccessTransfrom(TopSymbol.transform, pElim.Target()).GetChild(0).childCount;
            backwardUndoStack.Push(Sum <BackwardTermData, BackwardParenData> .Inr(new BackwardParenData(
                                                                                      pElim.Target(), size
                                                                                      , () =>
            {
                copy.SetActive(true);
                copy.transform.localScale = Vector3.one;
                return(copy.GetComponent <LayoutTracker>());
            }, TopSymbol, term
                                                                                      )));
        }
    }
Example #19
0
    // After the level has loaded, populate the skeleton using the symbol manager
    private void onLevelWasLoaded(int arity)
    {
        List <Term> variables = new List <Term>();

        for (int i = 0; i < arity; i++)
        {
            variables.Add(Term.Leaf(Sum <Combinator, Lambda.Variable> .Inr((Lambda.Variable)i)));
        }

        if (oldVariables)
        {
            Destroy(oldVariables.gameObject);
        }
        oldVariables = symbolManager.Initialize(Term.Node(variables));

        // Set the alpha of the oldVariables parens (top level parens) to 0
        Image image = oldVariables.GetComponent <Image>();
        Color c     = image.color;

        image.color = new Color(c.r, c.g, c.b, 0);
    }
Example #20
0
        public static IControl Host(Func <IPopover, IControl> content)
        {
            return(LayoutTracker.Create(tracker =>
            {
                var hostFrame = new ReplaySubject <Rectangle <IObservable <Points> > >(1);
                var host = new Implementation
                {
                    LayoutTracker = tracker,
                    Popovers = new BehaviorSubject <IImmutableList <IControl> >(ImmutableList <IControl> .Empty),
                    HostFrame = hostFrame
                };

                return content(host)
                .WithNativeOverlay(host.Popovers.Layer())
                .WithFrame(
                    frame =>
                {
                    hostFrame.OnNext(frame);
                    return frame;
                });
            }));
        }
Example #21
0
    private LayoutTracker CreateSymbols(Term term, Transform parent, List <int> path, int index)
    {
        return(term.Match <LayoutTracker>(l =>
        {
            LayoutTracker symbol = Instantiate(parenSymbol, parent);
            symbol.root = skeletonRoot;
            symbol.index = path.Append(index).ToList();
            LayoutRebuilder.ForceRebuildLayoutImmediate(parent.GetComponent <RectTransform>());
            Canvas.ForceUpdateCanvases();
            for (var i = 0; i < l.Count; i++)
            {
                CreateSymbols(l[i], symbol.transform, path.Append(index).ToList(), i);
            }

            return symbol;
        }, v =>
        {
            var symbol = Instantiate(GetSymbol(v), parent);

            symbol.index = path.Append(index).ToList();
            symbol.root = skeletonRoot;
            return symbol;
        }));
    }
Example #22
0
 public void addParens(List <int> path, int size, LayoutTracker paren, Shrub <Sum <Combinator, Variable> > newTerm)
 {
     StartCoroutine(smt.GetComponent <SymbolManager>().BackApplyParens(path, size, paren, smt.currentLayout, newTerm));
 }
Example #23
0
 public void unApply(Shrub <Sum <Combinator, Variable> > newTerm, LayoutTracker lt, Combinator C, List <int> path)
 {
     StartCoroutine(smt.GetComponent <SymbolManager>().UnTransition(newTerm, lt, C, path, smt.currentLayout));
     goal = newTerm;
     CheckSuccess();
 }
Example #24
0
 public void HandleClick(SymbolManager manager, Shrub <Sum <Combinator, Variable> > term, List <int> path, LayoutTracker root)
 {
     print("Click happened");
 }
Example #25
0
    public IEnumerator _UnTransition(Term newTerm, LayoutTracker lt, Combinator C, List <int> path, LayoutTracker TopSymbol)
    {
        forwardUndoStack.Push(new ForwardData(Sum <ElimRule, AddParenRule> .Inl(new CombinatorElim(C, path)), TopSymbol));

        /*
         * REMEMBER, you've already "typechecked" this operation, you can assume that everything fits
         * Get transform at path
         * Grab transforms at the first occurence of each debruijn index
         * Delete everything else
         * spawn metavariables
         * order everything appropriately
         */

        Transform target = AccessTransfrom(TopSymbol.transform, path);

        (var debruijn, var arity) = Util.ParseCombinator(C)
                                    .Match(
            pi => pi,
            u => throw new Exception(u.ToString())
            );

        debruijn.Match(d =>
        {
            d = d.ToList();
            for (int i = d.Count; i < target.childCount; i++)
            {
                d.Add(Shrub <int> .Leaf(arity));
                arity++;
            }

            debruijn = Shrub <int> .Node(d);
        }, x =>
        {
            var d = new List <Shrub <int> >();
            d.Add(Shrub <int> .Leaf(x));
            for (int i = d.Count; i < target.childCount; i++)
            {
                d.Add(Shrub <int> .Leaf(arity));
                arity++;
            }

            debruijn = Shrub <int> .Node(d);
        });


        Transform[] children = new Transform[arity];
        debruijn.IterateI(new List <int>(), (i, p) =>
        {
            children[i] = AccessTransfrom(target, p, t => t, () => null);
        });

        var canvas = GetComponentInParent <Canvas>();

        foreach (var child in children)
        {
            child?.SetParent(canvas.transform, true);
        }


        foreach (Transform t in target)
        {
            Destroy(t.gameObject);
        }

        lt.LockDown(.1f);
        lt.transform.SetParent(target, true);


        foreach (var child in children)
        {
            if (!child)
            {
                var meta = Instantiate(GetSymbol(Sum <Combinator, Variable> .Inr((Variable)(-1))), target);
                meta.root = skeletonRoot;
            }
            else
            {
                child.SetParent(target, true);
            }
        }

        foreach (Transform t in skeletonRoot)
        {
            Destroy(t.gameObject);
        }
        CreateSkeleton(newTerm, skeletonRoot);
        yield return(new WaitUntil(() =>
        {
            bool moving = false;
            IterateTransform(TopSymbol.transform, t =>
            {
                if (t.GetComponent <LayoutTracker>())
                {
                    moving |= t.GetComponent <LayoutTracker>().Moving();
                }
            });
            return !moving;
        }));
    }
Example #26
0
 public IEnumerator UnTransition(Term newTerm, LayoutTracker lt, Combinator C, List <int> path, LayoutTracker TopSymbol)
 {
     backwardUndoStack = new Stack <Sum <BackwardTermData, BackwardParenData> >();
     yield return(_UnTransition(newTerm, lt, C, path, TopSymbol));
 }
Example #27
0
    public IEnumerator BackApplyParens(List <int> path, int size, LayoutTracker paren, LayoutTracker TopSymbol, Term newTerm)
    {
        backwardUndoStack = new Stack <Sum <BackwardTermData, BackwardParenData> >();

        yield return(_BackApplyParens(path, size, paren, TopSymbol, newTerm));
    }
Example #28
0
 public ForwardData(Sum <ElimRule, AddParenRule> rule, LayoutTracker topSymbol)
 {
     this.rule = rule;
     TopSymbol = topSymbol;
 }
 public void CreateTerm()
 {
     currentLayout = CreateTermHelper().Item2;
 }
Example #30
0
    private IEnumerator _Transition(ElimRule rule, LayoutTracker TopSymbol) //no moving in topsymbol
    {
        pushForward(rule, TopSymbol);
        var oldTerm = currentTerm;
        /********* replace skeleton ***********/
        Term newTerm = rule.evaluate(oldTerm);

        currentTerm = newTerm;

        foreach (Transform t in skeletonRoot)
        {
            Destroy(t.gameObject);
        }
        CreateSkeleton(newTerm, skeletonRoot);



        /********* Find symbol where rule applies ***********/
        var index          = rule.Target();
        var affectedSymbol = AccessTransfrom(TopSymbol.transform, index).GetComponent <LayoutTracker>();
        var leftmostchild  = affectedSymbol.transform.GetChild(0).position;



        /********* case on the rule **********/
        if (rule is CombinatorElim CElim)
        {
            //Play the combinator Animation with usecombinator function
            affectedSymbol.transform.GetChild(0).GetComponent <AnimateCombinator>().UseCombinator();
            //Plays the appropriate combinator sound effect
            combinatorEffectPlay(CElim);

            /********** unpack the elim rule ***********/
            {
                (var debruijn, var arity) = Util.ParseCombinator(CElim.c)
                                            .Match(
                    pi => pi,
                    u => throw new Exception(u.ToString())
                    );
                //keep track of the arguments that we need to destroy or whether
                //they are the first use of an arg so we don't need to spawn a new one
                bool[] argumentsThatHaveBeenUsed = new bool[arity + 1]; /* + 1 for possible recursion at A[0]*/

                //get all the symbols at the affected level in a list for easier management
                List <LayoutTracker> symbols = new List <LayoutTracker>();
                foreach (Transform t in affectedSymbol.transform)
                {
                    symbols.Add(t.GetComponent <LayoutTracker>());
                }

                /**************** map over transforms to adjust indices ***************/

                /******* find the new symbols to replace the arguments with   ***********/
                var detatchedSymbols = debruijn.MapI(index.Append(0).ToList(), (ind, path) =>
                {
                    if (!argumentsThatHaveBeenUsed[ind + 1 /* +1 for recursion*/])
                    {
                        symbols[ind + 1].transform.SetParent(GetComponentInParent <Canvas>().transform, true);
                        symbols[ind + 1].index = path;

                        IterateTransform(symbols[ind + 1].transform,
                                         t => t.GetComponent <LayoutTracker>().index = path.Concat(t.GetComponent <LayoutTracker>().index.Skip(index.Count + 2)).ToList());
                        argumentsThatHaveBeenUsed[ind + 1] = true;
                        return(symbols[ind + 1]);
                    }
                    else
                    {
                        IterateTransform(symbols[ind + 1].transform,
                                         t => t.GetComponent <LayoutTracker>().index = path.Concat(t.GetComponent <LayoutTracker>().index.Skip(index.Count + 2)).ToList());
                        var newSymbol   = Instantiate(symbols[ind + 1], GetComponentInChildren <LayoutTracker>().transform.position, Quaternion.identity, transform);
                        newSymbol.index = path;
                        return(newSymbol);
                    }
                });

                /************** Cleanup unused argument symbols **************/
                for (var i = 0; i < argumentsThatHaveBeenUsed.Length; i++)
                {
                    if (!argumentsThatHaveBeenUsed[i])
                    {
                        Destroy(symbols[i].gameObject);
                    }
                }

                /*******  Create Paren objects and set up hierarchy *********/

                Transform CreateParens(Shrub <LayoutTracker> symbolShrub, List <int> totalPath)
                {
                    return(symbolShrub.Match <Transform>(l =>
                    {
                        var paren = Instantiate(parenSymbol, leftmostchild, Quaternion.identity, GetComponentInParent <Canvas>().transform);
                        paren.index = totalPath;
                        paren.root = skeletonRoot;
                        for (var i = 0; i < l.Count; i++)
                        {
                            CreateParens(l[i], totalPath.Append(i).ToList()).SetParent(paren.transform, true);
                        }

                        return paren.transform;
                    },
                                                         sym => sym.transform));
                }

                //create the paren object on a dummy object then move the new terms
                //to the appropriate place in the appropriate order
                Transform dummyParen = CreateParens(detatchedSymbols, index.Append(0).ToList()); //TODO verify

                List <Transform> ts = new List <Transform>();
                for (int i = dummyParen.childCount - 1; 0 <= i; i--)
                {
                    ts.Add(dummyParen.GetChild(i));
                }

                foreach (var t in ts)
                {
                    t.SetParent(affectedSymbol.transform, true);
                    t.SetSiblingIndex(0);
                    t.GetComponent <LayoutTracker>().LockDown(.15f);
                }
                Destroy(dummyParen.gameObject);



                /****** adjust unused symbols indices ********/


                for (int i = arity + 1; false; i++)
                {
                    int new_pos = i - arity - 1 + detatchedSymbols.Match(l => l.Count, v => 1);
                    symbols[i].index[symbols[i].index.Count - 1] = new_pos;

                    IterateTransform(symbols[i].transform, t => t.GetComponent <LayoutTracker>().index[index.Count - 1] = new_pos); //TODO verify
                }
            }
        }

        if (rule is ParenElim PElim)
        {
            affectedSymbol.gameObject.name = "affected boi";

            var old_paren = affectedSymbol.transform.GetChild(0);
            var children  = new List <Transform>();
            for (int i = old_paren.childCount - 1; i >= 0; i--)
            {
                children.Add(old_paren.GetChild(i));
            }

            for (int child = 0; child < children.Count; child++)
            {
                LayoutTracker lt = children[child].GetComponent <LayoutTracker>();
                lt.index.RemoveAt(lt.index.Count - 1);
                lt.index[lt.index.Count - 1] += child;
                children[child].SetParent(affectedSymbol.transform, true);
                children[child].SetSiblingIndex(0);
            }
            //TODO fade these out
            Destroy(old_paren.gameObject);
        }


        yield return(new WaitUntil(() =>
        {
            bool moving = false;
            IterateTransform(TopSymbol.transform, t =>
            {
                if (t.GetComponent <LayoutTracker>())
                {
                    moving |= t.GetComponent <LayoutTracker>().Moving();
                }
            });
            return !moving;
        }));
    }