public BehaviorTreeControl( ) : base()
        {
            m_nodes = new List< BehaviorNodeControl >();

            m_nodeCache = new EditorNodeTypeCache();
            m_nodeCache.CacheAvailableNodes();

            AddDecorator( new Scrollbars() );
            m_canvas = ( GraphicsCanvas )AddDecorator( new GraphicsCanvas() );

            m_linkLine = ( BezierCurve )m_canvas.AddShape( new BezierCurve( Vector2.zero, Vector2.zero, Color.red, 1.0f, BezierCurve.TangentMode.AutoY, Vector2.zero, Vector2.zero ) );
            m_linkLine.Tangents = BezierCurve.TangentMode.AutoY;

            ContextMenuControl ctx = new ContextMenuControl();            
            foreach ( EditorCachedNode node in m_nodeCache.Cache )
            {
                ctx.Menu.AddItem( new GUIContent( node.displayName ), false, AddNode, node );
            }
            ctx.Positionless = true;
            AddChild( ctx );
        }
        private BehaviorNodeControl DeserializeNode(XmlNode xml, EditorNodeTypeCache typeCache, out string nodeId, out List <string> childIds)
        {
            childIds = new List <string>();

            nodeId = xml.Attributes["id"].InnerText;
            string type = xml.Attributes["type"].InnerText;

            string[] posStr   = xml.Attributes["position"].InnerText.Split(',');
            Vector2  position = new Vector2(float.Parse(posStr[0]), float.Parse(posStr[1]));

            if (xml.Attributes["outputs"] != null)
            {
                childIds.AddRange(xml.Attributes["outputs"].InnerText.Split(','));
            }

            bool             found = false;
            EditorCachedNode data  = default(EditorCachedNode);

            foreach (EditorCachedNode cachedType in typeCache.Cache)
            {
                if (cachedType.type.ToString() == type)
                {
                    found = true;
                    data  = cachedType;
                    break;
                }
            }

            if (!found)
            {
                return(null);
            }

            BehaviorNodeControl control = new BehaviorNodeControl(data);

            control.SetPosition(position);
            DeserializeFields(xml, data, control);

            return(control);
        }
        public BehaviorTreeControl( ) : base()
        {
            m_nodes = new List <BehaviorNodeControl>();

            m_nodeCache = new EditorNodeTypeCache();
            m_nodeCache.CacheAvailableNodes();

            AddDecorator(new Scrollbars());
            m_canvas = ( GraphicsCanvas )AddDecorator(new GraphicsCanvas());

            m_linkLine          = ( BezierCurve )m_canvas.AddShape(new BezierCurve(Vector2.zero, Vector2.zero, Color.red, 1.0f, BezierCurve.TangentMode.AutoY, Vector2.zero, Vector2.zero));
            m_linkLine.Tangents = BezierCurve.TangentMode.AutoY;

            ContextMenuControl ctx = new ContextMenuControl();

            foreach (EditorCachedNode node in m_nodeCache.Cache)
            {
                ctx.Menu.AddItem(new GUIContent(node.displayName), false, AddNode, node);
            }
            ctx.Positionless = true;
            AddChild(ctx);
        }
        private BehaviorNodeControl DeserializeNode( XmlNode xml, EditorNodeTypeCache typeCache, out string nodeId, out List<string> childIds )
        {
            childIds = new List<string>();

            nodeId           = xml.Attributes[ "id" ].InnerText;
            string type      = xml.Attributes[ "type" ].InnerText;
            string[] posStr  = xml.Attributes[ "position" ].InnerText.Split(',');
            Vector2 position = new Vector2( float.Parse( posStr[ 0 ] ), float.Parse( posStr[ 1 ] ) );

            if ( xml.Attributes[ "outputs" ] != null )
            {
                childIds.AddRange( xml.Attributes[ "outputs" ].InnerText.Split( ',' ) );
            }

            bool found = false;
            EditorCachedNode data = default(EditorCachedNode);

            foreach( EditorCachedNode cachedType in typeCache.Cache )
            {
                if ( cachedType.type.ToString() == type )
                {
                    found = true;
                    data = cachedType;
                    break;
                }
            }

            if ( !found )
            {                
                return null;
            }

            BehaviorNodeControl control = new BehaviorNodeControl( data );
            control.SetPosition( position );
            DeserializeFields( xml, data, control );

            return control;
        }
        public bool Deserialize( string path, EditorNodeTypeCache typeCache, out string id, out BehaviorNodeControl[] controls )
        {
            id = "";
            controls = new BehaviorNodeControl[ 0 ];

            m_childMapping = new Dictionary<BehaviorNodeControl, List<string>>();

            try
            {
                m_indexTable = new Dictionary<BehaviorNodeControl, string>();

                XmlDocument xml = new XmlDocument();
                xml.Load( path );

                XmlNode xmlRoot = xml.SelectSingleNode( "BehaviorTreeLayout" );
                id = xmlRoot.Attributes[ "id" ].InnerText;

                List< BehaviorNodeControl > deserialized = new List<BehaviorNodeControl>();
                XmlNodeList xmlNodes = xmlRoot.SelectNodes( "Node" );
                foreach( XmlNode xmlNode in xmlNodes )
                {
                    string nodeId;
                    List< string > children;
                    BehaviorNodeControl c = DeserializeNode( xmlNode, typeCache, out nodeId, out children );

                    if ( c != null )
                    {
                        m_indexTable.Add( c, nodeId );
                        m_childMapping.Add( c, children );
                        deserialized.Add( c );
                    }
                    else
                    {
                        Debug.LogWarning( "Invalid node encountered, not all nodes have been deserialized" );
                    }
                }

                // Map outputs
                foreach( BehaviorNodeControl c in deserialized )
                {
                    if ( m_childMapping.ContainsKey( c ) )
                    {
                        int i = 0;
                        foreach( string cid in m_childMapping[ c ] )
                        {
                            foreach( KeyValuePair< BehaviorNodeControl, string > kvp in m_indexTable )
                            {
                                if ( kvp.Value == cid )
                                {
                                    c.SetOutput( kvp.Key, i );
                                    i++;
                                    break;
                                }
                            }
                        }
                    }
                }

                controls = deserialized.ToArray();

                return true;
            }
            catch( System.Exception e )
            {
                Debug.LogError( string.Format( "Could not load layout at `{0}` - {1}", path, e.Message ) );
            }

            return false;
        }
        public bool Deserialize(string path, EditorNodeTypeCache typeCache, out string id, out BehaviorNodeControl[] controls)
        {
            id       = "";
            controls = new BehaviorNodeControl[0];

            m_childMapping = new Dictionary <BehaviorNodeControl, List <string> >();

            try
            {
                m_indexTable = new Dictionary <BehaviorNodeControl, string>();

                XmlDocument xml = new XmlDocument();
                xml.Load(path);

                XmlNode xmlRoot = xml.SelectSingleNode("BehaviorTreeLayout");
                id = xmlRoot.Attributes["id"].InnerText;

                List <BehaviorNodeControl> deserialized = new List <BehaviorNodeControl>();
                XmlNodeList xmlNodes = xmlRoot.SelectNodes("Node");
                foreach (XmlNode xmlNode in xmlNodes)
                {
                    string              nodeId;
                    List <string>       children;
                    BehaviorNodeControl c = DeserializeNode(xmlNode, typeCache, out nodeId, out children);

                    if (c != null)
                    {
                        m_indexTable.Add(c, nodeId);
                        m_childMapping.Add(c, children);
                        deserialized.Add(c);
                    }
                    else
                    {
                        Debug.LogWarning("Invalid node encountered, not all nodes have been deserialized");
                    }
                }

                // Map outputs
                foreach (BehaviorNodeControl c in deserialized)
                {
                    if (m_childMapping.ContainsKey(c))
                    {
                        int i = 0;
                        foreach (string cid in m_childMapping[c])
                        {
                            foreach (KeyValuePair <BehaviorNodeControl, string> kvp in m_indexTable)
                            {
                                if (kvp.Value == cid)
                                {
                                    c.SetOutput(kvp.Key, i);
                                    i++;
                                    break;
                                }
                            }
                        }
                    }
                }

                controls = deserialized.ToArray();

                return(true);
            }
            catch (System.Exception e)
            {
                Debug.LogError(string.Format("Could not load layout at `{0}` - {1}", path, e.Message));
            }

            return(false);
        }