/// <summary> /// Deletes the specified value of the specified variable type from the specified scripting. /// </summary> /// <param name="variableType">Type of the variable.</param> /// <param name="value">The value.</param> /// <param name="scripting">The scripting.</param> /// <param name="items">Stores items to delete.</param> public static void DeleteFromScripting(VariableType variableType, object value, ScriptingComponent scripting, HashSet <ItemForDeletion> items) { // all variables foreach (NamedVariable variable in scripting.Variables) { // used in variable if (variable.VariableType == variableType && variable.Value.GetValue() == value) { items.Add(new ScriptNamedVariableForDeletion(variable)); } } // all state machines foreach (StateMachine stateMachine in scripting.StateMachines) { // all states foreach (State state in stateMachine.States) { foreach (BaseNode baseNode in state.Nodes) { // all script nodes if (baseNode is Node) { Node node = baseNode as Node; foreach (NodeSocket nodeSocket in node.Sockets) { // all variable node sockets if (nodeSocket is VariableNodeSocket) { VariableNodeSocket variableNodeSocket = nodeSocket as VariableNodeSocket; // used in variable node socket if (variableNodeSocket.VariableType == variableType && variableNodeSocket.Value.GetValue() == value) { items.Add(new ScriptVariableNodeSocketForDeletion(variableNodeSocket)); } } } } // all script variables else if (baseNode is Variable) { Variable variable = baseNode as Variable; // used in script variable if (variable.NamedVariable == null && variable.VariableType == variableType && variable.Value.GetValue() == value) { items.Add(new ScriptVariableForDeletion(variable)); } } } } } }
/// <summary> /// Generates the source code for initializing scripting nodes for the specified state. /// </summary> /// <param name="state">The state to generate scripting nodes from.</param> /// <param name="stateVariableName">Name of the state variable.</param> private void GenerateScriptNodes(State state, string stateVariableName) { Dictionary <BaseNode, string> baseNodes = new Dictionary <BaseNode, string>(); // init script nodes and variables for (int i = 0; i < state.Nodes.Count; ++i) { if (state.Nodes[i] is Node) { Node node = state.Nodes[i] as Node; writer.WriteLine("{0} script{1} = new {0}();", node.NodeData.RealName, i); writer.WriteLine("script{0}.Container = {1};", i, stateVariableName); baseNodes[node] = String.Format("script{0}", i); } else if (state.Nodes[i] is Variable) { Variable variable = state.Nodes[i] as Variable; if (variable.NamedVariable == null) { writer.WriteLine("Variable<{0}> variable{1} = new Variable<{0}>({2});", GetVariableGameEngineType(variable.VariableType), i, GetVariableValue(variable.Value)); baseNodes[variable] = String.Format("variable{0}", i); } } } // set script nodes settings and create connections for (int i = 0; i < state.Nodes.Count; ++i) { if (state.Nodes[i] is Node) { Node node = state.Nodes[i] as Node; foreach (NodeSocket socket in node.Sockets) { if (socket.Type == NodeSocketType.SignalOut) { Debug.Assert(socket is SignalNodeSocket, "Invalid node signal out socket class."); SignalNodeSocket signalSocket = socket as SignalNodeSocket; // connect to node in sockets foreach (SignalNodeSocket inSocket in signalSocket.Connections) { writer.WriteLine("{0}.{1} += {2}.{3};", baseNodes[node], signalSocket.NodeSocketData.RealName, baseNodes[inSocket.Node], inSocket.NodeSocketData.RealName); } } else if (socket.Type == NodeSocketType.VariableIn || socket.Type == NodeSocketType.VariableOut) { Debug.Assert(socket is VariableNodeSocket, "Invalid node variable socket class."); VariableNodeSocket variableSocket = socket as VariableNodeSocket; // no connection is made so use default value if possible if (variableSocket.Connections.Count == 0) { // no value is possible if (variableSocket.NodeSocketData.CanBeEmpty || variableSocket.Type == NodeSocketType.VariableOut || GetVariableValue(variableSocket.Value) == "null") { writer.WriteLine("{0}.{1} = null;", baseNodes[node], variableSocket.NodeSocketData.RealName); } else { // default value in array if (variableSocket.NodeSocketData.IsArray) { writer.WriteLine("{0}.{1} = new Variable<{2}>[1];", baseNodes[node], variableSocket.NodeSocketData.RealName, GetVariableGameEngineType(variableSocket.VariableType)); writer.WriteLine("{0}.{1}[0] = new Variable<{2}>({3});", baseNodes[node], variableSocket.NodeSocketData.RealName, GetVariableGameEngineType(variableSocket.VariableType), GetVariableValue(variableSocket.Value)); } // default value for variable else { writer.WriteLine("{0}.{1} = new Variable<{2}>({3});", baseNodes[node], variableSocket.NodeSocketData.RealName, GetVariableGameEngineType(variableSocket.VariableType), GetVariableValue(variableSocket.Value)); } } } // connect to variables else { if (variableSocket.NodeSocketData.IsArray) { // initialize array writer.WriteLine("{0}.{1} = new Variable<{2}>[{3}];", baseNodes[node], variableSocket.NodeSocketData.RealName, GetVariableGameEngineType(variableSocket.VariableType), variableSocket.Connections.Count); } for (int j = 0; j < variableSocket.Connections.Count; ++j) { if (variableSocket.Connections[j].NamedVariable == null) { writer.WriteLine(variableSocket.NodeSocketData.IsArray ? "{0}.{1}[{2}] = {3};" : "{0}.{1} = {3};", baseNodes[node], variableSocket.NodeSocketData.RealName, j, baseNodes[variableSocket.Connections[j]]); } // local variable else if ((actor == null && variableSocket.Connections[j].NamedVariable.ScriptingComponent.Actor == null) || (actor != null && variableSocket.Connections[j].NamedVariable.ScriptingComponent == actor.Scripting)) { writer.WriteLine(variableSocket.NodeSocketData.IsArray ? @"{0}.{1}[{2}] = GetVariable<{3}>(""{4}"");" : @"{0}.{1} = GetVariable<{3}>(""{4}"");", baseNodes[node], variableSocket.NodeSocketData.RealName, j, GetVariableGameEngineType(variableSocket.VariableType), variableSocket.Connections[j].NamedVariable.Name); } // other actor variable else { writer.WriteLine(variableSocket.NodeSocketData.IsArray ? @"{0}.{1}[{2}] = {3}.GetVariable<{4}>(""{5}"");" : @"{0}.{1} = {3}.GetVariable<{4}>(""{5}"");", baseNodes[node], variableSocket.NodeSocketData.RealName, j, variableSocket.Connections[j].NamedVariable.ScriptingComponent.Actor != null ? GetActorValue(variableSocket.Connections[j].NamedVariable.ScriptingComponent.Actor) : "Screen.Actors.Get(0)", GetVariableGameEngineType(variableSocket.VariableType), variableSocket.Connections[j].NamedVariable.Name); } } } } } // event node if (node.NodeData.Type == NodeType.Event) { writer.WriteLine("{0}.Connect();", baseNodes[node]); } } } }
/// <summary> /// Initializes a new instance of the <see cref="ScriptVariableNodeSocketForDeletion"/> class. /// </summary> /// <param name="variableNodeSocket">The variable node socket to delete.</param> public ScriptVariableNodeSocketForDeletion(VariableNodeSocket variableNodeSocket) { this.variableNodeSocket = variableNodeSocket; }
/// <summary> /// Clones the specified game objects. /// </summary> /// <param name="gameObjectsToCloned">The game objects to clone.</param> /// <param name="layer">The layer where to add the cloned actor, if <paramref name="addToContainer"/> is <c>true</c>.</param> /// <param name="addToContainer">If set to <c>true</c> cloned object is added to the container.</param> /// <param name="updateNameWithCloneStatus">If set to <c>true</c> name of the game object will contains information that was cloned.</param> /// <returns>Cloned game objects.</returns> public static List <GameObject> Clone(IEnumerable <GameObject> gameObjectsToCloned, Layer layer = null, bool addToContainer = false, bool updateNameWithCloneStatus = false) { List <GameObject> clonedObjects = new List <GameObject>(); Dictionary <Actor, Actor> clonedActors = new Dictionary <Actor, Actor>(); Dictionary <Path, Path> clonedPaths = new Dictionary <Path, Path>(); // clone all game objects foreach (GameObject gameObject in gameObjectsToCloned) { // clone actor if (gameObject is Actor) { Debug.Assert(!clonedActors.ContainsKey((Actor)gameObject), "Game object cannot be clonned twice."); Actor clonedActor; if (layer == null) { clonedActor = (Actor)((Actor)gameObject).Clone(addToContainer); } else { clonedActor = (Actor)((Actor)gameObject).Clone(layer, addToContainer); } clonedObjects.Add(clonedActor); AddAllClonedActors((Actor)gameObject, clonedActor, clonedActors); if (updateNameWithCloneStatus) { clonedActor.Name = clonedActor.Name + "(Copy)"; } } // clone path else if (gameObject is Path) { Debug.Assert(!clonedPaths.ContainsKey((Path)gameObject), "Game object cannot be clonned twice."); Path clonedPath = (Path)gameObject.Clone(addToContainer); clonedPaths.Add((Path)gameObject, clonedPath); clonedObjects.Add(clonedPath); if (updateNameWithCloneStatus) { clonedPath.Name = clonedPath.Name + "(Copy)"; } } // clone other game object else { clonedObjects.Add(gameObject.Clone(addToContainer)); } } // check all cloned actors foreach (KeyValuePair <Actor, Actor> clonedGameObject in clonedActors) { Actor originalActor = clonedGameObject.Key; Actor clonedActor = clonedGameObject.Value; // all variables foreach (NamedVariable variable in clonedActor.Scripting.Variables) { UpdateVariable(variable.Value, originalActor, clonedActors, clonedPaths); } // all state machines foreach (StateMachine stateMachine in clonedActor.Scripting.StateMachines) { // all states foreach (State state in stateMachine.States) { foreach (BaseNode baseNode in state.Nodes) { // all script nodes if (baseNode is Node) { Node node = baseNode as Node; foreach (NodeSocket nodeSocket in node.Sockets) { // all variable node sockets if (nodeSocket is VariableNodeSocket) { VariableNodeSocket variableNodeSocket = nodeSocket as VariableNodeSocket; UpdateVariable(variableNodeSocket.Value, originalActor, clonedActors, clonedPaths); } } } // all script variables else if (baseNode is Variable) { Variable variable = baseNode as Variable; if (variable.NamedVariable == null) { UpdateVariable(variable.Value, originalActor, clonedActors, clonedPaths); } else { Actor clonedNamedVariableOwner; if (variable.NamedVariable.ScriptingComponent.Actor != null && clonedActors.TryGetValue(variable.NamedVariable.ScriptingComponent.Actor, out clonedNamedVariableOwner)) { variable.NamedVariable = FindNamedVariable(clonedNamedVariableOwner, variable.NamedVariable.Name); Debug.Assert(variable.NamedVariable != null, "Named variable not found"); } } } } } } } return(clonedObjects); }
private void GenerateNode(Node node, XmlElement category) { // generate image SceneNode newNode = node.Clone(scriptingComponent.StateMachines[0].StartingState).CreateView(); scriptingScreen.AddSceneNodeToCenter(newNode); newNode.Location = new PointF(20, 10); bool hasVariables = false; foreach (NodeSocket nodeSocket in node.Sockets) { if (nodeSocket is VariableNodeSocket && ((VariableNodeSocket)nodeSocket).Visible) { hasVariables = true; break; } } scriptingScreen.DrawToBitmap(image, screenRect); string filenameImage = Path.Combine(outputDir, node.NodeData.RealName + ".png"); image.Clone(new RectangleF(0, 0, 20 + newNode.Bounds.Width + 20, 10 + newNode.Bounds.Height + (hasVariables ? 40 : 10)), image.PixelFormat).Save(filenameImage); ((NodeView)newNode).Node.Remove(); // generate xml element for node XmlElement nodeElement = (XmlElement)category.AppendChild(doc.CreateElement("node")); nodeElement.SetAttribute("id", Guid.NewGuid().ToString()); ElementAppendChild(nodeElement, "name", node.NodeData.Name); ElementAppendChild(nodeElement, "realName", node.NodeData.RealName); ElementAppendChild(nodeElement, "description", node.NodeData.Description); ElementAppendChild(nodeElement, "type", node.NodeData.Type.ToString()); ElementAppendChild(nodeElement, "image", node.NodeData.RealName + ".png"); XmlElement inSocketsElement = null; XmlElement outSocketsElement = null; XmlElement variableInSocketsElement = null; XmlElement variableOutSocketsElement = null; // generate sockets foreach (NodeSocket nodeSocket in node.Sockets) { // in socket if (nodeSocket is SignalNodeSocket && nodeSocket.Type == NodeSocketType.SignalIn) { if (inSocketsElement == null) { inSocketsElement = (XmlElement)nodeElement.AppendChild(doc.CreateElement("socketsIn")); } XmlElement socketElement = (XmlElement)inSocketsElement.AppendChild(doc.CreateElement("socket")); SignalNodeSocket signalNodeSocket = nodeSocket as SignalNodeSocket; ElementAppendChild(socketElement, "name", signalNodeSocket.NodeSocketData.Name); ElementAppendChild(socketElement, "realName", signalNodeSocket.NodeSocketData.RealName); ElementAppendChild(socketElement, "description", signalNodeSocket.NodeSocketData.Description); } // out socket else if (nodeSocket is SignalNodeSocket && nodeSocket.Type == NodeSocketType.SignalOut) { if (outSocketsElement == null) { outSocketsElement = (XmlElement)nodeElement.AppendChild(doc.CreateElement("socketsOut")); } XmlElement socketElement = (XmlElement)outSocketsElement.AppendChild(doc.CreateElement("socket")); SignalNodeSocket signalNodeSocket = nodeSocket as SignalNodeSocket; ElementAppendChild(socketElement, "name", signalNodeSocket.NodeSocketData.Name); ElementAppendChild(socketElement, "realName", signalNodeSocket.NodeSocketData.RealName); ElementAppendChild(socketElement, "description", signalNodeSocket.NodeSocketData.Description); } // variable in socket else if (nodeSocket is VariableNodeSocket && nodeSocket.Type == NodeSocketType.VariableIn) { if (variableInSocketsElement == null) { variableInSocketsElement = (XmlElement)nodeElement.AppendChild(doc.CreateElement("socketsVariableIn")); } XmlElement socketElement = (XmlElement)variableInSocketsElement.AppendChild(doc.CreateElement("socket")); VariableNodeSocket variableNodeSocket = nodeSocket as VariableNodeSocket; ElementAppendChild(socketElement, "name", variableNodeSocket.NodeSocketData.Name); ElementAppendChild(socketElement, "realName", variableNodeSocket.NodeSocketData.RealName); ElementAppendChild(socketElement, "description", variableNodeSocket.NodeSocketData.Description); ElementAppendChild(socketElement, "isArray", variableNodeSocket.NodeSocketData.IsArray.ToString()); ElementAppendChild(socketElement, "type", VariableTypeHelper.FriendlyName(variableNodeSocket.NodeSocketData.VariableType)); ElementAppendChild(socketElement, "defaultValue", variableNodeSocket.Value.ToString()); } // variable out socket else if (nodeSocket is VariableNodeSocket && nodeSocket.Type == NodeSocketType.VariableOut) { if (variableOutSocketsElement == null) { variableOutSocketsElement = (XmlElement)nodeElement.AppendChild(doc.CreateElement("socketsVariableOut")); } XmlElement socketElement = (XmlElement)variableOutSocketsElement.AppendChild(doc.CreateElement("socket")); VariableNodeSocket variableNodeSocket = nodeSocket as VariableNodeSocket; ElementAppendChild(socketElement, "name", variableNodeSocket.NodeSocketData.Name); ElementAppendChild(socketElement, "realName", variableNodeSocket.NodeSocketData.RealName); ElementAppendChild(socketElement, "description", variableNodeSocket.NodeSocketData.Description); ElementAppendChild(socketElement, "type", VariableTypeHelper.FriendlyName(variableNodeSocket.NodeSocketData.VariableType)); } else { Debug.Assert(true); } } }
/// <summary> /// Checks if the actor contains any scene specific variable values (for actor and path). /// If yes creates the <see cref="ItemForDeletion"/> for these values. /// </summary> /// <param name="actor">The actor to check.</param> /// <param name="allActors">All actors that can be used at the actor.</param> /// <param name="itemsToClear">Stores <see cref="ItemForDeletion"/> to clear problematic values.</param> private void CheckActorBeforeMakingPrototype(Actor actor, List <Actor> allActors, HashSet <ItemForDeletion> itemsToClear) { // all variables foreach (NamedVariable variable in actor.Scripting.Variables) { // path or actor variable if ((variable.VariableType == VariableType.Path && variable.Value.GetValue() != null) || (variable.VariableType == VariableType.Actor && variable.Value.GetValue() != null && !allActors.Contains((Actor)variable.Value.GetValue()))) { itemsToClear.Add(new ConsistentDeletionHelper.ScriptNamedVariableForDeletion(variable) { Type = DeletionType.Clear }); } } // all state machines foreach (StateMachine stateMachine in actor.Scripting.StateMachines) { // all states foreach (State state in stateMachine.States) { foreach (BaseNode baseNode in state.Nodes) { // all script nodes if (baseNode is Node) { Node node = baseNode as Node; foreach (NodeSocket nodeSocket in node.Sockets) { // all variable node sockets if (nodeSocket is VariableNodeSocket) { VariableNodeSocket variableNodeSocket = nodeSocket as VariableNodeSocket; // path or actor variable if ((variableNodeSocket.VariableType == VariableType.Path && variableNodeSocket.Value.GetValue() != null) || (variableNodeSocket.VariableType == VariableType.Actor && variableNodeSocket.Value.GetValue() != null && !allActors.Contains((Actor)variableNodeSocket.Value.GetValue()))) { itemsToClear.Add(new ConsistentDeletionHelper.ScriptVariableNodeSocketForDeletion(variableNodeSocket) { Type = DeletionType.Clear }); } } } } // all script variables else if (baseNode is Variable) { Variable variable = baseNode as Variable; if (variable.NamedVariable == null) { // path or actor variable if ((variable.VariableType == VariableType.Path && variable.Value.GetValue() != null) || (variable.VariableType == VariableType.Actor && variable.Value.GetValue() != null && !allActors.Contains((Actor)variable.Value.GetValue()))) { itemsToClear.Add(new ConsistentDeletionHelper.ScriptVariableForDeletion(variable) { Type = DeletionType.Clear }); } } else { // variable contains named variable from different actor if (!allActors.Contains(variable.NamedVariable.ScriptingComponent.Actor)) { itemsToClear.Add(new ConsistentDeletionHelper.ScriptVariableOfNamedVariableForDeletion(variable) { Type = DeletionType.Clear }); } } } } } } foreach (Actor child in actor.Children) { CheckActorBeforeMakingPrototype(child, allActors, itemsToClear); } }