Esempio n. 1
0
		/// <summary>
		/// Creates a new instance of a referenced behaviour node for a sub-reference graph.
		/// </summary>
		/// <param name="impulse">The original non-sub-reference graph referenced behaviour node.</param>
		public ReferencedBehavior(ReferencedBehavior referencedBehavior) : base(null, _theBackgroundBrush, _theDraggedBackgroundBrush, referencedBehavior.BaseLabel, false, referencedBehavior.Description)
		{
			_genericChildrenLocal= new ConnectorMultiple(_children, string.Empty, "GenericChildren", 1, int.MaxValue);
			_genericChildren= _genericChildrenLocal;

			// when this node is saved, the children won't as they belong to another behaviour
			_saveChildren= false;

			_referencedBehavior= null;

			referencedBehavior.CloneProperties(this);

			OnPropertyValueChanged(false);

			CopyEventHandlers(referencedBehavior);

#if DEBUG
			_debugIsSubreferencedGraphNode= true;
#endif
		}
Esempio n. 2
0
		/// <summary>
		/// Adds nodes to the referenced behaviour which represent sub-referenced behaviours.
		/// </summary>
		/// <param name="rootBehavior">The behaviour this node belongs to. NOT the referenced one.</param>
		/// <param name="parent">The node the sub-referenced behaviours will be added to.</param>
		/// <param name="node">The current node we are checking.</param>
		protected void GenerateReferencedBehaviorsTree(BehaviorNode rootBehavior, Node parent, Node node)
		{
			// check if this is a referenced behaviour
			if(node is ReferencedBehavior)
			{
				ReferencedBehavior rbnode= (ReferencedBehavior)node;

				// create the dummy node and add it without marking the behaviour as being modified as these are no REAL nodes.
				ReferencedBehavior rb= new ReferencedBehavior(rbnode);

				parent.AddChildNotModified(parent.DefaultConnector, rb);

				// we have a circular reference here. Skip the children
				if(rbnode._referencedBehavior ==rootBehavior)
				{
					rb._genericChildren.IsReadOnly= true;
					return;
				}

				// do the same for all the children
				foreach(Node child in node.Children)
					GenerateReferencedBehaviorsTree(rootBehavior, rb, child);

				rb._genericChildren.IsReadOnly= true;
			}
			else if(node is Impulse)
			{
				// create the dummy node and add it without marking the behaviour as being modified as these are no REAL nodes.
				Impulse ip= new Impulse( (Impulse)node );

				// do the same for all the children
				foreach(Node child in node.Children)
					GenerateReferencedBehaviorsTree(rootBehavior, ip, child);

				if(ip.Children.Count >0)
				{
					parent.AddChildNotModified(parent.DefaultConnector, ip);
					ip.GenericChildren.IsReadOnly= true;
				}
			}
			else
			{
				// do the same for all the children
				foreach(Node child in node.Children)
					GenerateReferencedBehaviorsTree(rootBehavior, parent, child);
			}
		}
Esempio n. 3
0
		/// <summary>
		/// Attaches a dragged node from the node explorer to an existing node.
		/// </summary>
		/// <param name="nvd">The node the new node will be attached to.</param>
		/// <param name="mode">The way the new node will be attached.</param>
		/// <param name="nodetag">The tag of the you want to create.</param>
		/// <param name="label">The label of the new node.</param>
		private void InsertNewNode(NodeViewData nvd, NodeAttachMode mode, NodeTag nodetag)
		{
			// check if the attach mode is valid
			if(mode ==NodeAttachMode.Event || mode ==NodeAttachMode.None)
				throw new Exception("A node cannot be created with the given attach mode");

			if(nodetag.Type !=NodeTagType.Behavior && nodetag.Type !=NodeTagType.Node)
				throw new Exception("Only behaviours and nodes can be attached to a behaviour tree");

			Node node= nvd.Node;

			Node newnode;
			// when we attach a behaviour we must create a special referenced behaviour node
			if(nodetag.Type ==NodeTagType.Behavior)
			{
				// reset any previously loaded behaviour
				FileManagers.FileManager.ResetLoadedBehavior();

				// get the behaviour we want to reference
				BehaviorNode behavior= _behaviorTreeList.LoadBehavior(nodetag.Filename);

				// a behaviour may not reference itself
				if(behavior ==_rootNode.RootBehavior)
					return;

				// create the referenced behaviour node for the behaviour
				ReferencedBehavior refnode= new ReferencedBehavior(_rootNode.RootBehavior, behavior);

				// register the view so it gets updated when the referenced behaviour gets updated.
				refnode.ReferencedBehaviorWasModified+= new ReferencedBehavior.ReferencedBehaviorWasModifiedEventDelegate(refnode_ReferencedBehaviorWasModified);

				newnode= refnode;
			}
			else
			{
				// simply create the node which is supposed to be created.
				newnode= Node.Create(nodetag.NodeType);
			}

			// update label
			newnode.OnPropertyValueChanged(false);

			// attach the new node with the correct mode
			switch(mode)
			{
				// the new node is inserted in front of the target node
				case(NodeAttachMode.Left):
					Node parent= node.Parent;

					int k= parent.Children.IndexOf(node);

					Node.Connector conn= node.ParentConnector;
					Debug.Check(conn !=null);

					parent.RemoveChild(conn, node);
					parent.AddChild(conn, newnode, k);

					Node.Connector newconn= newnode.GetConnector(conn.Identifier);
					Debug.Check(newconn !=null);
					newnode.AddChild(newconn, node);

					// automatically select the new node
					_selectedNodePending= newnode;
					_selectedNodePendingParent= nvd.Parent;
				break;

				// the new node is simply added to the target node's children
				case(NodeAttachMode.Right):
					node.AddChild(_dragTargetConnector, newnode);

					// automatically select the new node
					_selectedNodePending= newnode;
					_selectedNodePendingParent= nvd;
				break;

				// the new node is placed above the target node
				case(NodeAttachMode.Top):
					int n= _dragTargetNode.Node.ParentConnector.GetChildIndex(node);
					node.Parent.AddChild(_dragTargetNode.Node.ParentConnector, newnode, n);

					// automatically select the new node
					_selectedNodePending= newnode;
					_selectedNodePendingParent= nvd.Parent;
				break;

				// the new node is placed below the target node
				case(NodeAttachMode.Bottom):
					int m= _dragTargetNode.Node.ParentConnector.GetChildIndex(node);
					node.Parent.AddChild(_dragTargetNode.Node.ParentConnector, newnode, m +1);

					// automatically select the new node
					_selectedNodePending= newnode;
					_selectedNodePendingParent= nvd.Parent;
				break;
			}

			// the layout needs to be recalculated
			LayoutChanged();
		}