/// <summary> /// Loads a node from a given XML node. /// </summary> /// <param name="getBehaviorNode">The callback used to return the behavior.</param> /// <param name="xml">The XML node we want to create the node from.</param> /// <param name="parent">The parent this node will be added to.</param> /// <param name="connector">The connector used to add this node to the parent.</param> /// <returns>Returns the created node.</returns> protected Node CreateNodeAndAdd(List <Nodes.Node.ErrorCheck> result, GetBehaviorNode getBehaviorNode, XmlNode xml, Node parent, Node.Connector connector) { try { // get the type of the node and create it string clss = GetAttribute(xml, "Class"); Type t = Plugin.GetType(clss); if (t == null) { string msg = string.Format(Resources.ExceptionUnknownNodeType, clss); string msgError = string.Format("{0}:\n{1}", this.Filename, msg); //throw new Exception(msg); MessageBox.Show(msgError, Resources.LoadError, MessageBoxButtons.OK); parent.Behavior.TriggerWasModified(parent); return(null); } Node node = Nodes.Node.Create(t); if (parent == null) { //if this._version == 0, it means there is no Version attribute in the file node.Behavior.Version = this._version; } // update the loaded behaviour member if (node is BehaviorNode) { ((BehaviorNode)node).FileManager = this; } // add the node to the parent if (parent != null) { if (connector != null) { parent.AddChildNotModified(connector, node); } else { parent.AddFSMNode(node); } } int version = 0; if (node.Behavior != null) { version = node.Behavior.Version; } else { Debug.Check(true); } SetEnterExitSlot(result, xml, node, version); // initialise the properties IList <DesignerPropertyInfo> properties = node.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (!property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { InitProperty(result, xml, node, property); } } // return the created behaviour node if (node is BehaviorNode) { getBehaviorNode((BehaviorNode)node); } // maintain compatibility with version 1 if (node is ReferencedBehaviorNode) { ReferencedBehaviorNode refbehavior = (ReferencedBehaviorNode)node; if (refbehavior.ReferenceFilename == null) { refbehavior.ReferenceFilename = GetAttribute(xml, "Reference"); } } // update node with properties node.OnPropertyValueChanged(false); // load child objects foreach (XmlNode xnode in xml.ChildNodes) { if (xnode.NodeType == XmlNodeType.Element) { switch (xnode.Name) { // load parameters case ("Parameters"): if (node is Behavior || node is ReferencedBehavior) { LoadParameters(result, xnode, node, node.LocalVars); node.Behavior.PostLoadPars(); } break; case ("DescriptorRefs"): #if QUERY_EANBLED LoadDescriptorRefs(result, xnode, node.Behavior as Behavior); #endif//#if QUERY_EANBLED break; // maintain compatibility with version 1 case ("Node"): CreateNodeAndAdd(result, getBehaviorNode, xnode, node, node.GetConnector(BaseNode.Connector.kGeneric)); break; // maintain compatibility with version 2.1 case ("Event"): case ("Attachment"): { Attachments.Attachment a = CreateAttachment(result, node, xnode); if (a != null) { node.AddAttachment(a); a.PostCreate(result, version, node, xnode); } } break; case ("Comment"): // create a comment object node.CommentText = "temp"; // initialise the attributes properties = node.CommentObject.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { continue; } string value; if (GetAttribute(xnode, property.Property.Name, out value)) { property.SetValueFromString(result, node.CommentObject, value); } } break; case ("Connector"): string identifier = GetAttribute(xnode, "Identifier"); Nodes.Node.Connector conn = node.GetConnector(identifier); foreach (XmlNode connected in xnode.ChildNodes) { if (connected.NodeType == XmlNodeType.Element && connected.Name == "Node") { CreateNodeAndAdd(result, getBehaviorNode, connected, node, conn); } } break; case ("FSMNodes"): string locationX = GetAttribute(xnode, "ScreenLocationX"); string locationY = GetAttribute(xnode, "ScreenLocationY"); if (!string.IsNullOrEmpty(locationX) && !string.IsNullOrEmpty(locationY)) { try { float x = float.Parse(locationX); float y = float.Parse(locationY); node.ScreenLocation = new System.Drawing.PointF(x, y); } catch { } } foreach (XmlNode fsmNode in xnode.ChildNodes) { if (fsmNode.NodeType == XmlNodeType.Element && fsmNode.Name == "Node") { CreateNodeAndAdd(result, getBehaviorNode, fsmNode, node, null); } } break; } } } // update attachments with attributes foreach (Attachments.Attachment attach in node.Attachments) { attach.OnPropertyValueChanged(false); } // set the properties from its prefab bool isPrefabInstance = !string.IsNullOrEmpty(node.PrefabName) && !node.HasOwnPrefabData; if (isPrefabInstance) { Node prefabNode = Plugin.GetPrefabNode(node); if (prefabNode != null) { node.ResetByPrefab(node.PrefabName, prefabNode); Behavior b = node.Behavior as Behavior; b.AgentType.AddPars(b.LocalVars); } } node.PostCreate(result, version, xml); return(node); } catch (Exception e) { string idNode = xml.Attributes["Id"].Value; string msgError = string.Format("{0}:\r\nNode Id:{1}\r\n{2}", this.Filename, idNode, e.Message); //throw new Exception(msg); MessageBox.Show(msgError, Resources.LoadError, MessageBoxButtons.OK); } return(null); }
/// <summary> /// Loads a node from a given XML node. /// </summary> /// <param name="getBehaviorNode">The callback used to return the behavior.</param> /// <param name="xml">The XML node we want to create the node from.</param> /// <param name="parent">The parent this node will be added to.</param> /// <param name="connector">The connector used to add this node to the parent.</param> /// <returns>Returns the created node.</returns> protected Node CreateNodeAndAdd(GetBehaviorNode getBehaviorNode, XmlNode xml, Node parent, Node.Connector connector) { // get the type of the node and create it string clss = GetAttribute(xml, "Class"); Type t = Plugin.GetType(clss); if (t == null) { throw new Exception(string.Format(Resources.ExceptionUnknownNodeType, clss)); } Node node = Nodes.Node.Create(t); // update the loaded behaviour member if (node is BehaviorNode) { ((BehaviorNode)node).FileManager = this; } // add the node to the parent if (parent != null) { Debug.Check(connector != null); parent.AddChildNotModified(connector, node); } // initialise the properties IList <DesignerPropertyInfo> properties = node.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { continue; } InitProperty(xml, node, property); node.PostPropertyInit(property); } // return the created behaviour node if (node is BehaviorNode) { getBehaviorNode((BehaviorNode)node); } // maintain compatibility with version 1 if (node is ReferencedBehaviorNode) { ReferencedBehaviorNode refbehavior = (ReferencedBehaviorNode)node; if (refbehavior.ReferenceFilename == null) { refbehavior.ReferenceFilename = GetAttribute(xml, "Reference"); } } // update node with properties node.OnPropertyValueChanged(false); // load child objects foreach (XmlNode xnode in xml.ChildNodes) { if (xnode.NodeType == XmlNodeType.Element) { switch (xnode.Name.ToLowerInvariant()) { // maintain compatibility with version 1 case ("node"): CreateNodeAndAdd(getBehaviorNode, xnode, node, node.GetConnector("GenericChildren")); break; // maintain compatibility with version 2.1 case ("event"): case ("attachment"): node.AddAttachment(CreateAttachment(node, xnode)); break; case ("comment"): // create a comment object node.CommentText = "temp"; // initialise the attributes properties = node.CommentObject.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { continue; } string value; if (GetAttribute(xnode, property.Property.Name, out value)) { property.SetValueFromString(node.CommentObject, value); } } break; case ("connector"): string identifier = GetAttribute(xnode, "Identifier"); Nodes.Node.Connector conn = node.GetConnector(identifier); foreach (XmlNode connected in xnode.ChildNodes) { if (connected.NodeType == XmlNodeType.Element && connected.Name.ToLowerInvariant() == "node") { CreateNodeAndAdd(getBehaviorNode, connected, node, conn); } } break; } } } // update attachments with attributes foreach (Attachments.Attachment attach in node.Attachments) { attach.OnPropertyValueChanged(false); } return(node); }
//if there is a 'Predicate' attachment, convert it to a Condition node and attach it to the '_custom_condition' connector. private void AutoRestruct(List <Node.ErrorCheck> result, int version, Behaviac.Design.Attachments.Attachment a, Node node) { if (version <= 1) { string attachClass = a.GetType().FullName; if (attachClass.IndexOf("PluginBehaviac.Events.Predicate") >= 0) { DesignerPropertyInfo propInfo = DesignerProperty.GetDesignerProperty(a.GetType(), "Opl"); RightValueDef opl = propInfo.GetValue(a) as RightValueDef; propInfo = DesignerProperty.GetDesignerProperty(a.GetType(), "Opr"); RightValueDef opr = propInfo.GetValue(a) as RightValueDef; propInfo = DesignerProperty.GetDesignerProperty(a.GetType(), "Operator"); OperatorType oprr = (OperatorType)propInfo.GetValue(a); OperatorTypes oprType = (OperatorTypes)((int)OperatorTypes.Equal - (int)OperatorType.Equal + (int)oprr); propInfo = DesignerProperty.GetDesignerProperty(a.GetType(), "BinaryOperator"); Behaviac.Design.Attachments.BinaryOperator binaryOpr = (Behaviac.Design.Attachments.BinaryOperator)propInfo.GetValue(a); string clss = node.GetType().FullName; bool bIsSeqSel = (node.GetType().IsSubclassOf(typeof(Sequence)) || node.GetType().IsSubclassOf(typeof(Selector))); bool bCare = (bIsSeqSel || node.GetType().IsSubclassOf(typeof(Impulse)) ); if (bCare || clss == "PluginBehaviac.Nodes.Query" || clss == "PluginBehaviac.Nodes.DecoratorCountLimit") { node.RemoveAttachment(a); node.Behavior.TriggerWasModified(node); Type newType = Plugin.GetType("PluginBehaviac.Nodes.Condition"); Behaviac.Design.Nodes.Node newNode = Behaviac.Design.Nodes.Node.Create(newType); Behaviac.Design.Nodes.Node.Connector connector = node.GetConnector(Node.Connector.kInterupt); if (connector != null && connector.Identifier == Node.Connector.kInterupt && connector.ChildCount > 0) { //it has multiple Predicates, so insert all of them to a newly created Sequence Node oldOne = (Node)connector.GetChild(0); if (oldOne.GetType().IsSubclassOf(typeof(Condition))) { AddAfterConditions(node, binaryOpr, newNode, connector, oldOne); } else { if (bIsSeqSel) { Debug.Check(oldOne.GetType().IsSubclassOf(typeof(Decorator))); Decorator d = oldOne as Decorator; node = oldOne; connector = node.GetConnector(BaseNode.Connector.kGeneric); oldOne = (Node)d.Children[0]; } if (oldOne.GetType() == typeof(PluginBehaviac.Nodes.And)) { if (binaryOpr == Behaviac.Design.Attachments.BinaryOperator.Or) { node.RemoveChild(connector, oldOne); Type selType1 = Plugin.GetType("PluginBehaviac.Nodes.Or"); Behaviac.Design.Nodes.Node sel = Behaviac.Design.Nodes.Node.Create(selType1); sel.AddChild(BaseNode.Connector.kGeneric, oldOne); sel.AddChild(BaseNode.Connector.kGeneric, newNode); node.AddChild(BaseNode.Connector.kInterupt, sel); } else { oldOne.AddChild(BaseNode.Connector.kGeneric, newNode); } } else if (oldOne.GetType() == typeof(PluginBehaviac.Nodes.Or)) { if (binaryOpr == Behaviac.Design.Attachments.BinaryOperator.And) { node.RemoveChild(connector, oldOne); Type selType1 = Plugin.GetType("PluginBehaviac.Nodes.And"); Behaviac.Design.Nodes.Node sel = Behaviac.Design.Nodes.Node.Create(selType1); sel.AddChild(BaseNode.Connector.kGeneric, oldOne); sel.AddChild(BaseNode.Connector.kGeneric, newNode); node.AddChild(BaseNode.Connector.kInterupt, sel); } else { oldOne.AddChild(BaseNode.Connector.kGeneric, newNode); } } else if (oldOne.GetType().IsSubclassOf(typeof(Condition))) { AddAfterConditions(node, binaryOpr, newNode, connector, oldOne); } else { Debug.Check(false); } } } else { //the first condition Behaviac.Design.Nodes.Node notNode = null; if (bIsSeqSel) { //for sequence/selector, it is reverted Type notType = Plugin.GetType("PluginBehaviac.Nodes.DecoratorNot"); notNode = Behaviac.Design.Nodes.Node.Create(notType); node.AddChild(BaseNode.Connector.kInterupt, notNode); notNode.AddChild(BaseNode.Connector.kGeneric, newNode); } else { node.AddChild(BaseNode.Connector.kInterupt, newNode); } } // initialise the attachments properties IList <DesignerPropertyInfo> lp = newNode.GetDesignerProperties(); for (int p = 0; p < lp.Count; ++p) { if (lp[p].Property.Name == "Opl") { lp[p].Property.SetValue(newNode, opl, null); } else if (lp[p].Property.Name == "Opr") { lp[p].Property.SetValue(newNode, opr, null); } else if (lp[p].Property.Name == "Operator") { lp[p].Property.SetValue(newNode, oprr, null); } } // update attacheent with attributes newNode.OnPropertyValueChanged(false); } else if (clss == "PluginBehaviac.Nodes.Action") { Type newType = Plugin.GetType("PluginBehaviac.Events.Precondition"); Behaviac.Design.Attachments.Attachment newNode = Behaviac.Design.Attachments.Attachment.Create(newType, node); node.AddAttachment(newNode); node.RemoveAttachment(a); node.Behavior.TriggerWasModified(node); // initialise the attachments properties IList <DesignerPropertyInfo> lp = newNode.GetDesignerProperties(); for (int p = 0; p < lp.Count; ++p) { if (lp[p].Property.Name == "BinaryOperator") { lp[p].Property.SetValue(newNode, binaryOpr, null); } else if (lp[p].Property.Name == "Opl") { lp[p].Property.SetValue(newNode, opl, null); } else if (lp[p].Property.Name == "Opr2") { lp[p].Property.SetValue(newNode, opr, null); } else if (lp[p].Property.Name == "Operator") { lp[p].Property.SetValue(newNode, oprType, null); } else if (lp[p].Property.Name == "IsAlive") { lp[p].SetValueFromString(result, newNode, "true"); } } // update attacheent with attributes newNode.OnPropertyValueChanged(false); } else { Debug.Check(false); } } } // if (version <= 1) }
/// <summary> /// Loads a node from a given XML node. /// </summary> /// <param name="getBehaviorNode">The callback used to return the behavior.</param> /// <param name="xml">The XML node we want to create the node from.</param> /// <param name="parent">The parent this node will be added to.</param> /// <param name="connector">The connector used to add this node to the parent.</param> /// <returns>Returns the created node.</returns> protected Node CreateNodeAndAdd(GetBehaviorNode getBehaviorNode, XmlNode xml, Node parent, Node.Connector connector) { try { // get the type of the node and create it string clss = GetAttribute(xml, "Class"); Type t = Plugin.GetType(clss); if (t == null) { string msg = string.Format(Resources.ExceptionUnknownNodeType, clss); string msgError = string.Format("{0}:\n{1}", this.Filename, msg); //throw new Exception(msg); MessageBox.Show(msgError, Resources.LoadError, MessageBoxButtons.OK); parent.Behavior.IsModified = true; return(null); } Node node = Nodes.Node.Create(t); // update the loaded behaviour member if (node is BehaviorNode) { ((BehaviorNode)node).FileManager = this; } // add the node to the parent if (parent != null) { Debug.Check(connector != null); parent.AddChildNotModified(connector, node); } // initialise the properties IList <DesignerPropertyInfo> properties = node.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (!property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { InitProperty(xml, node, property); node.PostPropertyInit(property); } } // return the created behaviour node if (node is BehaviorNode) { getBehaviorNode((BehaviorNode)node); } // maintain compatibility with version 1 if (node is ReferencedBehaviorNode) { ReferencedBehaviorNode refbehavior = (ReferencedBehaviorNode)node; if (refbehavior.ReferenceFilename == null) { refbehavior.ReferenceFilename = GetAttribute(xml, "Reference"); } } // update node with properties node.OnPropertyValueChanged(false); // load child objects foreach (XmlNode xnode in xml.ChildNodes) { if (xnode.NodeType == XmlNodeType.Element) { switch (xnode.Name.ToLowerInvariant()) { // load parameters case ("parameters"): LoadParameters(xnode, node, node.Pars); break; case ("descriptorrefs"): #if QUERY_EANBLED LoadDescriptorRefs(xnode, node.Behavior as Behavior); #endif//#if QUERY_EANBLED break; // maintain compatibility with version 1 case ("node"): CreateNodeAndAdd(getBehaviorNode, xnode, node, node.GetConnector("GenericChildren")); break; // maintain compatibility with version 2.1 case ("event"): case ("attachment"): { Attachments.Attachment a = CreateAttachment(node, xnode); if (a != null) { node.AddAttachment(a); } } break; case ("comment"): // create a comment object node.CommentText = "temp"; // initialise the attributes properties = node.CommentObject.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { continue; } string value; if (GetAttribute(xnode, property.Property.Name, out value)) { property.SetValueFromString(node.CommentObject, value); } } break; case ("connector"): string identifier = GetAttribute(xnode, "Identifier"); Nodes.Node.Connector conn = node.GetConnector(identifier); foreach (XmlNode connected in xnode.ChildNodes) { if (connected.NodeType == XmlNodeType.Element && connected.Name.ToLowerInvariant() == "node") { CreateNodeAndAdd(getBehaviorNode, connected, node, conn); } } break; } } } // update attachments with attributes foreach (Attachments.Attachment attach in node.Attachments) { attach.OnPropertyValueChanged(false); } // set the properties from its prefab bool isPrefabInstance = !string.IsNullOrEmpty(node.PrefabName) && !node.HasOwnPrefabData; if (isPrefabInstance) { Node prefabNode = Plugin.GetPrefabNode(node); if (prefabNode != null) { node.ResetByPrefab(node.PrefabName, prefabNode); } } return(node); } catch (Exception e) { string idNode = xml.Attributes["Id"].Value; string msgError = string.Format("{0}:\r\nNode Id:{1}\r\n{2}", this.Filename, idNode, e.Message); //throw new Exception(msg); MessageBox.Show(msgError, Resources.LoadError, MessageBoxButtons.OK); } return(null); }