public uint CreateActionNode(ActionNode.Do func)
        {
            ActionNode newNode = new ActionNode(func);

            newNode.SetID(++m_nodeID);
            uint a = newNode.GetID();

            m_nodeDic.Add(a, newNode);
            return(a);
        }
        private uint CreateActionNodeWithID(ActionNode.Do func, uint nodeID)
        {
            if (m_nodeDic.ContainsKey(nodeID))
            {
                return(0xffffffff);   // id already exists
            }
            ActionNode newNode = new ActionNode(func);

            newNode.SetID(nodeID);
            m_nodeDic.Add(nodeID, newNode);
            return(nodeID);
        }
        public bool LoadTree(string filePath = "Default.tree")
        {
            if (!File.Exists(filePath))
            {
                return(false);
            }
            List <string> data;

            string[]    lines = File.ReadAllLines(filePath);
            uint        x;
            int         count;
            List <uint> children = new List <uint>();

            foreach (string line in lines)
            {
                data  = line.Split(',').ToList <string>();
                count = data.Count();
                if (UInt32.TryParse(data[0], out uint id))
                {
                    if (id > m_nodeID)
                    {
                        m_nodeID = id;
                    }

                    switch (data[1])
                    {
                    case "ActionNode":
                        Type          calledType = Type.GetType(data[3]);
                        MethodInfo    method     = calledType.GetMethod(data[2]);
                        ActionNode.Do action     = Delegate.CreateDelegate(typeof(ActionNode.Do), null, method) as ActionNode.Do;
                        CreateActionNodeWithID(action, id);
                        break;


                    case "Inverter":
                        if (UInt32.TryParse(data[2], out x))
                        {
                            CreateDecoratorNodeWithID(DecoratorNodeType.Inverter, x, id);
                        }
                        break;

                    case "Repeater":
                        if (UInt32.TryParse(data[2], out x))
                        {
                            if (data.Count >= 3)        // does it contain extra data
                            {
                                if (UInt32.TryParse(data[3], out uint y))
                                {
                                    CreateDecoratorNodeWithID(DecoratorNodeType.Repeater, x, id, y);
                                }
                            }
                            else
                            {
                                CreateDecoratorNodeWithID(DecoratorNodeType.Repeater, x, id);
                            }
                        }

                        break;

                    case "RepeatTillFail":
                        if (UInt32.TryParse(data[2], out x))
                        {
                            CreateDecoratorNodeWithID(DecoratorNodeType.RepeatTillFail, x, id);
                        }
                        break;

                    case "Limiter":
                        if (UInt32.TryParse(data[2], out x))
                        {
                            CreateDecoratorNodeWithID(DecoratorNodeType.RepeatTillFail, x, id);
                        }
                        break;


                    case "Selector":
                        for (int i = 2; i < count; ++i)
                        {
                            if (UInt32.TryParse(data[i], out x))
                            {
                                children.Add(x);
                            }
                        }

                        CreateCompositeNodeWithID(CompositeNodeTypes.Selector, children, id);
                        break;

                    case "Sequence":
                        for (int i = 2; i < count; ++i)
                        {
                            if (UInt32.TryParse(data[i], out x))
                            {
                                children.Add(x);
                            }
                        }

                        CreateCompositeNodeWithID(CompositeNodeTypes.Sequence, children, id);
                        break;

                    // Set the root node at the end
                    case "root":
                        if (UInt32.TryParse(data[2], out x))
                        {
                            SetRootNode(x);
                        }
                        break;
                    }
                }
            }
            return(true);
        }